aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_con
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_con')
-rw-r--r--libraries/ecore/src/lib/ecore_con/Ecore_Con.h1938
-rw-r--r--libraries/ecore/src/lib/ecore_con/Makefile.am46
-rw-r--r--libraries/ecore/src/lib/ecore_con/Makefile.in935
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con.c2583
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c101
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_ares.c628
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_info.c449
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_local.c317
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c754
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_private.h397
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_socks.c940
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c2113
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_url.c1635
13 files changed, 0 insertions, 12836 deletions
diff --git a/libraries/ecore/src/lib/ecore_con/Ecore_Con.h b/libraries/ecore/src/lib/ecore_con/Ecore_Con.h
deleted file mode 100644
index d0ca6f6..0000000
--- a/libraries/ecore/src/lib/ecore_con/Ecore_Con.h
+++ /dev/null
@@ -1,1938 +0,0 @@
1#ifndef _ECORE_CON_H
2#define _ECORE_CON_H
3
4#include <time.h>
5#include <libgen.h>
6#ifdef _WIN32
7# include <ws2tcpip.h>
8#else
9# include <netdb.h>
10#endif
11#include <Eina.h>
12
13#ifdef EAPI
14# undef EAPI
15#endif
16
17#ifdef _WIN32
18# ifdef EFL_ECORE_CON_BUILD
19# ifdef DLL_EXPORT
20# define EAPI __declspec(dllexport)
21# else
22# define EAPI
23# endif
24# else
25# define EAPI __declspec(dllimport)
26# endif
27#else
28# ifdef __GNUC__
29# if __GNUC__ >= 4
30# define EAPI __attribute__ ((visibility("default")))
31# else
32# define EAPI
33# endif
34# else
35# define EAPI
36# endif
37#endif
38
39/**
40 * @defgroup Ecore_Con_Group Ecore_Con - Connection functions
41 *
42 * The Ecore Connection Library ( @c Ecore_Con ) provides simple mechanisms
43 * for communications between programs using reliable sockets. It saves
44 * the programmer from having to worry about file descriptors and waiting
45 * for incoming connections.
46 *
47 * There are two main objects in the @c Ecore_Con library: the @c
48 * Ecore_Con_Server and the @c Ecore_Con_Client.
49 *
50 * The @c Ecore_Con_Server represents a server that can be connected to.
51 * It is used regardless of whether the program is acting as a server or
52 * client itself.
53 *
54 * To create a listening server call @c ecore_con_server_add(), optionally using
55 * an ECORE_CON_USE_* encryption type OR'ed with the type for encryption.
56 *
57 * To connect to a server, call @c ecore_con_server_connect(). Data can
58 * then be sent to the server using the @c ecore_con_server_send().
59 *
60 * Functions are described in the following groupings:
61 * @li @ref Ecore_Con_Lib_Group
62 * @li @ref Ecore_Con_Server_Group
63 * @li @ref Ecore_Con_Client_Group
64 * @li @ref Ecore_Con_Url_Group
65 *
66 * Events are described in @ref Ecore_Con_Events_Group.
67 */
68
69
70/**
71 * @defgroup Ecore_Con_Events_Group Events
72 *
73 * @li ECORE_CON_CLIENT_ADD: Whenever a client connection is made to an
74 * @c Ecore_Con_Server, an event of this type is emitted, allowing the
75 * retrieval of the client's ip with @ref ecore_con_client_ip_get and
76 * associating data with the client using ecore_con_client_data_set.
77 * @li ECORE_CON_EVENT_CLIENT_DEL: Whenever a client connection to an
78 * @c Ecore_Con_Server, an event of this type is emitted. The contents of
79 * the data with this event are variable, but if the client object in the data
80 * is non-null, it must be freed with @ref ecore_con_client_del.
81 * @li ECORE_CON_EVENT_SERVER_ADD: Whenever a server object is created
82 * with @ref ecore_con_server_connect, an event of this type is emitted,
83 * allowing for data to be serialized and sent to the server using
84 * @ref ecore_con_server_send. At this point, the http handshake has
85 * occurred.
86 * @li ECORE_CON_EVENT_SERVER_DEL: Whenever a server object is destroyed,
87 * usually by the server connection being refused or dropped, an event of this
88 * type is emitted. The contents of the data with this event are variable,
89 * but if the server object in the data is non-null, it must be freed
90 * with @ref ecore_con_server_del.
91 * @li ECORE_CON_EVENT_CLIENT_DATA: Whenever a client connects to your server
92 * object and sends data, an event of this type is emitted. The data will contain both
93 * the size and contents of the message sent by the client. It should be noted that
94 * data within this object is transient, so it must be duplicated in order to be
95 * retained. This event will continue to occur until the client has stopped sending its
96 * message, so a good option for storing this data is an Eina_Strbuf. Once the message has
97 * been received in full, the client object must be freed with ecore_con_client_free.
98 * @li ECORE_CON_EVENT_SERVER_DATA: Whenever your server object connects to its destination
99 * and receives data, an event of this type is emitted. The data will contain both
100 * the size and contents of the message sent by the server. It should be noted that
101 * data within this object is transient, so it must be duplicated in order to be
102 * retained. This event will continue to occur until the server has stopped sending its
103 * message, so a good option for storing this data is an Eina_Strbuf. Once the message has
104 * been received in full, the server object must be freed with ecore_con_server_free.
105 *
106 */
107
108/**
109 * @defgroup Ecore_Con_Buffer Buffering
110 *
111 * As Ecore_Con works on an event driven design, as data arrives, events will
112 * be produced containing the data that arrived. It is up to the user of
113 * Ecore_Con to either parse as they go, append to a file to later parse the
114 * whole file in one go, or append to memory to parse or handle leter.
115 *
116 * To help with this Eina has some handy API's. The Eina_Binbuf and
117 * Eina_Strbuf APIs, abstract dynamic buffer management and make it trivial
118 * to handle buffers at runtime, without having to manage them. Eina_Binbuf
119 * makes it possible to create, expand, reset and slice a blob of memory -
120 * all via API. No system calls, no pointer manipulations and no size
121 * calculation.
122 *
123 * Additional functions include adding content at specified byte positions in
124 * the buffer, escaping the inputs, find and replace strings. This provides
125 * extreme flexibility to play around, with a dynamic blob of memory.
126 *
127 * It is good to free it (using eina_binbuf_free()) after using it.
128 *
129 * Eina_Binbuf compliments Ecore_Con use cases, where dynamic sizes of data
130 * arrive from the network (think http download in chunks). Using
131 * Eina_Binbuf provides enough flexibility to handle data as it arrives and
132 * to defer its processing until desired, without having to think about
133 * where to store the temporary data and how to manage its size.
134 *
135 * An example of how to use these with Ecore_Con follows.
136 *
137 * @code
138 * #include <Eina.h>
139 * #include <Ecore.h>
140 * #include <Ecore_Con.h>
141 *
142 * static Eina_Bool
143 * data_callback(void *data, int type, void *event)
144 * {
145 * Ecore_Con_Event_Url_Data *url_data = event;
146 * if ( url_data->size > 0)
147 * {
148 * // append data as it arrives - don't worry where or how it gets stored.
149 * // Also don't worry about size, expanding, reallocing etc.
150 * // just keep appending - size is automatically handled.
151 *
152 * eina_binbuf_append_length(data, url_data->data, url_data->size);
153 *
154 * fprintf(stderr, "Appended %d \n", url_data->size);
155 * }
156 * return EINA_TRUE;
157 * }
158 *
159 *
160 *
161 * static Eina_Bool
162 * completion_callback(void *data, int type, void *event)
163 * {
164 * Ecore_Con_Event_Url_Complete *url_complete = event;
165 * printf("download completed with status code: %d\n", url_complete->status);
166 *
167 * // get the data back from Eina_Binbuf
168 * char *ptr = eina_binbuf_string_get(data);
169 * size_t size = eina_binbuf_length_get(data);
170 *
171 * // process data as required (write to file)
172 * fprintf(stderr, "Size of data = %d bytes\n", size);
173 * int fd = open("./elm.png", O_CREAT);
174 * write(fd, ptr, size);
175 * close(fd);
176 *
177 * // free it when done.
178 * eina_binbuf_free(data);
179 *
180 * ecore_main_loop_quit();
181 *
182 * return EINA_TRUE;
183 * }
184 *
185 *
186 * int
187 * main(int argc, char **argv)
188 * {
189 *
190 * const char *url = "http://www.enlightenment.org/p/index/d/logo.png";
191 *
192 * ecore_init();
193 * ecore_con_init();
194 * ecore_con_url_init();
195 *
196 *
197 * // This is single additional line to manage dynamic network data.
198 * Eina_Binbuf *data = eina_binbuf_new();
199 * Ecore_Con_Url *url_con = ecore_con_url_new(url);
200 *
201 * ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE,
202 * completion_callback,
203 * data);
204 * ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA,
205 * data_callback,
206 * data);
207 * ecore_con_url_get(url_con);
208 *
209 * ecore_main_loop_begin();
210 * return 0;
211 * }
212 * @endcode
213 */
214
215#ifdef __cplusplus
216extern "C" {
217#endif
218#define ECORE_CON_USE_SSL ECORE_CON_USE_SSL2
219#define ECORE_CON_REMOTE_SYSTEM ECORE_CON_REMOTE_TCP
220
221
222/**
223 * @typedef Ecore_Con_Server
224 * A connection handle to a server
225 * @ingroup Ecore_Con_Server_Group
226 */
227typedef struct _Ecore_Con_Server Ecore_Con_Server;
228
229/**
230 * @typedef Ecore_Con_Client
231 * A connection handle to a client
232 * @ingroup Ecore_Con_Client_Group
233 */
234typedef struct _Ecore_Con_Client Ecore_Con_Client;
235
236/**
237 * @typedef Ecore_Con_Socks
238 * An object representing a SOCKS proxy
239 * @ingroup Ecore_Con_Socks_Group
240 * @since 1.2
241 */
242typedef struct Ecore_Con_Socks Ecore_Con_Socks;
243
244/**
245 * @typedef Ecore_Con_Url
246 * A handle to an http upload/download object
247 * @ingroup Ecore_Con_Url_Group
248 */
249typedef struct _Ecore_Con_Url Ecore_Con_Url;
250
251
252/**
253 * @addtogroup Ecore_Con_Events_Group Events
254 * @{
255 */
256
257/**
258 * @typedef Ecore_Con_Event_Client_Add
259 * Used as the @p data param for the corresponding event
260 */
261typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add;
262
263/**
264 * @typedef Ecore_Con_Event_Client_Upgrade
265 * Used as the @p data param for the corresponding event
266 * @since 1.1
267 */
268typedef struct _Ecore_Con_Event_Client_Upgrade Ecore_Con_Event_Client_Upgrade;
269
270/**
271 * @typedef Ecore_Con_Event_Client_Del
272 * Used as the @p data param for the corresponding event
273 */
274typedef struct _Ecore_Con_Event_Client_Del Ecore_Con_Event_Client_Del;
275
276/**
277 * @typedef Ecore_Con_Event_Client_Error
278 * Used as the @p data param for the corresponding event
279 * @since 1.1
280 */
281typedef struct _Ecore_Con_Event_Client_Error Ecore_Con_Event_Client_Error;
282
283/**
284 * @typedef Ecore_Con_Event_Server_Add
285 * Used as the @p data param for the corresponding event
286 */
287typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add;
288
289/**
290 * @typedef Ecore_Con_Event_Server_Upgrade
291 * Used as the @p data param for the corresponding event
292 * @since 1.1
293 */
294typedef struct _Ecore_Con_Event_Server_Upgrade Ecore_Con_Event_Server_Upgrade;
295
296/**
297 * @typedef Ecore_Con_Event_Server_Del
298 * Used as the @p data param for the corresponding event
299 */
300typedef struct _Ecore_Con_Event_Server_Del Ecore_Con_Event_Server_Del;
301
302/**
303 * @typedef Ecore_Con_Event_Server_Error
304 * Used as the @p data param for the corresponding event
305 * @since 1.1
306 */
307typedef struct _Ecore_Con_Event_Server_Error Ecore_Con_Event_Server_Error;
308
309/**
310 * @typedef Ecore_Con_Event_Client_Data
311 * Used as the @p data param for the corresponding event
312 */
313typedef struct _Ecore_Con_Event_Client_Data Ecore_Con_Event_Client_Data;
314
315/**
316 * @typedef Ecore_Con_Event_Server_Data
317 * Used as the @p data param for the corresponding event
318 */
319typedef struct _Ecore_Con_Event_Server_Data Ecore_Con_Event_Server_Data;
320
321/**
322 * @typedef Ecore_Con_Event_Client_Write
323 * Used as the @p data param for the corresponding event
324 * @since 1.1
325 */
326typedef struct _Ecore_Con_Event_Client_Write Ecore_Con_Event_Client_Write;
327
328/**
329 * @typedef Ecore_Con_Event_Server_Write
330 * Used as the @p data param for the corresponding event
331 * @since 1.1
332 */
333typedef struct _Ecore_Con_Event_Server_Write Ecore_Con_Event_Server_Write;
334
335/**
336 * @typedef Ecore_Con_Event_Proxy_Bind
337 * Used as the @p data param for the corresponding event
338 * @since 1.2
339 */
340typedef struct _Ecore_Con_Event_Proxy_Bind Ecore_Con_Event_Proxy_Bind;
341
342/**
343 * @typedef Ecore_Con_Event_Url_Data
344 * Used as the @p data param for the corresponding event
345 * @ingroup Ecore_Con_Url_Group
346 */
347typedef struct _Ecore_Con_Event_Url_Data Ecore_Con_Event_Url_Data;
348
349/**
350 * @typedef Ecore_Con_Event_Url_Complete
351 * Used as the @p data param for the corresponding event
352 * @ingroup Ecore_Con_Url_Group
353 */
354typedef struct _Ecore_Con_Event_Url_Complete Ecore_Con_Event_Url_Complete;
355
356/**
357 * @typedef Ecore_Con_Event_Url_Progress
358 * Used as the @p data param for the corresponding event
359 * @ingroup Ecore_Con_Url_Group
360 */
361typedef struct _Ecore_Con_Event_Url_Progress Ecore_Con_Event_Url_Progress;
362
363/**
364 * @struct _Ecore_Con_Event_Client_Add
365 * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ADD event
366 */
367struct _Ecore_Con_Event_Client_Add
368{
369 Ecore_Con_Client *client; /** the client that connected */
370};
371
372/**
373 * @struct _Ecore_Con_Event_Client_Upgrade
374 * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_UPGRADE event
375 * @since 1.1
376 */
377struct _Ecore_Con_Event_Client_Upgrade
378{
379 Ecore_Con_Client *client; /** the client that completed handshake */
380};
381
382/**
383 * @struct _Ecore_Con_Event_Client_Del
384 * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DEL event
385 */
386struct _Ecore_Con_Event_Client_Del
387{
388 Ecore_Con_Client *client; /** the client that was lost */
389};
390
391/**
392 * @struct _Ecore_Con_Event_Client_Error
393 * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ERROR event
394 */
395struct _Ecore_Con_Event_Client_Error
396{
397 Ecore_Con_Client *client; /** the client for which an error occurred */
398 char *error; /**< the error string describing what happened */
399};
400
401/**
402 * @struct _Ecore_Con_Event_Server_Add
403 * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ADD event
404 */
405struct _Ecore_Con_Event_Server_Add
406{
407 Ecore_Con_Server *server; /** the server that was connected to */
408};
409
410/**
411 * @struct _Ecore_Con_Event_Server_Upgrade
412 * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_UPGRADE event
413 * @since 1.1
414 */
415struct _Ecore_Con_Event_Server_Upgrade
416{
417 Ecore_Con_Server *server; /** the server that was connected to */
418};
419
420/**
421 * @struct _Ecore_Con_Event_Server_Del
422 * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DEL event
423 */
424struct _Ecore_Con_Event_Server_Del
425{
426 Ecore_Con_Server *server; /** the client that was lost */
427};
428
429/**
430 * @struct _Ecore_Con_Event_Server_Error
431 * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ERROR event
432 */
433struct _Ecore_Con_Event_Server_Error
434{
435 Ecore_Con_Server *server; /** the server for which an error occurred */
436 char *error; /**< the error string describing what happened */
437};
438
439/**
440 * @struct _Ecore_Con_Event_Client_Data
441 * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DATA event
442 */
443struct _Ecore_Con_Event_Client_Data
444{
445 Ecore_Con_Client *client; /**< the client that connected */
446 void *data; /**< the data that the client sent */
447 int size; /**< the length of the data sent */
448};
449
450/**
451 * @struct _Ecore_Con_Event_Server_Data
452 * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DATA event
453 */
454struct _Ecore_Con_Event_Server_Data
455{
456 Ecore_Con_Server *server; /**< the server that was connected to */
457 void *data; /**< the data that the server sent */
458 int size; /**< the length of the data sent */
459};
460
461/**
462 * @struct _Ecore_Con_Event_Client_Write
463 * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_WRITE event
464 */
465struct _Ecore_Con_Event_Client_Write
466{
467 Ecore_Con_Client *client; /**< the client that connected */
468 int size; /**< the length of the data sent */
469};
470
471/**
472 * @struct _Ecore_Con_Event_Server_Write
473 * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_WRITE event
474 */
475struct _Ecore_Con_Event_Server_Write
476{
477 Ecore_Con_Server *server; /**< the server that was connected to */
478 int size; /**< the length of the data sent */
479};
480
481/**
482 * @struct _Ecore_Con_Event_Proxy_Bind
483 * Used as the @p data param for the @ref ECORE_CON_EVENT_PROXY_BIND event
484 * @ingroup Ecore_Con_Socks_Group
485 * @since 1.2
486 */
487struct _Ecore_Con_Event_Proxy_Bind
488{
489 Ecore_Con_Server *server; /**< the server object connected to the proxy */
490 const char *ip; /**< the proxy-bound ip address */
491 int port; /**< the proxy-bound port */
492};
493
494/**
495 * @struct _Ecore_Con_Event_Url_Data
496 * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_DATA event
497 * @ingroup Ecore_Con_Url_Group
498 */
499struct _Ecore_Con_Event_Url_Data
500{
501 Ecore_Con_Url *url_con; /**< a pointer to the connection object */
502 int size; /**< the size of the current received data (in bytes) */
503 unsigned char data[1]; /**< the data received on this event */
504};
505
506/**
507 * @struct _Ecore_Con_Event_Url_Complete
508 * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_COMPLETE event
509 * @ingroup Ecore_Con_Url_Group
510 */
511struct _Ecore_Con_Event_Url_Complete
512{
513 Ecore_Con_Url *url_con; /**< a pointer to the connection object */
514 int status; /**< HTTP status code of the operation (200, 404, 401, etc.) */
515};
516
517/**
518 * @struct _Ecore_Con_Event_Url_Progress
519 * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_PROGRESS event
520 * @ingroup Ecore_Con_Url_Group
521 */
522struct _Ecore_Con_Event_Url_Progress
523{
524 Ecore_Con_Url *url_con; /**< a pointer to the connection object */
525 struct
526 {
527 double total; /**< total size of the downloading data (in bytes) */
528 double now; /**< current size of the downloading data (in bytes) */
529 } down; /**< download info */
530 struct
531 {
532 double total; /**< total size of the uploading data (in bytes) */
533 double now; /**< current size of the uploading data (in bytes) */
534 } up; /**< upload info */
535};
536
537/** A client has connected to the server */
538EAPI extern int ECORE_CON_EVENT_CLIENT_ADD;
539/** A client has disconnected from the server */
540EAPI extern int ECORE_CON_EVENT_CLIENT_DEL;
541/** A client experienced an error
542 * @since 1.1
543 */
544EAPI extern int ECORE_CON_EVENT_CLIENT_ERROR;
545/** A client connection has been upgraded to SSL
546 * @since 1.1
547 */
548EAPI extern int ECORE_CON_EVENT_CLIENT_UPGRADE;
549/** A server was created */
550EAPI extern int ECORE_CON_EVENT_SERVER_ADD;
551/** A server connection was lost */
552EAPI extern int ECORE_CON_EVENT_SERVER_DEL;
553/** A server experienced an error
554 * @since 1.1
555 */
556EAPI extern int ECORE_CON_EVENT_SERVER_ERROR;
557/** A server connection has been upgraded to SSL
558 * @since 1.1
559 */
560EAPI extern int ECORE_CON_EVENT_SERVER_UPGRADE;
561/** A server connection has sent data to its client
562 * @since 1.1
563 */
564EAPI extern int ECORE_CON_EVENT_CLIENT_WRITE;
565/** A server connection object has sent data
566 * @since 1.1
567 */
568EAPI extern int ECORE_CON_EVENT_SERVER_WRITE;
569/** A client connected to the server has sent data */
570EAPI extern int ECORE_CON_EVENT_CLIENT_DATA;
571/** A server connection object has data */
572EAPI extern int ECORE_CON_EVENT_SERVER_DATA;
573/** A server connection has successfully negotiated an ip:port binding
574 * @since 1.2
575 */
576EAPI extern int ECORE_CON_EVENT_PROXY_BIND;
577/** A URL object has data */
578EAPI extern int ECORE_CON_EVENT_URL_DATA;
579/** A URL object has completed its transfer to and from the server and can be reused */
580EAPI extern int ECORE_CON_EVENT_URL_COMPLETE;
581/** A URL object has made progress in its transfer */
582EAPI extern int ECORE_CON_EVENT_URL_PROGRESS;
583
584/**
585 * @}
586 */
587
588/**
589 * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions
590 *
591 * Utility functions that set up and shut down the Ecore Connection
592 * library.
593 *
594 * There's also ecore_con_lookup() that can be used to make simple asynchronous
595 * DNS lookups.
596 *
597 * A simple example of how to use these functions:
598 * @li @ref ecore_con_lookup_example_c
599 *
600 * @{
601 */
602
603/**
604 * @typedef Ecore_Con_Dns_Cb
605 * A callback type for use with @ref ecore_con_lookup.
606 */
607typedef void (*Ecore_Con_Dns_Cb)(const char *canonname,
608 const char *ip,
609 struct sockaddr *addr,
610 int addrlen,
611 void *data);
612
613/**
614 * @typedef Ecore_Con_Type
615 * @enum _Ecore_Con_Type
616 * Types for an ecore_con client/server object. A correct way to set this type is
617 * with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if encryption is desired,
618 * and LOAD_CERT if the previously loaded certificate should be used.
619 * @code
620 * ECORE_CON_REMOTE_TCP | ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT
621 * @endcode
622 * @ingroup Ecore_Con_Server_Group
623 */
624typedef enum _Ecore_Con_Type
625{
626 /** Socket in ~/.ecore */
627 ECORE_CON_LOCAL_USER = 0,
628 /** Socket in /tmp */
629 ECORE_CON_LOCAL_SYSTEM = 1,
630 /** Abstract socket */
631 ECORE_CON_LOCAL_ABSTRACT = 2,
632 /** Remote server using TCP */
633 ECORE_CON_REMOTE_TCP = 3,
634 /** Remote multicast server */
635 ECORE_CON_REMOTE_MCAST = 4,
636 /** Remote server using UDP */
637 ECORE_CON_REMOTE_UDP = 5,
638 /** Remote broadcast using UDP */
639 ECORE_CON_REMOTE_BROADCAST = 6,
640 /** Remote connection sending packets immediately */
641 ECORE_CON_REMOTE_NODELAY = 7,
642 /** Remote connection sending data in large chunks
643 * @note Only available on Linux
644 * @since 1.2
645 */
646 ECORE_CON_REMOTE_CORK = 8,
647 /** Use SSL2: UNSUPPORTED. **/
648 ECORE_CON_USE_SSL2 = (1 << 4),
649 /** Use SSL3 */
650 ECORE_CON_USE_SSL3 = (1 << 5),
651 /** Use TLS */
652 ECORE_CON_USE_TLS = (1 << 6),
653 /** Use both TLS and SSL3 */
654 ECORE_CON_USE_MIXED = ECORE_CON_USE_SSL3 | ECORE_CON_USE_TLS,
655 /** Attempt to use the loaded certificate */
656 ECORE_CON_LOAD_CERT = (1 << 7)
657} Ecore_Con_Type;
658
659/**
660 * Initialises the Ecore_Con library.
661 * @return Number of times the library has been initialised without being
662 * shut down.
663 *
664 * @note This function already calls ecore_init() internally, so you don't need
665 * to call it explicitly.
666 */
667EAPI int ecore_con_init(void);
668
669/**
670 * Shuts down the Ecore_Con library.
671 * @return Number of times the library has been initialised without being
672 * shut down.
673 * @note This function already calls ecore_shutdown() internally, so you don't
674 * need to call it explicitly unless you called ecore_init() explicitly too.
675 */
676EAPI int ecore_con_shutdown(void);
677
678/**
679 * Do an asynchronous DNS lookup.
680 *
681 * @param name IP address or server name to translate.
682 * @param done_cb Callback to notify when done.
683 * @param data User data to be given to done_cb.
684 * @return EINA_TRUE if the request did not fail to be set up, EINA_FALSE if it
685 * failed.
686 *
687 * This function performs a DNS lookup on the hostname specified by @p name,
688 * then calls @p done_cb with the result and the @p data given as parameter.
689 * The result will be given to the @p done_cb as follows:
690 * @li @c canonname - the canonical name of the address
691 * @li @c ip - the resolved ip address
692 * @li @c addr - a pointer to the socket address
693 * @li @c addrlen - the length of the socket address, in bytes
694 * @li @c data - the data pointer given as parameter to ecore_con_lookup()
695 */
696EAPI Eina_Bool ecore_con_lookup(const char *name,
697 Ecore_Con_Dns_Cb done_cb,
698 const void *data);
699
700/**
701 * @}
702 */
703
704/**
705 * @defgroup Ecore_Con_SSL_Group Ecore Connection SSL Functions
706 *
707 * @{
708 */
709EAPI int ecore_con_ssl_available_get(void);
710EAPI Eina_Bool ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr, const char *cert);
711EAPI Eina_Bool ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr, const char *key_file);
712EAPI Eina_Bool ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, const char *crl_file);
713EAPI Eina_Bool ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, const char *ca_file);
714EAPI void ecore_con_ssl_server_verify(Ecore_Con_Server *svr);
715EAPI void ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr);
716EAPI void ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name);
717EAPI const char *ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr);
718EAPI Eina_Bool ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type compl_type);
719EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type compl_type);
720
721/**
722 * @}
723 */
724
725EAPI Ecore_Con_Socks *ecore_con_socks4_remote_add(const char *ip, int port, const char *username);
726EAPI Eina_Bool ecore_con_socks4_remote_exists(const char *ip, int port, const char *username);
727EAPI void ecore_con_socks4_remote_del(const char *ip, int port, const char *username);
728EAPI Ecore_Con_Socks *ecore_con_socks5_remote_add(const char *ip, int port, const char *username, const char *password);
729EAPI Eina_Bool ecore_con_socks5_remote_exists(const char *ip, int port, const char *username, const char *password);
730EAPI void ecore_con_socks5_remote_del(const char *ip, int port, const char *username, const char *password);
731EAPI void ecore_con_socks_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable);
732EAPI Eina_Bool ecore_con_socks_lookup_get(Ecore_Con_Socks *ecs);
733EAPI void ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind);
734EAPI Eina_Bool ecore_con_socks_bind_get(Ecore_Con_Socks *ecs);
735EAPI unsigned int ecore_con_socks_version_get(Ecore_Con_Socks *ecs);
736EAPI void ecore_con_socks_remote_del(Ecore_Con_Socks *ecs);
737EAPI void ecore_con_socks_apply_once(Ecore_Con_Socks *ecs);
738EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs);
739
740/**
741 * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions
742 *
743 * This group of functions is applied to an @ref Ecore_Con_Server object. It
744 * doesn't mean that they should be used in the server application, but on the
745 * server object. In fact, most of them should be used in the client
746 * application, when retrieving information or sending data.
747 *
748 * Setting up a server is very simple: you just need to start it with
749 * ecore_con_server_add() and setup some callbacks to the events
750 * @ref ECORE_CON_EVENT_CLIENT_ADD, @ref ECORE_CON_EVENT_CLIENT_DEL and
751 * @ref ECORE_CON_EVENT_CLIENT_DATA, that will be called when a client is
752 * communicating with the server:
753 *
754 * @code
755 * if (!(svr = ecore_con_server_add(ECORE_CON_REMOTE_TCP, "127.0.0.1", 8080, NULL)))
756 * exit(1);
757 *
758 * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, _add_cb, NULL);
759 * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, _del_cb, NULL);
760 * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, _data_cb, NULL);
761 *
762 * ecore_main_loop_begin();
763 * @endcode
764 *
765 * The function ecore_con_server_connect() can be used to write a client that
766 * connects to a server. The resulting code will be very similar to the server
767 * code:
768 *
769 * @code
770 * if (!(svr = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, "127.0.0.1", 8080, NULL)))
771 * exit(1);
772 *
773 * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _add_cb, NULL);
774 * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _del_cb, NULL);
775 * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _data_cb, NULL);
776 *
777 * ecore_main_loop_begin();
778 * @endcode
779 *
780 * After these two pieces of code are executed, respectively, in the server and
781 * client code, the server will be up and running and the client will try to
782 * connect to it. The connection, with its subsequent messages being sent from
783 * server to client and client to server, can be represented in the following
784 * sequence diagram:
785 *
786 * @htmlonly
787 * <img src="ecore_con-client-server.png" style="max-width: 400px"/>
788 * <a href="ecore_con-client-server.png">Full size</a>
789 * @endhtmlonly
790 *
791 * @image rtf ecore_con-client-server.png
792 * @image latex ecore_con-client-server.eps width=\textwidth
793 *
794 * Please notice the important difference between these two codes: the first is
795 * used for writing a @b server, while the second should be used for writing a
796 * @b client.
797 *
798 * A reference for the @c client functions can be found at @ref
799 * Ecore_Con_Client_Group.
800 *
801 * Examples of usage for this API can be found here:
802 * @li @ref ecore_con_server_simple_example_c
803 * @li @ref ecore_con_client_simple_example_c
804 *
805 * @{
806 */
807
808/**
809 * Creates a server to listen for connections.
810 *
811 * @param type The connection type.
812 * @param name Name to associate with the socket. It is used when
813 * generating the socket name of a Unix socket, or for
814 * determining what host to listen on for TCP sockets.
815 * @c NULL will not be accepted.
816 * @param port Number to identify socket. When a Unix socket is used,
817 * it becomes part of the socket name. When a TCP socket
818 * is used, it is used as the TCP port.
819 * @param data Data to associate with the created Ecore_Con_Server
820 * object.
821 * @return A new Ecore_Con_Server.
822 *
823 * The socket on which the server listens depends on the connection
824 * type:
825 * @li If @a type is @c ECORE_CON_LOCAL_USER, the server will listen on
826 * the Unix socket "~/.ecore/[name]/[port]".
827 * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen
828 * on Unix socket "/tmp/.ecore_service|[name]|[port]".
829 * @li If @a type is @c ECORE_CON_REMOTE_TCP, the server will listen
830 * on TCP port @c port.
831 *
832 * More information about the @p type can be found at @ref _Ecore_Con_Type.
833 *
834 * The @p data parameter can be fetched later using ecore_con_server_data_get()
835 * or changed with ecore_con_server_data_set().
836 */
837EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type,
838 const char *name, int port,
839 const void *data);
840
841/**
842 * Creates a connection to the specified server and returns an associated object.
843 *
844 * @param type The connection type.
845 * @param name Name used when determining what socket to connect to.
846 * It is used to generate the socket name when the socket
847 * is a Unix socket. It is used as the hostname when
848 * connecting with a TCP socket.
849 * @param port Number to identify the socket to connect to. Used when
850 * generating the socket name for a Unix socket, or as the
851 * TCP port when connecting to a TCP socket.
852 * @param data Data to associate with the created Ecore_Con_Server
853 * object.
854 * @return A new Ecore_Con_Server.
855 *
856 * The socket to which the connection is made depends on the connection type:
857 * @li If @a type is @c ECORE_CON_LOCAL_USER, the function will
858 * connect to the server at the Unix socket
859 * "~/.ecore/[name]/[port]".
860 * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the function will
861 * connect to the server at the Unix socket
862 * "/tmp/.ecore_service|[name]|[port]".
863 * @li If @a type is @c ECORE_CON_REMOTE_TCP, the function will
864 * connect to the server at the TCP port "[name]:[port]".
865 *
866 * More information about the @p type can be found at @ref _Ecore_Con_Type.
867 *
868 * This function won't block. It will either succeed, or fail due to invalid
869 * parameters, failed memory allocation, etc., returning @c NULL on that case.
870 *
871 * However, even if this call returns a valid @ref Ecore_Con_Server, the
872 * connection will only be successfully completed if an event of type
873 * @ref ECORE_CON_EVENT_SERVER_ADD is received. If it fails to complete, an
874 * @ref ECORE_CON_EVENT_SERVER_DEL will be received.
875 *
876 * The @p data parameter can be fetched later using ecore_con_server_data_get()
877 * or changed with ecore_con_server_data_set().
878 */
879EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type,
880 const char *name, int port,
881 const void *data);
882/**
883 * Closes the connection and frees the given server.
884 *
885 * @param svr The given server.
886 * @return Data associated with the server when it was created.
887 *
888 * All the clients connected to this server will be disconnected.
889 *
890 * @see ecore_con_server_add, ecore_con_server_connect
891 */
892EAPI void * ecore_con_server_del(Ecore_Con_Server *svr);
893
894/**
895 * Retrieves the data associated with the given server.
896 *
897 * @param svr The given server.
898 * @return The associated data.
899 *
900 * @see ecore_con_server_data_set()
901 */
902EAPI void * ecore_con_server_data_get(Ecore_Con_Server *svr);
903/**
904 * Sets the data associated with the given server.
905 *
906 * @param svr The given server.
907 * @param data The data to associate with @p svr
908 * @return The previously associated data, if any.
909 *
910 * @see ecore_con_server_data_get()
911 */
912EAPI void * ecore_con_server_data_set(Ecore_Con_Server *svr,
913 void *data);
914/**
915 * Retrieves whether the given server is currently connected.
916 *
917 * @param svr The given server.
918 * @return #EINA_TRUE if the server is connected. #EINA_FALSE otherwise.
919 */
920EAPI Eina_Bool ecore_con_server_connected_get(Ecore_Con_Server *svr);
921/**
922 * Retrieves the current list of clients.
923 *
924 * @param svr The given server.
925 * @return The list of clients on this server.
926 *
927 * Each node in the returned list points to an @ref Ecore_Con_Client. This list
928 * cannot be modified or freed. It can also change if new clients are connected
929 * or disconnected, and will become invalid when the server is deleted/freed.
930 */
931EAPI const Eina_List * ecore_con_server_clients_get(Ecore_Con_Server *svr);
932
933/**
934 * Retrieves the name of server.
935 *
936 * @param svr The given server.
937 * @return The name of the server.
938 *
939 * The name returned is the name used to connect on this server.
940 */
941EAPI const char * ecore_con_server_name_get(Ecore_Con_Server *svr);
942
943/**
944 * Retrieves the server port in use.
945 *
946 * @param svr The given server.
947 * @return The server port in use.
948 *
949 * The port where the server is listening for connections.
950 */
951EAPI int ecore_con_server_port_get(Ecore_Con_Server *svr);
952/**
953 * @brief Check how long a server has been connected
954 *
955 * @param svr The server to check
956 * @return The total time, in seconds, that the server has been
957 * connected/running
958 *
959 * This function is used to find out the time that has been elapsed since
960 * ecore_con_server_add() succeeded.
961 */
962EAPI double ecore_con_server_uptime_get(Ecore_Con_Server *svr);
963/**
964 * Sends the given data to the given server.
965 *
966 * @param svr The given server.
967 * @param data The given data.
968 * @param size Length of the data, in bytes, to send.
969 * @return The number of bytes sent. @c 0 will be returned if there is an
970 * error.
971 *
972 * This function will send the given data to the server as soon as the program
973 * is back to the main loop. Thus, this function returns immediately
974 * (non-blocking). If the data needs to be sent @b now, call
975 * ecore_con_server_flush() after this one.
976 *
977 * @see ecore_con_client_send()
978 * @see ecore_con_server_flush()
979 */
980EAPI int ecore_con_server_send(Ecore_Con_Server *svr,
981 const void *data,
982 int size);
983/**
984 * Sets a limit on the number of clients that can be handled concurrently
985 * by the given server, and a policy on what to do if excess clients try to
986 * connect.
987 *
988 * @param svr The given server.
989 * @param client_limit The maximum number of clients to handle
990 * concurrently. -1 means unlimited (default). 0
991 * effectively disables the server.
992 * @param reject_excess_clients Set to 1 to automatically disconnect
993 * excess clients as soon as they connect if you are
994 * already handling client_limit clients. Set to 0
995 * (default) to just hold off on the "accept()"
996 * system call until the number of active clients
997 * drops. This causes the kernel to queue up to 4096
998 * connections (or your kernel's limit, whichever is
999 * lower).
1000 *
1001 * Beware that if you set this once ecore is already running, you may
1002 * already have pending CLIENT_ADD events in your event queue. Those
1003 * clients have already connected and will not be affected by this call.
1004 * Only clients subsequently trying to connect will be affected.
1005 */
1006EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr,
1007 int client_limit,
1008 char reject_excess_clients);
1009/**
1010 * Gets the IP address of a server that has been connected to.
1011 *
1012 * @param svr The given server.
1013 * @return A pointer to an internal string that contains the IP address of
1014 * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
1015 * This string should not be modified or trusted to stay valid after
1016 * deletion for the @p svr object. If no IP is known NULL is returned.
1017 */
1018EAPI const char * ecore_con_server_ip_get(Ecore_Con_Server *svr);
1019/**
1020 * Flushes all pending data to the given server.
1021 *
1022 * @param svr The given server.
1023 *
1024 * This function will block until all data is sent to the server.
1025 *
1026 * @see ecore_con_server_send()
1027 * @see ecore_con_client_flush()
1028 */
1029EAPI void ecore_con_server_flush(Ecore_Con_Server *svr);
1030/**
1031 * Set the default time after which an inactive client will be disconnected
1032 *
1033 * @param svr The server object
1034 * @param timeout The timeout, in seconds, to disconnect after
1035 *
1036 * This function is used by the server to set the default idle timeout on
1037 * clients. If the any of the clients becomes idle for a time higher than this
1038 * value, it will be disconnected. A value of < 1 disables the idle timeout.
1039 *
1040 * This timeout is not affected by the one set by
1041 * ecore_con_client_timeout_set(). A client will be disconnected whenever the
1042 * client or the server timeout is reached. That means, the lower timeout value
1043 * will be used for that client if ecore_con_client_timeout_set() is used on it.
1044 *
1045 * @see ecore_con_server_timeout_get()
1046 * @see ecore_con_client_timeout_set()
1047 */
1048EAPI void ecore_con_server_timeout_set(Ecore_Con_Server *svr, double timeout);
1049/**
1050 * Get the default time after which an inactive client will be disconnected
1051 *
1052 * @param svr The server object
1053 * @return The timeout, in seconds, to disconnect after
1054 *
1055 * This function is used to get the idle timeout for clients. A value of < 1
1056 * means the idle timeout is disabled.
1057 *
1058 * @see ecore_con_server_timeout_set()
1059 * @see ecore_con_client_timeout_get()
1060 */
1061EAPI double ecore_con_server_timeout_get(Ecore_Con_Server *svr);
1062
1063/**
1064 * Get the fd that the server is connected to
1065 *
1066 * @param svr The server object
1067 * @return The fd, or -1 on failure
1068 *
1069 * This function returns the fd which is used by the underlying server connection.
1070 * It should not be tampered with unless you REALLY know what you are doing.
1071 * @note This function is only valid for servers created with ecore_con_server_connect()
1072 * @warning Seriously. Don't use this unless you know what you are doing.
1073 * @since 1.1
1074 */
1075EAPI int ecore_con_server_fd_get(Ecore_Con_Server *svr);
1076
1077/**
1078 * Get the fd that the client is connected to
1079 *
1080 * @param cl The client object
1081 * @return The fd, or -1 on failure
1082 *
1083 * This function returns the fd which is used by the underlying client connection.
1084 * It should not be tampered with unless you REALLY know what you are doing.
1085 * @since 1.1
1086 */
1087EAPI int ecore_con_client_fd_get(Ecore_Con_Client *cl);
1088/**
1089 * @}
1090 */
1091
1092/**
1093 * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions
1094 *
1095 * Functions to communicate with and/or set options on a client.
1096 *
1097 * This set of functions, as explained in @ref Ecore_Con_Server_Group, is used
1098 * to send data to a client, or to set options and get information about this
1099 * client. Most of them should be used on the server, applied on the client
1100 * object.
1101 *
1102 * If you need to implement a client, the way to connect to a server is
1103 * described in @ref Ecore_Con_Server_Group.
1104 *
1105 * An example of usage of these functions can be found at:
1106 * @li @ref ecore_con_client_simple_example_c
1107 *
1108 * @{
1109 */
1110
1111/**
1112 * Sends the given data to the given client.
1113 *
1114 * @param cl The given client.
1115 * @param data The given data.
1116 * @param size Length of the data, in bytes, to send.
1117 * @return The number of bytes sent. @c 0 will be returned if there is an
1118 * error.
1119 *
1120 * This function will send the given data to the client as soon as the program
1121 * is back to the main loop. Thus, this function returns immediately
1122 * (non-blocking). If the data needs to be sent @b now, call
1123 * ecore_con_client_flush() after this one.
1124 *
1125 * @see ecore_con_server_send()
1126 * @see ecore_con_client_flush()
1127 */
1128EAPI int ecore_con_client_send(Ecore_Con_Client *cl,
1129 const void *data,
1130 int size);
1131/**
1132 * Retrieves the server representing the socket the client has
1133 * connected to.
1134 *
1135 * @param cl The given client.
1136 * @return The server that the client connected to.
1137 */
1138EAPI Ecore_Con_Server *ecore_con_client_server_get(Ecore_Con_Client *cl);
1139/**
1140 * Closes the connection and frees memory allocated to the given client.
1141 *
1142 * @param cl The given client.
1143 * @return Data associated with the client.
1144 */
1145EAPI void * ecore_con_client_del(Ecore_Con_Client *cl);
1146/**
1147 * Sets the data associated with the given client to @p data.
1148 *
1149 * @param cl The given client.
1150 * @param data What to set the data to.
1151 */
1152EAPI void ecore_con_client_data_set(Ecore_Con_Client *cl,
1153 const void *data);
1154/**
1155 * Retrieves the data associated with the given client.
1156 *
1157 * @param cl The given client.
1158 * @return The data associated with @p cl.
1159 */
1160EAPI void * ecore_con_client_data_get(Ecore_Con_Client *cl);
1161
1162/**
1163 * Gets the IP address of a client that has connected.
1164 *
1165 * @param cl The given client.
1166 * @return A pointer to an internal string that contains the IP address of
1167 * the connected client in the form "XXX.YYY.ZZZ.AAA" IP notation.
1168 *
1169 * The returned string should not be modified, freed or trusted to stay valid
1170 * after deletion for the @p cl object. If no IP is known NULL is returned.
1171 */
1172EAPI const char * ecore_con_client_ip_get(Ecore_Con_Client *cl);
1173/**
1174 * Flushes all pending data to the given client.
1175 *
1176 * @param cl The given client.
1177 *
1178 * This function will block until all data is sent to the server.
1179 *
1180 * @see ecore_con_client_send()
1181 * @see ecore_con_server_flush()
1182 */
1183EAPI void ecore_con_client_flush(Ecore_Con_Client *cl);
1184/**
1185 * @brief Check how long a client has been connected
1186 *
1187 * @param cl The client to check
1188 * @return The total time, in seconds, that the client has been connected to
1189 * the server
1190 *
1191 * This function is used to find out how long a client has been connected for.
1192 */
1193EAPI double ecore_con_client_uptime_get(Ecore_Con_Client *cl);
1194/**
1195 * Get the default time after which the client will be disconnected when
1196 * inactive
1197 *
1198 * @param cl The client object
1199 * @return The timeout, in seconds, to disconnect after
1200 *
1201 * This function is used to get the idle timeout for a client. A value of < 1
1202 * means the idle timeout is disabled.
1203 *
1204 * @see ecore_con_client_timeout_set()
1205 */
1206EAPI double ecore_con_client_timeout_get(Ecore_Con_Client *cl);
1207/**
1208 * Set the time after which the client will be disconnected when inactive
1209 *
1210 * @param cl The client object
1211 * @param timeout The timeout, in seconds, to disconnect after
1212 *
1213 * This function is used by the server to set the idle timeout on a specific
1214 * client. If the client becomes idle for a time higher than this value, it will
1215 * be disconnected. A value of < 1 disables the idle timeout.
1216 *
1217 * This timeout is not affected by the one set by
1218 * ecore_con_server_timeout_set(). A client will be disconnected whenever the
1219 * client or the server timeout is reached. That means, the lower timeout value
1220 * will be used for that client if ecore_con_server_timeout_set() is used on the
1221 * server.
1222 *
1223 * @see ecore_con_client_timeout_get()
1224 * @see ecore_con_server_timeout_set()
1225 */
1226EAPI void ecore_con_client_timeout_set(Ecore_Con_Client *cl, double timeout);
1227/**
1228 * Returns whether the client is still connected
1229 *
1230 * @param cl The given client.
1231 * @return #EINA_TRUE if connected, else EINA_FALSE
1232 */
1233EAPI Eina_Bool ecore_con_client_connected_get(Ecore_Con_Client *cl);
1234/**
1235 * @brief Return the port that the client has connected to
1236 *
1237 * @param cl The client
1238 * @return The port that @p cl has connected to, or -1 on error
1239 * Use this function to return the port on which a given client has connected.
1240 */
1241EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl);
1242
1243
1244
1245/**
1246 * @}
1247 */
1248
1249/**
1250 * @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions
1251 *
1252 * Utility functions that set up, use and shut down the Ecore URL
1253 * Connection library.
1254 *
1255 * These functions are a shortcut to make it easy to perform http requests
1256 * (POST, GET, etc).
1257 *
1258 * Brief usage:
1259 * 1. Create an Ecore_Con_Url object with ecore_con_url_new(url);
1260 * 2. Register to receive the #ECORE_CON_EVENT_URL_COMPLETE event
1261 * (and optionally the #ECORE_CON_EVENT_URL_DATA and
1262 * #ECORE_CON_EVENT_URL_PROGRESS event to receive
1263 * the response, e.g. for HTTP/FTP downloads)
1264 * 3. Perform the operation with ecore_con_url_get(...);
1265 *
1266 * Note that it is good to reuse @ref Ecore_Con_Url objects wherever possible,
1267 * but bear in mind that each one can only perform one operation at a time. You
1268 * need to wait for the #ECORE_CON_EVENT_URL_COMPLETE event before re-using or
1269 * destroying the object.
1270 *
1271 * If it's necessary to change the @ref Ecore_Con_Url object url, use
1272 * ecore_con_url_url_set().
1273 *
1274 * Simple Usage 1 (HTTP GET):
1275 * @code
1276 * ecore_con_url_url_set(url_con, "http://www.google.com");
1277 * ecore_con_url_get(url_con);
1278 * @endcode
1279 *
1280 * Simple usage 2 (HTTP POST):
1281 * @code
1282 * ecore_con_url_url_set(url_con, "http://www.example.com/post_handler.cgi");
1283 * ecore_con_url_post(url_con, data, data_length, "multipart/form-data");
1284 * @endcode
1285 *
1286 * Simple Usage 3 (FTP download):
1287 * @code
1288 * fd = creat(filename, 0644)
1289 * ecore_con_url_url_set(url_con, "ftp://ftp.example.com/pub/myfile");
1290 * ecore_con_url_fd_set(url_con, fd);
1291 * ecore_con_url_get(url_con);
1292 * @endcode
1293 *
1294 * Simple Usage 4 (FTP upload as ftp://ftp.example.com/file):
1295 * @code
1296 * ecore_con_url_url_set(url_con, "ftp://ftp.example.com");
1297 * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass", NULL);
1298 * @endcode
1299 *
1300 * Simple Usage 5 (FTP upload as ftp://ftp.example.com/dir/file):
1301 * @code
1302 * ecore_con_url_url_set(url_con, "ftp://ftp.example.com");
1303 * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass","dir");
1304 * @endcode
1305 *
1306 * These are complete examples for the API:
1307 * @li @ref ecore_con_url_download_example.c "Downloading a file"
1308 * @li @ref ecore_con_url_headers_example.c "Setting many options for the
1309 * connection"
1310 *
1311 * @{
1312 */
1313
1314/**
1315 * @typedef Ecore_Con_Url_Time
1316 * @enum _Ecore_Con_Url_Time
1317 * The type of condition to use when making an HTTP request dependent on time,
1318 * so that headers such as "If-Modified-Since" are used.
1319 */
1320typedef enum _Ecore_Con_Url_Time
1321{
1322 /**
1323 * Do not place time restrictions on the HTTP requests.
1324 */
1325 ECORE_CON_URL_TIME_NONE = 0,
1326 /**
1327 * Add the "If-Modified-Since" HTTP header, so that the request is performed
1328 * by the server only if the target has been modified since the time value
1329 * passed to it in the request.
1330 */
1331 ECORE_CON_URL_TIME_IFMODSINCE,
1332 /**
1333 * Add the "If-Unmodified-Since" HTTP header, so that the request is
1334 * performed by the server only if the target has NOT been modified since
1335 * the time value passed to it in the request.
1336 */
1337 ECORE_CON_URL_TIME_IFUNMODSINCE
1338} Ecore_Con_Url_Time;
1339
1340/**
1341 * @typedef Ecore_Con_Url_Http_Version
1342 * @enum _Ecore_Con_Url_Http_Version
1343 * The http version to use
1344 * @since 1.2
1345 */
1346typedef enum _Ecore_Con_Url_Http_Version
1347{
1348 /**
1349 * HTTP version 1.0
1350 * @since 1.2
1351 */
1352 ECORE_CON_URL_HTTP_VERSION_1_0,
1353 /**
1354 * HTTP version 1.1 (default)
1355 * @since 1.2
1356 */
1357 ECORE_CON_URL_HTTP_VERSION_1_1
1358} Ecore_Con_Url_Http_Version;
1359
1360/**
1361 * Change the HTTP version used for the request
1362 * @param version The version to be used
1363 * @return EINA_TRUE on success, EINA_FALSE on failure to change version
1364 * @since 1.2
1365 * @see ecore_con_url_pipeline_get()
1366 */
1367EAPI Eina_Bool ecore_con_url_http_version_set(Ecore_Con_Url *url_con, Ecore_Con_Url_Http_Version version);
1368
1369/**
1370 * Initialises the Ecore_Con_Url library.
1371 * @return Number of times the library has been initialised without being
1372 * shut down.
1373 *
1374 * @note This function doesn't call ecore_con_init(). You still need to call it
1375 * explicitly before calling this one.
1376 */
1377EAPI int ecore_con_url_init(void);
1378
1379/**
1380 * Shuts down the Ecore_Con_Url library.
1381 * @return Number of calls that still uses Ecore_Con_Url
1382 *
1383 * @note This function doesn't call ecore_con_shutdown(). You still need to call
1384 * it explicitly after calling this one.
1385 */
1386EAPI int ecore_con_url_shutdown(void);
1387
1388/**
1389 * Enable or disable HTTP 1.1 pipelining.
1390 * @param enable EINA_TRUE will turn it on, EINA_FALSE will disable it.
1391 *
1392 * Pipelining allows to send one request after another one, without having to
1393 * wait for the reply of the first request. The respective replies are received
1394 * in the order that the requests were sent.
1395 *
1396 * Enabling this feature will be valid for all requests done using @c
1397 * ecore_con_url.
1398 *
1399 * See http://en.wikipedia.org/wiki/HTTP_pipelining for more info.
1400 *
1401 * @see ecore_con_url_pipeline_get()
1402 */
1403EAPI void ecore_con_url_pipeline_set(Eina_Bool enable);
1404/**
1405 * Is HTTP 1.1 pipelining enable ?
1406 * @return EINA_TRUE if it is enable.
1407 *
1408 * @see ecore_con_url_pipeline_set()
1409 */
1410EAPI Eina_Bool ecore_con_url_pipeline_get(void);
1411
1412/**
1413 * Creates and initializes a new Ecore_Con_Url connection object.
1414 *
1415 * @param url URL that will receive requests. Can be changed using
1416 * ecore_con_url_url_set.
1417 *
1418 * @return NULL on error, a new Ecore_Con_Url on success.
1419 *
1420 * Creates and initializes a new Ecore_Con_Url connection object that can be
1421 * used for sending requests.
1422 *
1423 * @see ecore_con_url_custom_new()
1424 * @see ecore_con_url_url_set()
1425 */
1426EAPI Ecore_Con_Url * ecore_con_url_new(const char *url);
1427/**
1428 * Creates a custom connection object.
1429 *
1430 * @param url URL that will receive requests
1431 * @param custom_request Custom request (e.g. GET, POST, HEAD, PUT, etc)
1432 *
1433 * @return NULL on error, a new Ecore_Con_Url on success.
1434 *
1435 * Creates and initializes a new Ecore_Con_Url for a custom request (e.g. HEAD,
1436 * SUBSCRIBE and other obscure HTTP requests). This object should be used like
1437 * one created with ecore_con_url_new().
1438 *
1439 * @see ecore_con_url_new()
1440 * @see ecore_con_url_url_set()
1441 */
1442EAPI Ecore_Con_Url * ecore_con_url_custom_new(const char *url,
1443 const char *custom_request);
1444/**
1445 * Destroys a Ecore_Con_Url connection object.
1446 *
1447 * @param url_con Connection object to free.
1448 *
1449 * @see ecore_con_url_new()
1450 */
1451EAPI void ecore_con_url_free(Ecore_Con_Url *url_con);
1452/**
1453 * Sets the URL to send the request to.
1454 *
1455 * @param url_con Connection object through which the request will be sent.
1456 * @param url URL that will receive the request
1457 *
1458 * @return EINA_TRUE on success, EINA_FALSE on error.
1459 *
1460 */
1461EAPI Eina_Bool ecore_con_url_url_set(Ecore_Con_Url *url_con,
1462 const char *url);
1463/**
1464 * Gets the URL to send the request to.
1465 *
1466 * @param url_con Connection object through which the request will be sent.
1467 * @return URL that will receive the request, NULL on failure. URL is stringshared.
1468 * @since 1.1
1469 */
1470EAPI const char *ecore_con_url_url_get(Ecore_Con_Url *url_con);
1471/**
1472 * Associates data with a connection object.
1473 *
1474 * @param url_con Connection object to associate data.
1475 * @param data Data to be set.
1476 *
1477 * Associates data with a connection object, which can be retrieved later with
1478 * ecore_con_url_data_get()).
1479 *
1480 * @see ecore_con_url_data_get()
1481 */
1482EAPI void ecore_con_url_data_set(Ecore_Con_Url *url_con,
1483 void *data);
1484/**
1485 * Retrieves data associated with a Ecore_Con_Url connection object.
1486 *
1487 * @param url_con Connection object to retrieve data from.
1488 *
1489 * @return Data associated with the given object.
1490 *
1491 * Retrieves data associated with a Ecore_Con_Url connection object (previously
1492 * set with ecore_con_url_data_set()).
1493 *
1494 * @see ecore_con_url_data_set()
1495 */
1496EAPI void * ecore_con_url_data_get(Ecore_Con_Url *url_con);
1497/**
1498 * Adds an additional header to the request connection object.
1499 *
1500 * @param url_con Connection object
1501 * @param key Header key
1502 * @param value Header value
1503 *
1504 * Adds an additional header (User-Agent, Content-Type, etc.) to the request
1505 * connection object. This addition will be valid for only one
1506 * ecore_con_url_get() or ecore_con_url_post() call.
1507 *
1508 * Some functions like ecore_con_url_time() also add headers to the request.
1509 *
1510 * @see ecore_con_url_get()
1511 * @see ecore_con_url_post()
1512 * @see ecore_con_url_additional_headers_clear()
1513 */
1514EAPI void ecore_con_url_additional_header_add(Ecore_Con_Url *url_con,
1515 const char *key,
1516 const char *value);
1517/**
1518 * Cleans additional headers.
1519 *
1520 * @param url_con Connection object to clean additional headers.
1521 *
1522 * Cleans additional headers associated with a connection object (previously
1523 * added with ecore_con_url_additional_header_add()).
1524 *
1525 * @see ecore_con_url_additional_header_add()
1526 * @see ecore_con_url_get()
1527 * @see ecore_con_url_post()
1528 */
1529EAPI void ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con);
1530/**
1531 * Retrieves headers from last request sent.
1532 *
1533 * @param url_con Connection object to retrieve response headers from.
1534 *
1535 * Retrieves a list containing the response headers. This function should be
1536 * used after an ECORE_CON_EVENT_URL_COMPLETE event (headers should normally be
1537 * ready at that time).
1538 *
1539 * @return List of response headers. This list must not be modified by the user.
1540 */
1541EAPI const Eina_List * ecore_con_url_response_headers_get(Ecore_Con_Url *url_con);
1542/**
1543 * Setup a file for receiving response data.
1544 *
1545 * @param url_con Connection object to set file
1546 * @param fd File descriptor associated with the file. A negative value will
1547 * unset any previously set fd.
1548 *
1549 * Sets up a file to have response data written into. Note that
1550 * ECORE_CON_EVENT_URL_DATA events will not be emitted if a file has been set to
1551 * receive the response data.
1552 *
1553 * This call can be used to easily setup a file where the downloaded data will
1554 * be saved.
1555 */
1556EAPI void ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd);
1557/**
1558 * Retrieves the number of bytes received.
1559 *
1560 * Retrieves the number of bytes received on the last request of the given
1561 * connection object.
1562 *
1563 * @param url_con Connection object which the request was sent on.
1564 *
1565 * @return Number of bytes received on request.
1566 *
1567 * @see ecore_con_url_get()
1568 * @see ecore_con_url_post()
1569 */
1570EAPI int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con);
1571/**
1572 * Sets url_con to use http auth, with given username and password, "safely" or not.
1573 *
1574 * @param url_con Connection object to perform a request on, previously created
1575 * with ecore_con_url_new() or ecore_con_url_custom_new().
1576 * @param username Username to use in authentication
1577 * @param password Password to use in authentication
1578 * @param safe Whether to use "safer" methods (eg, NOT http basic auth)
1579 *
1580 * @return #EINA_TRUE on success, #EINA_FALSE on error.
1581 *
1582 * ATTENTION: requires libcurl >= 7.19.1 to work, otherwise will always return 0.
1583 */
1584EAPI Eina_Bool ecore_con_url_httpauth_set(Ecore_Con_Url *url_con,
1585 const char *username,
1586 const char *password,
1587 Eina_Bool safe);
1588/**
1589 * Sends a get request.
1590 *
1591 * @param url_con Connection object to perform a request on, previously created
1592 *
1593 * @return #EINA_TRUE on success, #EINA_FALSE on error.
1594 *
1595 * The request is performed immediately, but you need to setup event handlers
1596 * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or
1597 * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result.
1598 *
1599 * @see ecore_con_url_custom_new()
1600 * @see ecore_con_url_additional_headers_clear()
1601 * @see ecore_con_url_additional_header_add()
1602 * @see ecore_con_url_data_set()
1603 * @see ecore_con_url_data_get()
1604 * @see ecore_con_url_response_headers_get()
1605 * @see ecore_con_url_time()
1606 * @see ecore_con_url_post()
1607 */
1608EAPI Eina_Bool ecore_con_url_get(Ecore_Con_Url *url_con);
1609/**
1610 * Sends a post request.
1611 *
1612 * @param url_con Connection object to perform a request on, previously created
1613 * with ecore_con_url_new() or ecore_con_url_custom_new().
1614 * @param data Payload (data sent on the request). Can be @c NULL.
1615 * @param length Payload length. If @c -1, rely on automatic length
1616 * calculation via @c strlen() on @p data.
1617 * @param content_type Content type of the payload (e.g. text/xml). Can be @c
1618 * NULL.
1619 *
1620 * @return #EINA_TRUE on success, #EINA_FALSE on error.
1621 *
1622 * The request starts immediately, but you need to setup event handlers
1623 * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or
1624 * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result.
1625 *
1626 * This call won't block your main loop.
1627 *
1628 * @see ecore_con_url_custom_new()
1629 * @see ecore_con_url_additional_headers_clear()
1630 * @see ecore_con_url_additional_header_add()
1631 * @see ecore_con_url_data_set()
1632 * @see ecore_con_url_data_get()
1633 * @see ecore_con_url_response_headers_get()
1634 * @see ecore_con_url_time()
1635 * @see ecore_con_url_get()
1636 */
1637EAPI Eina_Bool ecore_con_url_post(Ecore_Con_Url *url_con,
1638 const void *data, long length,
1639 const char *content_type);
1640/**
1641 * Sets whether HTTP requests should be conditional, dependent on
1642 * modification time.
1643 *
1644 * @param url_con Ecore_Con_Url to act upon.
1645 * @param time_condition Condition to use for HTTP requests.
1646 * @param timestamp Time since 1 Jan 1970 to use in the condition.
1647 *
1648 * This function may set the header "If-Modified-Since" or
1649 * "If-Unmodified-Since", depending on the value of @p time_condition, with the
1650 * value @p timestamp.
1651 *
1652 * @sa ecore_con_url_get()
1653 * @sa ecore_con_url_post()
1654 */
1655EAPI void ecore_con_url_time(Ecore_Con_Url *url_con,
1656 Ecore_Con_Url_Time time_condition,
1657 double timestamp);
1658
1659/**
1660 * @brief Uploads a file to an ftp site.
1661 * @param url_con The Ecore_Con_Url object to send with
1662 * @param filename The path to the file to send
1663 * @param user The username to log in with
1664 * @param pass The password to log in with
1665 * @param upload_dir The directory to which the file should be uploaded
1666 * @return #EINA_TRUE on success, else #EINA_FALSE.
1667 * Upload @p filename to an ftp server set in @p url_con using @p user
1668 * and @p pass to directory @p upload_dir
1669 */
1670EAPI Eina_Bool ecore_con_url_ftp_upload(Ecore_Con_Url *url_con,
1671 const char *filename,
1672 const char *user,
1673 const char *pass,
1674 const char *upload_dir);
1675/**
1676 * Toggle libcurl's verbose output.
1677 *
1678 * @param url_con Ecore_Con_Url instance which will be acted upon.
1679 * @param verbose Whether or not to enable libcurl's verbose output.
1680 *
1681 * If @p verbose is @c EINA_TRUE, libcurl will output a lot of verbose
1682 * information about its operations, which is useful for
1683 * debugging. The verbose information will be sent to stderr.
1684 */
1685EAPI void ecore_con_url_verbose_set(Ecore_Con_Url *url_con,
1686 Eina_Bool verbose);
1687/**
1688 * Enable or disable EPSV extension
1689 * @return FIXME: To be more documented.
1690 */
1691EAPI void ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con,
1692 Eina_Bool use_epsv);
1693
1694/**
1695 * Enables the cookie engine for subsequent HTTP requests.
1696 *
1697 * @param url_con Ecore_Con_Url instance which will be acted upon.
1698 *
1699 * After this function is called, cookies set by the server in HTTP responses
1700 * will be parsed and stored, as well as sent back to the server in new HTTP
1701 * requests.
1702 *
1703 * @note Even though this function is called @c ecore_con_url_cookies_init(),
1704 * there is no symmetrical shutdown operation.
1705 */
1706EAPI void ecore_con_url_cookies_init(Ecore_Con_Url *url_con);
1707/**
1708 * Controls whether session cookies from previous sessions shall be loaded.
1709 *
1710 * @param url_con Ecore_Con_Url instance which will be acted upon.
1711 * @param ignore If @c EINA_TRUE, ignore session cookies when loading cookies
1712 * from files. If @c EINA_FALSE, all cookies will be loaded.
1713 *
1714 * Session cookies are cookies with no expire date set, which usually means
1715 * they are removed after the current session is closed.
1716 *
1717 * By default, when Ecore_Con_Url loads cookies from a file, all cookies are
1718 * loaded, including session cookies, which, most of the time, were supposed
1719 * to be loaded and valid only for that session.
1720 *
1721 * If @p ignore is set to @c EINA_TRUE, when Ecore_Con_Url loads cookies from
1722 * the files passed to @c ecore_con_url_cookies_file_add(), session cookies
1723 * will not be loaded.
1724 *
1725 * @see ecore_con_url_cookies_file_add()
1726 */
1727EAPI void ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con,
1728 Eina_Bool ignore);
1729/**
1730 * Clears currently loaded cookies.
1731 * @param url_con Ecore_Con_Url instance which will be acted upon.
1732 *
1733 * The cleared cookies are removed and will not be sent in subsequent HTTP
1734 * requests, nor will they be written to the cookiejar file set via
1735 * @c ecore_con_url_cookies_jar_file_set().
1736 *
1737 * @note This function will initialize the cookie engine if it has not been
1738 * initialized yet.
1739 * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded
1740 * immediately, just when the request is started. Thus, if you ask to
1741 * clear the cookies, but has a file already set by that function, the
1742 * cookies will then be loaded and you will have old cookies set. In order
1743 * to don't have any old cookie set, you need to don't call
1744 * ecore_con_url_cookies_file_add() ever on the @p url_con handler, and
1745 * call this function to clear any cookie set by a previous request on
1746 * this handler.
1747 *
1748 * @see ecore_con_url_cookies_session_clear()
1749 * @see ecore_con_url_cookies_ignore_old_session_set()
1750 */
1751EAPI void ecore_con_url_cookies_clear(Ecore_Con_Url *url_con);
1752/**
1753 * Clears currently loaded session cookies.
1754 *
1755 * @param url_con Ecore_Con_Url instance which will be acted upon.
1756 *
1757 * Session cookies are cookies with no expire date set, which usually means
1758 * they are removed after the current session is closed.
1759 *
1760 * The cleared cookies are removed and will not be sent in subsequent HTTP
1761 * requests, nor will they be written to the cookiejar file set via
1762 * @c ecore_con_url_cookies_jar_file_set().
1763 *
1764 * @note This function will initialize the cookie engine if it has not been
1765 * initialized yet.
1766 * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded
1767 * immediately, just when the request is started. Thus, if you ask to
1768 * clear the session cookies, but has a file already set by that function,
1769 * the session cookies will then be loaded and you will have old cookies
1770 * set. In order to don't have any old session cookie set, you need to
1771 * don't call ecore_con_url_cookies_file_add() ever on the @p url_con
1772 * handler, and call this function to clear any session cookie set by a
1773 * previous request on this handler. An easier way to don't use old
1774 * session cookies is by using the function
1775 * ecore_con_url_cookies_ignore_old_session_set().
1776 *
1777 * @see ecore_con_url_cookies_clear()
1778 * @see ecore_con_url_cookies_ignore_old_session_set()
1779 */
1780EAPI void ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con);
1781/**
1782 * Adds a file to the list of files from which to load cookies.
1783 *
1784 * @param url_con Ecore_Con_Url instance which will be acted upon.
1785 * @param file_name Name of the file that will be added to the list.
1786 *
1787 * Files must contain cookies defined according to two possible formats:
1788 *
1789 * @li HTTP-style header ("Set-Cookie: ...").
1790 * @li <a href="http://www.cookiecentral.com/faq/#3.5">Netscape/Mozilla cookie data format.</a>
1791 *
1792 * Cookies will only be @b read from this file. If you want to save cookies to a
1793 * file, use ecore_con_url_cookies_jar_file_set(). Also notice that this
1794 * function supports the both types of cookie file cited above, while
1795 * ecore_con_url_cookies_jar_file_set() will save only in the Netscape/Mozilla's
1796 * format.
1797 *
1798 * Please notice that the file will not be read immediately, but rather added
1799 * to a list of files that will be loaded and parsed at a later time.
1800 *
1801 * @note This function will initialize the cookie engine if it has not been
1802 * initialized yet.
1803 *
1804 * @see ecore_con_url_cookies_ignore_old_session_set()
1805 * @see ecore_con_url_cookies_jar_file_set()
1806 */
1807EAPI void ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con,
1808 const char * const file_name);
1809/**
1810 * Sets the name of the file to which all current cookies will be written when
1811 * either cookies are flushed or Ecore_Con is shut down.
1812 *
1813 * @param url_con Ecore_Con_Url instance which will be acted upon.
1814 * @param cookiejar_file File to which the cookies will be written.
1815 *
1816 * @return @c EINA_TRUE is the file name has been set successfully,
1817 * @c EINA_FALSE otherwise.
1818 *
1819 * Cookies are written following Netscape/Mozilla's data format, also known as
1820 * cookie-jar.
1821 *
1822 * Cookies will only be @b saved to this file. If you need to read cookies from
1823 * a file, use ecore_con_url_cookies_file_add() instead.
1824 *
1825 * @note This function will initialize the cookie engine if it has not been
1826 * initialized yet.
1827 *
1828 * @see ecore_con_url_cookies_jar_write()
1829 */
1830EAPI Eina_Bool ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con,
1831 const char * const cookiejar_file);
1832/**
1833 * Writes all current cookies to the cookie jar immediately.
1834 *
1835 * @param url_con Ecore_Con_Url instance which will be acted upon.
1836 *
1837 * A cookie-jar file must have been previously set by
1838 * @c ecore_con_url_jar_file_set, otherwise nothing will be done.
1839 *
1840 * @note This function will initialize the cookie engine if it has not been
1841 * initialized yet.
1842 *
1843 * @see ecore_con_url_cookies_jar_file_set()
1844 */
1845EAPI void ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con);
1846
1847EAPI void ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con,
1848 Eina_Bool verify);
1849EAPI int ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con,
1850 const char *ca_path);
1851
1852/**
1853 * Set HTTP proxy to use.
1854 *
1855 * The parameter should be a char * to a zero terminated string holding
1856 * the host name or dotted IP address. To specify port number in this string,
1857 * append :[port] to the end of the host name.
1858 * The proxy string may be prefixed with [protocol]:// since any such prefix
1859 * will be ignored.
1860 * The proxy's port number may optionally be specified with the separate option.
1861 * If not specified, libcurl will default to using port 1080 for proxies.
1862 *
1863 * @param url_con Connection object that will use the proxy.
1864 * @param proxy Porxy string or @c NULL to disable
1865 *
1866 * @return #EINA_TRUE on success, #EINA_FALSE on error.
1867 * @since 1.2
1868 */
1869EAPI Eina_Bool ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy);
1870
1871/**
1872 * Set zero terminated username to use for proxy.
1873 *
1874 * if socks protocol is used for proxy, protocol should be socks5 and above.
1875 *
1876 * @param url_con Connection object that will use the proxy.
1877 * @param username Username string.
1878 *
1879 * @return #EINA_TRUE on success, #EINA_FALSE on error.
1880 *
1881 * @see ecore_con_url_proxy_set()
1882 *
1883 * @since 1.2
1884 */
1885EAPI Eina_Bool ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username);
1886
1887/**
1888 * Set zero terminated password to use for proxy.
1889 *
1890 * if socks protocol is used for proxy, protocol should be socks5 and above.
1891 *
1892 * @param url_con Connection object that will use the proxy.
1893 * @param password Password string.
1894 *
1895 * @return #EINA_TRUE on success, #EINA_FALSE on error.
1896 *
1897 * @see ecore_con_url_proxy_set()
1898 *
1899 * @since 1.2
1900 */
1901EAPI Eina_Bool ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password);
1902
1903/**
1904 * Set timeout in seconds.
1905 *
1906 * the maximum time in seconds that you allow the ecore con url transfer
1907 * operation to take. Normally, name lookups can take a considerable time
1908 * and limiting operations to less than a few minutes risk aborting perfectly
1909 * normal operations.
1910 *
1911 * @param url_con Connection object that will use the timeout.
1912 * @param timeout time in seconds.
1913 *
1914 * @see ecore_con_url_cookies_jar_file_set()
1915 *
1916 * @since 1.2
1917 */
1918EAPI void ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout);
1919
1920/**
1921 * Get the returned HTTP STATUS code
1922 *
1923 * This is used to, at any time, try to return the status code for a transmission.
1924 * @param url_con Connection object
1925 * @return A valid HTTP STATUS code, or 0 on failure
1926 *
1927 * @since 1.2
1928 */
1929EAPI int ecore_con_url_status_code_get(Ecore_Con_Url *url_con);
1930/**
1931 * @}
1932 */
1933
1934#ifdef __cplusplus
1935}
1936#endif
1937
1938#endif
diff --git a/libraries/ecore/src/lib/ecore_con/Makefile.am b/libraries/ecore/src/lib/ecore_con/Makefile.am
deleted file mode 100644
index 929b30e..0000000
--- a/libraries/ecore/src/lib/ecore_con/Makefile.am
+++ /dev/null
@@ -1,46 +0,0 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I$(top_builddir)/src/lib/ecore \
5-I$(top_builddir)/src/lib/ecore_con \
6-I$(top_srcdir)/src/lib/ecore \
7-I$(top_srcdir)/src/lib/ecore_con \
8@EFL_ECORE_CON_BUILD@ \
9@SSL_CFLAGS@ \
10@CURL_CFLAGS@ \
11@EINA_CFLAGS@ \
12@TLS_CFLAGS@ \
13@CARES_CFLAGS@ \
14@WIN32_CPPFLAGS@
15
16lib_LTLIBRARIES = libecore_con.la
17includes_HEADERS = Ecore_Con.h
18includesdir = $(includedir)/ecore-@VMAJ@
19
20libecore_con_la_SOURCES = \
21ecore_con.c \
22ecore_con_socks.c \
23ecore_con_ssl.c \
24ecore_con_url.c \
25ecore_con_alloc.c
26
27if ECORE_HAVE_WIN32
28libecore_con_la_SOURCES += ecore_con_local_win32.c
29else
30libecore_con_la_SOURCES += ecore_con_local.c
31endif
32
33if HAVE_CARES
34libecore_con_la_SOURCES += ecore_con_ares.c
35else
36libecore_con_la_SOURCES += ecore_con_info.c
37endif
38
39libecore_con_la_CFLAGS = @WIN32_CFLAGS@
40libecore_con_la_LIBADD = \
41$(top_builddir)/src/lib/ecore/libecore.la \
42@SSL_LIBS@ @CURL_LIBS@ @EINA_LIBS@ @TLS_LIBS@ @CARES_LIBS@ @WIN32_LIBS@
43
44libecore_con_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
45
46EXTRA_DIST = ecore_con_private.h
diff --git a/libraries/ecore/src/lib/ecore_con/Makefile.in b/libraries/ecore/src/lib/ecore_con/Makefile.in
deleted file mode 100644
index c35b08e..0000000
--- a/libraries/ecore/src/lib/ecore_con/Makefile.in
+++ /dev/null
@@ -1,935 +0,0 @@
1# Makefile.in generated by automake 1.11.1 from Makefile.am.
2# @configure_input@
3
4# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
5# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
6# Inc.
7# This Makefile.in is free software; the Free Software Foundation
8# gives unlimited permission to copy and/or distribute it,
9# with or without modifications, as long as this notice is preserved.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
13# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14# PARTICULAR PURPOSE.
15
16@SET_MAKE@
17
18
19VPATH = @srcdir@
20pkgdatadir = $(datadir)/@PACKAGE@
21pkgincludedir = $(includedir)/@PACKAGE@
22pkglibdir = $(libdir)/@PACKAGE@
23pkglibexecdir = $(libexecdir)/@PACKAGE@
24am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
25install_sh_DATA = $(install_sh) -c -m 644
26install_sh_PROGRAM = $(install_sh) -c
27install_sh_SCRIPT = $(install_sh) -c
28INSTALL_HEADER = $(INSTALL_DATA)
29transform = $(program_transform_name)
30NORMAL_INSTALL = :
31PRE_INSTALL = :
32POST_INSTALL = :
33NORMAL_UNINSTALL = :
34PRE_UNINSTALL = :
35POST_UNINSTALL = :
36build_triplet = @build@
37host_triplet = @host@
38@ECORE_HAVE_WIN32_TRUE@am__append_1 = ecore_con_local_win32.c
39@ECORE_HAVE_WIN32_FALSE@am__append_2 = ecore_con_local.c
40@HAVE_CARES_TRUE@am__append_3 = ecore_con_ares.c
41@HAVE_CARES_FALSE@am__append_4 = ecore_con_info.c
42subdir = src/lib/ecore_con
43DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \
44 $(srcdir)/Makefile.in
45ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
46am__aclocal_m4_deps = $(top_srcdir)/m4/ac_attribute.m4 \
47 $(top_srcdir)/m4/ac_path_generic.m4 \
48 $(top_srcdir)/m4/check_x_extension.m4 \
49 $(top_srcdir)/m4/ecore_check_module.m4 \
50 $(top_srcdir)/m4/ecore_check_options.m4 \
51 $(top_srcdir)/m4/efl_compiler_flag.m4 \
52 $(top_srcdir)/m4/efl_doxygen.m4 \
53 $(top_srcdir)/m4/efl_examples.m4 \
54 $(top_srcdir)/m4/efl_path_max.m4 $(top_srcdir)/m4/efl_tests.m4 \
55 $(top_srcdir)/m4/efl_threads.m4 $(top_srcdir)/m4/gettext.m4 \
56 $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
57 $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
58 $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
59 $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
60 $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
61 $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
62 $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
63am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
64 $(ACLOCAL_M4)
65mkinstalldirs = $(install_sh) -d
66CONFIG_HEADER = $(top_builddir)/config.h
67CONFIG_CLEAN_FILES =
68CONFIG_CLEAN_VPATH_FILES =
69am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
70am__vpath_adj = case $$p in \
71 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
72 *) f=$$p;; \
73 esac;
74am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
75am__install_max = 40
76am__nobase_strip_setup = \
77 srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
78am__nobase_strip = \
79 for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
80am__nobase_list = $(am__nobase_strip_setup); \
81 for p in $$list; do echo "$$p $$p"; done | \
82 sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
83 $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
84 if (++n[$$2] == $(am__install_max)) \
85 { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
86 END { for (dir in files) print dir, files[dir] }'
87am__base_list = \
88 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
89 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
90am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"
91LTLIBRARIES = $(lib_LTLIBRARIES)
92libecore_con_la_DEPENDENCIES = \
93 $(top_builddir)/src/lib/ecore/libecore.la
94am__libecore_con_la_SOURCES_DIST = ecore_con.c ecore_con_socks.c \
95 ecore_con_ssl.c ecore_con_url.c ecore_con_alloc.c \
96 ecore_con_local_win32.c ecore_con_local.c ecore_con_ares.c \
97 ecore_con_info.c
98@ECORE_HAVE_WIN32_TRUE@am__objects_1 = libecore_con_la-ecore_con_local_win32.lo
99@ECORE_HAVE_WIN32_FALSE@am__objects_2 = \
100@ECORE_HAVE_WIN32_FALSE@ libecore_con_la-ecore_con_local.lo
101@HAVE_CARES_TRUE@am__objects_3 = libecore_con_la-ecore_con_ares.lo
102@HAVE_CARES_FALSE@am__objects_4 = libecore_con_la-ecore_con_info.lo
103am_libecore_con_la_OBJECTS = libecore_con_la-ecore_con.lo \
104 libecore_con_la-ecore_con_socks.lo \
105 libecore_con_la-ecore_con_ssl.lo \
106 libecore_con_la-ecore_con_url.lo \
107 libecore_con_la-ecore_con_alloc.lo $(am__objects_1) \
108 $(am__objects_2) $(am__objects_3) $(am__objects_4)
109libecore_con_la_OBJECTS = $(am_libecore_con_la_OBJECTS)
110AM_V_lt = $(am__v_lt_$(V))
111am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
112am__v_lt_0 = --silent
113libecore_con_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
114 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
115 $(libecore_con_la_CFLAGS) $(CFLAGS) $(libecore_con_la_LDFLAGS) \
116 $(LDFLAGS) -o $@
117DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
118depcomp = $(SHELL) $(top_srcdir)/depcomp
119am__depfiles_maybe = depfiles
120am__mv = mv -f
121COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
122 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
123LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
124 $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
125 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
126 $(AM_CFLAGS) $(CFLAGS)
127AM_V_CC = $(am__v_CC_$(V))
128am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
129am__v_CC_0 = @echo " CC " $@;
130AM_V_at = $(am__v_at_$(V))
131am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
132am__v_at_0 = @
133CCLD = $(CC)
134LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
135 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
136 $(AM_LDFLAGS) $(LDFLAGS) -o $@
137AM_V_CCLD = $(am__v_CCLD_$(V))
138am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
139am__v_CCLD_0 = @echo " CCLD " $@;
140AM_V_GEN = $(am__v_GEN_$(V))
141am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
142am__v_GEN_0 = @echo " GEN " $@;
143SOURCES = $(libecore_con_la_SOURCES)
144DIST_SOURCES = $(am__libecore_con_la_SOURCES_DIST)
145HEADERS = $(includes_HEADERS)
146ETAGS = etags
147CTAGS = ctags
148DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
149ACLOCAL = @ACLOCAL@
150ALLOCA = @ALLOCA@
151AMTAR = @AMTAR@
152AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
153AR = @AR@
154AS = @AS@
155AUTOCONF = @AUTOCONF@
156AUTOHEADER = @AUTOHEADER@
157AUTOMAKE = @AUTOMAKE@
158AWK = @AWK@
159CARES_CFLAGS = @CARES_CFLAGS@
160CARES_LIBS = @CARES_LIBS@
161CC = @CC@
162CCDEPMODE = @CCDEPMODE@
163CFLAGS = @CFLAGS@
164CHECK_CFLAGS = @CHECK_CFLAGS@
165CHECK_LIBS = @CHECK_LIBS@
166CPP = @CPP@
167CPPFLAGS = @CPPFLAGS@
168CURL_CFLAGS = @CURL_CFLAGS@
169CURL_LIBS = @CURL_LIBS@
170CXX = @CXX@
171CXXCPP = @CXXCPP@
172CXXDEPMODE = @CXXDEPMODE@
173CXXFLAGS = @CXXFLAGS@
174CYGPATH_W = @CYGPATH_W@
175DEFS = @DEFS@
176DEPDIR = @DEPDIR@
177DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@
178DIRECTFB_LIBS = @DIRECTFB_LIBS@
179DLLTOOL = @DLLTOOL@
180DSYMUTIL = @DSYMUTIL@
181DUMPBIN = @DUMPBIN@
182ECHO_C = @ECHO_C@
183ECHO_N = @ECHO_N@
184ECHO_T = @ECHO_T@
185ECORE_XCB_CFLAGS = @ECORE_XCB_CFLAGS@
186ECORE_XCB_LIBS = @ECORE_XCB_LIBS@
187EFL_ECORE_BUILD = @EFL_ECORE_BUILD@
188EFL_ECORE_CON_BUILD = @EFL_ECORE_CON_BUILD@
189EFL_ECORE_EVAS_BUILD = @EFL_ECORE_EVAS_BUILD@
190EFL_ECORE_FILE_BUILD = @EFL_ECORE_FILE_BUILD@
191EFL_ECORE_IMF_BUILD = @EFL_ECORE_IMF_BUILD@
192EFL_ECORE_IMF_EVAS_BUILD = @EFL_ECORE_IMF_EVAS_BUILD@
193EFL_ECORE_INPUT_BUILD = @EFL_ECORE_INPUT_BUILD@
194EFL_ECORE_INPUT_EVAS_BUILD = @EFL_ECORE_INPUT_EVAS_BUILD@
195EFL_ECORE_IPC_BUILD = @EFL_ECORE_IPC_BUILD@
196EFL_ECORE_PSL1GHT_BUILD = @EFL_ECORE_PSL1GHT_BUILD@
197EFL_ECORE_SDL_BUILD = @EFL_ECORE_SDL_BUILD@
198EFL_ECORE_WIN32_BUILD = @EFL_ECORE_WIN32_BUILD@
199EFL_ECORE_WINCE_BUILD = @EFL_ECORE_WINCE_BUILD@
200EFL_PTHREAD_CFLAGS = @EFL_PTHREAD_CFLAGS@
201EFL_PTHREAD_LIBS = @EFL_PTHREAD_LIBS@
202EGREP = @EGREP@
203EINA_CFLAGS = @EINA_CFLAGS@
204EINA_LIBS = @EINA_LIBS@
205ESCAPE_CFLAGS = @ESCAPE_CFLAGS@
206ESCAPE_LIBS = @ESCAPE_LIBS@
207EVAS_CFLAGS = @EVAS_CFLAGS@
208EVAS_LIBS = @EVAS_LIBS@
209EVIL_CFLAGS = @EVIL_CFLAGS@
210EVIL_LIBS = @EVIL_LIBS@
211EXEEXT = @EXEEXT@
212EXOTIC_CFLAGS = @EXOTIC_CFLAGS@
213EXOTIC_LIBS = @EXOTIC_LIBS@
214FGREP = @FGREP@
215GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
216GLIB_CFLAGS = @GLIB_CFLAGS@
217GLIB_LIBS = @GLIB_LIBS@
218GMSGFMT = @GMSGFMT@
219GMSGFMT_015 = @GMSGFMT_015@
220GREP = @GREP@
221INSTALL = @INSTALL@
222INSTALL_DATA = @INSTALL_DATA@
223INSTALL_PROGRAM = @INSTALL_PROGRAM@
224INSTALL_SCRIPT = @INSTALL_SCRIPT@
225INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
226INTLLIBS = @INTLLIBS@
227INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
228KEYSYMDEFS = @KEYSYMDEFS@
229LD = @LD@
230LDFLAGS = @LDFLAGS@
231LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
232LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
233LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
234LIBICONV = @LIBICONV@
235LIBINTL = @LIBINTL@
236LIBOBJS = @LIBOBJS@
237LIBS = @LIBS@
238LIBTOOL = @LIBTOOL@
239LIPO = @LIPO@
240LN_S = @LN_S@
241LTLIBICONV = @LTLIBICONV@
242LTLIBINTL = @LTLIBINTL@
243LTLIBOBJS = @LTLIBOBJS@
244MAKEINFO = @MAKEINFO@
245MKDIR_P = @MKDIR_P@
246MSGFMT = @MSGFMT@
247MSGFMT_015 = @MSGFMT_015@
248MSGMERGE = @MSGMERGE@
249NM = @NM@
250NMEDIT = @NMEDIT@
251OBJC = @OBJC@
252OBJCDEPMODE = @OBJCDEPMODE@
253OBJCFLAGS = @OBJCFLAGS@
254OBJDUMP = @OBJDUMP@
255OBJEXT = @OBJEXT@
256OTOOL = @OTOOL@
257OTOOL64 = @OTOOL64@
258PACKAGE = @PACKAGE@
259PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
260PACKAGE_NAME = @PACKAGE_NAME@
261PACKAGE_STRING = @PACKAGE_STRING@
262PACKAGE_TARNAME = @PACKAGE_TARNAME@
263PACKAGE_URL = @PACKAGE_URL@
264PACKAGE_VERSION = @PACKAGE_VERSION@
265PATH_SEPARATOR = @PATH_SEPARATOR@
266PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
267PIXMAN_LIBS = @PIXMAN_LIBS@
268PKG_CONFIG = @PKG_CONFIG@
269PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
270PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
271POSUB = @POSUB@
272RANLIB = @RANLIB@
273SCIM_CFLAGS = @SCIM_CFLAGS@
274SCIM_LIBS = @SCIM_LIBS@
275SDL_CFLAGS = @SDL_CFLAGS@
276SDL_CONFIG = @SDL_CONFIG@
277SDL_LIBS = @SDL_LIBS@
278SED = @SED@
279SET_MAKE = @SET_MAKE@
280SHELL = @SHELL@
281SHM_OPEN_LIBS = @SHM_OPEN_LIBS@
282SSL_CFLAGS = @SSL_CFLAGS@
283SSL_LIBS = @SSL_LIBS@
284STRIP = @STRIP@
285TLS2_CFLAGS = @TLS2_CFLAGS@
286TLS2_LIBS = @TLS2_LIBS@
287TLS_CFLAGS = @TLS_CFLAGS@
288TLS_LIBS = @TLS_LIBS@
289TSLIB_CFLAGS = @TSLIB_CFLAGS@
290TSLIB_LIBS = @TSLIB_LIBS@
291USE_NLS = @USE_NLS@
292VERSION = @VERSION@
293VMAJ = @VMAJ@
294WAYLAND_CFLAGS = @WAYLAND_CFLAGS@
295WAYLAND_EGL_CFLAGS = @WAYLAND_EGL_CFLAGS@
296WAYLAND_EGL_LIBS = @WAYLAND_EGL_LIBS@
297WAYLAND_LIBS = @WAYLAND_LIBS@
298WIN32_CFLAGS = @WIN32_CFLAGS@
299WIN32_CPPFLAGS = @WIN32_CPPFLAGS@
300WIN32_LIBS = @WIN32_LIBS@
301XCB_COMPOSITE_CFLAGS = @XCB_COMPOSITE_CFLAGS@
302XCB_COMPOSITE_LIBS = @XCB_COMPOSITE_LIBS@
303XCB_CURSOR_CFLAGS = @XCB_CURSOR_CFLAGS@
304XCB_CURSOR_LIBS = @XCB_CURSOR_LIBS@
305XCB_DAMAGE_CFLAGS = @XCB_DAMAGE_CFLAGS@
306XCB_DAMAGE_LIBS = @XCB_DAMAGE_LIBS@
307XCB_DPMS_CFLAGS = @XCB_DPMS_CFLAGS@
308XCB_DPMS_LIBS = @XCB_DPMS_LIBS@
309XCB_RANDR_CFLAGS = @XCB_RANDR_CFLAGS@
310XCB_RANDR_LIBS = @XCB_RANDR_LIBS@
311XCB_RENDER_CFLAGS = @XCB_RENDER_CFLAGS@
312XCB_RENDER_LIBS = @XCB_RENDER_LIBS@
313XCB_SCREENSAVER_CFLAGS = @XCB_SCREENSAVER_CFLAGS@
314XCB_SCREENSAVER_LIBS = @XCB_SCREENSAVER_LIBS@
315XCB_SHAPE_CFLAGS = @XCB_SHAPE_CFLAGS@
316XCB_SHAPE_LIBS = @XCB_SHAPE_LIBS@
317XCB_SYNC_CFLAGS = @XCB_SYNC_CFLAGS@
318XCB_SYNC_LIBS = @XCB_SYNC_LIBS@
319XCB_X11_CFLAGS = @XCB_X11_CFLAGS@
320XCB_X11_LIBS = @XCB_X11_LIBS@
321XCB_XFIXES_CFLAGS = @XCB_XFIXES_CFLAGS@
322XCB_XFIXES_LIBS = @XCB_XFIXES_LIBS@
323XCB_XGESTURE_CFLAGS = @XCB_XGESTURE_CFLAGS@
324XCB_XGESTURE_LIBS = @XCB_XGESTURE_LIBS@
325XCB_XINERAMA_CFLAGS = @XCB_XINERAMA_CFLAGS@
326XCB_XINERAMA_LIBS = @XCB_XINERAMA_LIBS@
327XCB_XINPUT_CFLAGS = @XCB_XINPUT_CFLAGS@
328XCB_XINPUT_LIBS = @XCB_XINPUT_LIBS@
329XCB_XPRINT_CFLAGS = @XCB_XPRINT_CFLAGS@
330XCB_XPRINT_LIBS = @XCB_XPRINT_LIBS@
331XCB_XTEST_CFLAGS = @XCB_XTEST_CFLAGS@
332XCB_XTEST_LIBS = @XCB_XTEST_LIBS@
333XCOMPOSITE_CFLAGS = @XCOMPOSITE_CFLAGS@
334XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@
335XDAMAGE_CFLAGS = @XDAMAGE_CFLAGS@
336XDAMAGE_LIBS = @XDAMAGE_LIBS@
337XDPMS_CFLAGS = @XDPMS_CFLAGS@
338XDPMS_LIBS = @XDPMS_LIBS@
339XFIXES_CFLAGS = @XFIXES_CFLAGS@
340XFIXES_LIBS = @XFIXES_LIBS@
341XGESTURE_CFLAGS = @XGESTURE_CFLAGS@
342XGESTURE_LIBS = @XGESTURE_LIBS@
343XGETTEXT = @XGETTEXT@
344XGETTEXT_015 = @XGETTEXT_015@
345XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
346XI2_CFLAGS = @XI2_CFLAGS@
347XI2_LIBS = @XI2_LIBS@
348XINERAMA_CFLAGS = @XINERAMA_CFLAGS@
349XINERAMA_LIBS = @XINERAMA_LIBS@
350XKB_CFLAGS = @XKB_CFLAGS@
351XKB_LIBS = @XKB_LIBS@
352XMKMF = @XMKMF@
353XPRINT_CFLAGS = @XPRINT_CFLAGS@
354XPRINT_LIBS = @XPRINT_LIBS@
355XRANDR_CFLAGS = @XRANDR_CFLAGS@
356XRANDR_LIBS = @XRANDR_LIBS@
357XRENDER_CFLAGS = @XRENDER_CFLAGS@
358XRENDER_LIBS = @XRENDER_LIBS@
359XSS_CFLAGS = @XSS_CFLAGS@
360XSS_LIBS = @XSS_LIBS@
361XTEST_CFLAGS = @XTEST_CFLAGS@
362XTEST_LIBS = @XTEST_LIBS@
363X_CFLAGS = @X_CFLAGS@
364X_EXTRA_LIBS = @X_EXTRA_LIBS@
365X_LIBS = @X_LIBS@
366X_PRE_LIBS = @X_PRE_LIBS@
367Xcursor_cflags = @Xcursor_cflags@
368Xcursor_libs = @Xcursor_libs@
369abs_builddir = @abs_builddir@
370abs_srcdir = @abs_srcdir@
371abs_top_builddir = @abs_top_builddir@
372abs_top_srcdir = @abs_top_srcdir@
373ac_ct_CC = @ac_ct_CC@
374ac_ct_CXX = @ac_ct_CXX@
375ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
376ac_ct_OBJC = @ac_ct_OBJC@
377am__include = @am__include@
378am__leading_dot = @am__leading_dot@
379am__quote = @am__quote@
380am__tar = @am__tar@
381am__untar = @am__untar@
382bindir = @bindir@
383build = @build@
384build_alias = @build_alias@
385build_cpu = @build_cpu@
386build_os = @build_os@
387build_vendor = @build_vendor@
388builddir = @builddir@
389cocoa_ldflags = @cocoa_ldflags@
390datadir = @datadir@
391datarootdir = @datarootdir@
392dlopen_libs = @dlopen_libs@
393docdir = @docdir@
394dvidir = @dvidir@
395ecore_cocoa_cflags = @ecore_cocoa_cflags@
396ecore_cocoa_libs = @ecore_cocoa_libs@
397ecore_con_cflags = @ecore_con_cflags@
398ecore_con_libs = @ecore_con_libs@
399ecore_directfb_cflags = @ecore_directfb_cflags@
400ecore_directfb_libs = @ecore_directfb_libs@
401ecore_evas_cflags = @ecore_evas_cflags@
402ecore_evas_libs = @ecore_evas_libs@
403ecore_fb_cflags = @ecore_fb_cflags@
404ecore_fb_libs = @ecore_fb_libs@
405ecore_file_cflags = @ecore_file_cflags@
406ecore_file_libs = @ecore_file_libs@
407ecore_imf_cflags = @ecore_imf_cflags@
408ecore_imf_evas_cflags = @ecore_imf_evas_cflags@
409ecore_imf_evas_libs = @ecore_imf_evas_libs@
410ecore_imf_libs = @ecore_imf_libs@
411ecore_imf_scim_cflags = @ecore_imf_scim_cflags@
412ecore_imf_scim_libs = @ecore_imf_scim_libs@
413ecore_imf_xim_cflags = @ecore_imf_xim_cflags@
414ecore_imf_xim_libs = @ecore_imf_xim_libs@
415ecore_input_cflags = @ecore_input_cflags@
416ecore_input_evas_cflags = @ecore_input_evas_cflags@
417ecore_input_evas_libs = @ecore_input_evas_libs@
418ecore_input_libs = @ecore_input_libs@
419ecore_ipc_cflags = @ecore_ipc_cflags@
420ecore_ipc_libs = @ecore_ipc_libs@
421ecore_psl1ght_cflags = @ecore_psl1ght_cflags@
422ecore_psl1ght_libs = @ecore_psl1ght_libs@
423ecore_sdl_cflags = @ecore_sdl_cflags@
424ecore_sdl_libs = @ecore_sdl_libs@
425ecore_wayland_cflags = @ecore_wayland_cflags@
426ecore_wayland_libs = @ecore_wayland_libs@
427ecore_win32_cflags = @ecore_win32_cflags@
428ecore_win32_libs = @ecore_win32_libs@
429ecore_wince_cflags = @ecore_wince_cflags@
430ecore_wince_libs = @ecore_wince_libs@
431ecore_x_cflags = @ecore_x_cflags@
432ecore_x_libs = @ecore_x_libs@
433ecore_x_libs_private = @ecore_x_libs_private@
434efl_doxygen = @efl_doxygen@
435efl_have_doxygen = @efl_have_doxygen@
436exec_prefix = @exec_prefix@
437have_ecore_x_xcb_define = @have_ecore_x_xcb_define@
438host = @host@
439host_alias = @host_alias@
440host_cpu = @host_cpu@
441host_os = @host_os@
442host_vendor = @host_vendor@
443htmldir = @htmldir@
444includedir = @includedir@
445infodir = @infodir@
446install_sh = @install_sh@
447libdir = @libdir@
448libexecdir = @libexecdir@
449localedir = @localedir@
450localstatedir = @localstatedir@
451lt_ECHO = @lt_ECHO@
452lt_enable_auto_import = @lt_enable_auto_import@
453mandir = @mandir@
454mkdir_p = @mkdir_p@
455oldincludedir = @oldincludedir@
456pdfdir = @pdfdir@
457pkgconfig_requires_private = @pkgconfig_requires_private@
458prefix = @prefix@
459program_transform_name = @program_transform_name@
460psdir = @psdir@
461release_info = @release_info@
462requirements_ecore = @requirements_ecore@
463requirements_ecore_cocoa = @requirements_ecore_cocoa@
464requirements_ecore_con = @requirements_ecore_con@
465requirements_ecore_directfb = @requirements_ecore_directfb@
466requirements_ecore_evas = @requirements_ecore_evas@
467requirements_ecore_fb = @requirements_ecore_fb@
468requirements_ecore_file = @requirements_ecore_file@
469requirements_ecore_imf = @requirements_ecore_imf@
470requirements_ecore_imf_evas = @requirements_ecore_imf_evas@
471requirements_ecore_imf_scim = @requirements_ecore_imf_scim@
472requirements_ecore_imf_xim = @requirements_ecore_imf_xim@
473requirements_ecore_input = @requirements_ecore_input@
474requirements_ecore_input_evas = @requirements_ecore_input_evas@
475requirements_ecore_ipc = @requirements_ecore_ipc@
476requirements_ecore_psl1ght = @requirements_ecore_psl1ght@
477requirements_ecore_sdl = @requirements_ecore_sdl@
478requirements_ecore_wayland = @requirements_ecore_wayland@
479requirements_ecore_win32 = @requirements_ecore_win32@
480requirements_ecore_wince = @requirements_ecore_wince@
481requirements_ecore_x = @requirements_ecore_x@
482rt_libs = @rt_libs@
483sbindir = @sbindir@
484sharedstatedir = @sharedstatedir@
485srcdir = @srcdir@
486sysconfdir = @sysconfdir@
487target_alias = @target_alias@
488top_build_prefix = @top_build_prefix@
489top_builddir = @top_builddir@
490top_srcdir = @top_srcdir@
491version_info = @version_info@
492x_cflags = @x_cflags@
493x_includes = @x_includes@
494x_libs = @x_libs@
495MAINTAINERCLEANFILES = Makefile.in
496AM_CPPFLAGS = \
497-I$(top_builddir)/src/lib/ecore \
498-I$(top_builddir)/src/lib/ecore_con \
499-I$(top_srcdir)/src/lib/ecore \
500-I$(top_srcdir)/src/lib/ecore_con \
501@EFL_ECORE_CON_BUILD@ \
502@SSL_CFLAGS@ \
503@CURL_CFLAGS@ \
504@EINA_CFLAGS@ \
505@TLS_CFLAGS@ \
506@CARES_CFLAGS@ \
507@WIN32_CPPFLAGS@
508
509lib_LTLIBRARIES = libecore_con.la
510includes_HEADERS = Ecore_Con.h
511includesdir = $(includedir)/ecore-@VMAJ@
512libecore_con_la_SOURCES = ecore_con.c ecore_con_socks.c \
513 ecore_con_ssl.c ecore_con_url.c ecore_con_alloc.c \
514 $(am__append_1) $(am__append_2) $(am__append_3) \
515 $(am__append_4)
516libecore_con_la_CFLAGS = @WIN32_CFLAGS@
517libecore_con_la_LIBADD = \
518$(top_builddir)/src/lib/ecore/libecore.la \
519@SSL_LIBS@ @CURL_LIBS@ @EINA_LIBS@ @TLS_LIBS@ @CARES_LIBS@ @WIN32_LIBS@
520
521libecore_con_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
522EXTRA_DIST = ecore_con_private.h
523all: all-am
524
525.SUFFIXES:
526.SUFFIXES: .c .lo .o .obj
527$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
528 @for dep in $?; do \
529 case '$(am__configure_deps)' in \
530 *$$dep*) \
531 ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
532 && { if test -f $@; then exit 0; else break; fi; }; \
533 exit 1;; \
534 esac; \
535 done; \
536 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lib/ecore_con/Makefile'; \
537 $(am__cd) $(top_srcdir) && \
538 $(AUTOMAKE) --gnu src/lib/ecore_con/Makefile
539.PRECIOUS: Makefile
540Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
541 @case '$?' in \
542 *config.status*) \
543 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
544 *) \
545 echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
546 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
547 esac;
548
549$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
550 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
551
552$(top_srcdir)/configure: $(am__configure_deps)
553 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
554$(ACLOCAL_M4): $(am__aclocal_m4_deps)
555 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
556$(am__aclocal_m4_deps):
557install-libLTLIBRARIES: $(lib_LTLIBRARIES)
558 @$(NORMAL_INSTALL)
559 test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
560 @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
561 list2=; for p in $$list; do \
562 if test -f $$p; then \
563 list2="$$list2 $$p"; \
564 else :; fi; \
565 done; \
566 test -z "$$list2" || { \
567 echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
568 $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
569 }
570
571uninstall-libLTLIBRARIES:
572 @$(NORMAL_UNINSTALL)
573 @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
574 for p in $$list; do \
575 $(am__strip_dir) \
576 echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
577 $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
578 done
579
580clean-libLTLIBRARIES:
581 -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
582 @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
583 dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
584 test "$$dir" != "$$p" || dir=.; \
585 echo "rm -f \"$${dir}/so_locations\""; \
586 rm -f "$${dir}/so_locations"; \
587 done
588libecore_con.la: $(libecore_con_la_OBJECTS) $(libecore_con_la_DEPENDENCIES)
589 $(AM_V_CCLD)$(libecore_con_la_LINK) -rpath $(libdir) $(libecore_con_la_OBJECTS) $(libecore_con_la_LIBADD) $(LIBS)
590
591mostlyclean-compile:
592 -rm -f *.$(OBJEXT)
593
594distclean-compile:
595 -rm -f *.tab.c
596
597@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con.Plo@am__quote@
598@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_alloc.Plo@am__quote@
599@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_ares.Plo@am__quote@
600@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_info.Plo@am__quote@
601@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_local.Plo@am__quote@
602@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_local_win32.Plo@am__quote@
603@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_socks.Plo@am__quote@
604@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_ssl.Plo@am__quote@
605@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_url.Plo@am__quote@
606
607.c.o:
608@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
609@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
610@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
611@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
612@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
613@am__fastdepCC_FALSE@ $(COMPILE) -c $<
614
615.c.obj:
616@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
617@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
618@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
619@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
620@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
621@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
622
623.c.lo:
624@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
625@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
626@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
627@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
628@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
629@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
630
631libecore_con_la-ecore_con.lo: ecore_con.c
632@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con.Tpo -c -o libecore_con_la-ecore_con.lo `test -f 'ecore_con.c' || echo '$(srcdir)/'`ecore_con.c
633@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con.Tpo $(DEPDIR)/libecore_con_la-ecore_con.Plo
634@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
635@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con.c' object='libecore_con_la-ecore_con.lo' libtool=yes @AMDEPBACKSLASH@
636@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
637@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con.lo `test -f 'ecore_con.c' || echo '$(srcdir)/'`ecore_con.c
638
639libecore_con_la-ecore_con_socks.lo: ecore_con_socks.c
640@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_socks.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_socks.Tpo -c -o libecore_con_la-ecore_con_socks.lo `test -f 'ecore_con_socks.c' || echo '$(srcdir)/'`ecore_con_socks.c
641@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_socks.Tpo $(DEPDIR)/libecore_con_la-ecore_con_socks.Plo
642@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
643@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_socks.c' object='libecore_con_la-ecore_con_socks.lo' libtool=yes @AMDEPBACKSLASH@
644@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
645@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con_socks.lo `test -f 'ecore_con_socks.c' || echo '$(srcdir)/'`ecore_con_socks.c
646
647libecore_con_la-ecore_con_ssl.lo: ecore_con_ssl.c
648@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_ssl.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_ssl.Tpo -c -o libecore_con_la-ecore_con_ssl.lo `test -f 'ecore_con_ssl.c' || echo '$(srcdir)/'`ecore_con_ssl.c
649@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_ssl.Tpo $(DEPDIR)/libecore_con_la-ecore_con_ssl.Plo
650@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
651@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_ssl.c' object='libecore_con_la-ecore_con_ssl.lo' libtool=yes @AMDEPBACKSLASH@
652@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
653@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con_ssl.lo `test -f 'ecore_con_ssl.c' || echo '$(srcdir)/'`ecore_con_ssl.c
654
655libecore_con_la-ecore_con_url.lo: ecore_con_url.c
656@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_url.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_url.Tpo -c -o libecore_con_la-ecore_con_url.lo `test -f 'ecore_con_url.c' || echo '$(srcdir)/'`ecore_con_url.c
657@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_url.Tpo $(DEPDIR)/libecore_con_la-ecore_con_url.Plo
658@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
659@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_url.c' object='libecore_con_la-ecore_con_url.lo' libtool=yes @AMDEPBACKSLASH@
660@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
661@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con_url.lo `test -f 'ecore_con_url.c' || echo '$(srcdir)/'`ecore_con_url.c
662
663libecore_con_la-ecore_con_alloc.lo: ecore_con_alloc.c
664@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_alloc.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_alloc.Tpo -c -o libecore_con_la-ecore_con_alloc.lo `test -f 'ecore_con_alloc.c' || echo '$(srcdir)/'`ecore_con_alloc.c
665@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_alloc.Tpo $(DEPDIR)/libecore_con_la-ecore_con_alloc.Plo
666@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
667@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_alloc.c' object='libecore_con_la-ecore_con_alloc.lo' libtool=yes @AMDEPBACKSLASH@
668@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
669@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con_alloc.lo `test -f 'ecore_con_alloc.c' || echo '$(srcdir)/'`ecore_con_alloc.c
670
671libecore_con_la-ecore_con_local_win32.lo: ecore_con_local_win32.c
672@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_local_win32.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_local_win32.Tpo -c -o libecore_con_la-ecore_con_local_win32.lo `test -f 'ecore_con_local_win32.c' || echo '$(srcdir)/'`ecore_con_local_win32.c
673@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_local_win32.Tpo $(DEPDIR)/libecore_con_la-ecore_con_local_win32.Plo
674@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
675@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_local_win32.c' object='libecore_con_la-ecore_con_local_win32.lo' libtool=yes @AMDEPBACKSLASH@
676@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
677@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con_local_win32.lo `test -f 'ecore_con_local_win32.c' || echo '$(srcdir)/'`ecore_con_local_win32.c
678
679libecore_con_la-ecore_con_local.lo: ecore_con_local.c
680@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_local.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_local.Tpo -c -o libecore_con_la-ecore_con_local.lo `test -f 'ecore_con_local.c' || echo '$(srcdir)/'`ecore_con_local.c
681@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_local.Tpo $(DEPDIR)/libecore_con_la-ecore_con_local.Plo
682@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
683@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_local.c' object='libecore_con_la-ecore_con_local.lo' libtool=yes @AMDEPBACKSLASH@
684@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
685@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con_local.lo `test -f 'ecore_con_local.c' || echo '$(srcdir)/'`ecore_con_local.c
686
687libecore_con_la-ecore_con_ares.lo: ecore_con_ares.c
688@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_ares.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_ares.Tpo -c -o libecore_con_la-ecore_con_ares.lo `test -f 'ecore_con_ares.c' || echo '$(srcdir)/'`ecore_con_ares.c
689@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_ares.Tpo $(DEPDIR)/libecore_con_la-ecore_con_ares.Plo
690@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
691@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_ares.c' object='libecore_con_la-ecore_con_ares.lo' libtool=yes @AMDEPBACKSLASH@
692@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
693@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con_ares.lo `test -f 'ecore_con_ares.c' || echo '$(srcdir)/'`ecore_con_ares.c
694
695libecore_con_la-ecore_con_info.lo: ecore_con_info.c
696@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_info.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_info.Tpo -c -o libecore_con_la-ecore_con_info.lo `test -f 'ecore_con_info.c' || echo '$(srcdir)/'`ecore_con_info.c
697@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_info.Tpo $(DEPDIR)/libecore_con_la-ecore_con_info.Plo
698@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
699@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_info.c' object='libecore_con_la-ecore_con_info.lo' libtool=yes @AMDEPBACKSLASH@
700@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
701@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con_info.lo `test -f 'ecore_con_info.c' || echo '$(srcdir)/'`ecore_con_info.c
702
703mostlyclean-libtool:
704 -rm -f *.lo
705
706clean-libtool:
707 -rm -rf .libs _libs
708install-includesHEADERS: $(includes_HEADERS)
709 @$(NORMAL_INSTALL)
710 test -z "$(includesdir)" || $(MKDIR_P) "$(DESTDIR)$(includesdir)"
711 @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \
712 for p in $$list; do \
713 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
714 echo "$$d$$p"; \
715 done | $(am__base_list) | \
716 while read files; do \
717 echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includesdir)'"; \
718 $(INSTALL_HEADER) $$files "$(DESTDIR)$(includesdir)" || exit $$?; \
719 done
720
721uninstall-includesHEADERS:
722 @$(NORMAL_UNINSTALL)
723 @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \
724 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
725 test -n "$$files" || exit 0; \
726 echo " ( cd '$(DESTDIR)$(includesdir)' && rm -f" $$files ")"; \
727 cd "$(DESTDIR)$(includesdir)" && rm -f $$files
728
729ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
730 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
731 unique=`for i in $$list; do \
732 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
733 done | \
734 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
735 END { if (nonempty) { for (i in files) print i; }; }'`; \
736 mkid -fID $$unique
737tags: TAGS
738
739TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
740 $(TAGS_FILES) $(LISP)
741 set x; \
742 here=`pwd`; \
743 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
744 unique=`for i in $$list; do \
745 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
746 done | \
747 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
748 END { if (nonempty) { for (i in files) print i; }; }'`; \
749 shift; \
750 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
751 test -n "$$unique" || unique=$$empty_fix; \
752 if test $$# -gt 0; then \
753 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
754 "$$@" $$unique; \
755 else \
756 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
757 $$unique; \
758 fi; \
759 fi
760ctags: CTAGS
761CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
762 $(TAGS_FILES) $(LISP)
763 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
764 unique=`for i in $$list; do \
765 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
766 done | \
767 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
768 END { if (nonempty) { for (i in files) print i; }; }'`; \
769 test -z "$(CTAGS_ARGS)$$unique" \
770 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
771 $$unique
772
773GTAGS:
774 here=`$(am__cd) $(top_builddir) && pwd` \
775 && $(am__cd) $(top_srcdir) \
776 && gtags -i $(GTAGS_ARGS) "$$here"
777
778distclean-tags:
779 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
780
781distdir: $(DISTFILES)
782 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
783 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
784 list='$(DISTFILES)'; \
785 dist_files=`for file in $$list; do echo $$file; done | \
786 sed -e "s|^$$srcdirstrip/||;t" \
787 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
788 case $$dist_files in \
789 */*) $(MKDIR_P) `echo "$$dist_files" | \
790 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
791 sort -u` ;; \
792 esac; \
793 for file in $$dist_files; do \
794 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
795 if test -d $$d/$$file; then \
796 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
797 if test -d "$(distdir)/$$file"; then \
798 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
799 fi; \
800 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
801 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
802 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
803 fi; \
804 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
805 else \
806 test -f "$(distdir)/$$file" \
807 || cp -p $$d/$$file "$(distdir)/$$file" \
808 || exit 1; \
809 fi; \
810 done
811check-am: all-am
812check: check-am
813all-am: Makefile $(LTLIBRARIES) $(HEADERS)
814installdirs:
815 for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"; do \
816 test -z "$$dir" || $(MKDIR_P) "$$dir"; \
817 done
818install: install-am
819install-exec: install-exec-am
820install-data: install-data-am
821uninstall: uninstall-am
822
823install-am: all-am
824 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
825
826installcheck: installcheck-am
827install-strip:
828 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
829 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
830 `test -z '$(STRIP)' || \
831 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
832mostlyclean-generic:
833
834clean-generic:
835
836distclean-generic:
837 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
838 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
839
840maintainer-clean-generic:
841 @echo "This command is intended for maintainers to use"
842 @echo "it deletes files that may require special tools to rebuild."
843 -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
844clean: clean-am
845
846clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
847 mostlyclean-am
848
849distclean: distclean-am
850 -rm -rf ./$(DEPDIR)
851 -rm -f Makefile
852distclean-am: clean-am distclean-compile distclean-generic \
853 distclean-tags
854
855dvi: dvi-am
856
857dvi-am:
858
859html: html-am
860
861html-am:
862
863info: info-am
864
865info-am:
866
867install-data-am: install-includesHEADERS
868
869install-dvi: install-dvi-am
870
871install-dvi-am:
872
873install-exec-am: install-libLTLIBRARIES
874
875install-html: install-html-am
876
877install-html-am:
878
879install-info: install-info-am
880
881install-info-am:
882
883install-man:
884
885install-pdf: install-pdf-am
886
887install-pdf-am:
888
889install-ps: install-ps-am
890
891install-ps-am:
892
893installcheck-am:
894
895maintainer-clean: maintainer-clean-am
896 -rm -rf ./$(DEPDIR)
897 -rm -f Makefile
898maintainer-clean-am: distclean-am maintainer-clean-generic
899
900mostlyclean: mostlyclean-am
901
902mostlyclean-am: mostlyclean-compile mostlyclean-generic \
903 mostlyclean-libtool
904
905pdf: pdf-am
906
907pdf-am:
908
909ps: ps-am
910
911ps-am:
912
913uninstall-am: uninstall-includesHEADERS uninstall-libLTLIBRARIES
914
915.MAKE: install-am install-strip
916
917.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
918 clean-libLTLIBRARIES clean-libtool ctags distclean \
919 distclean-compile distclean-generic distclean-libtool \
920 distclean-tags distdir dvi dvi-am html html-am info info-am \
921 install install-am install-data install-data-am install-dvi \
922 install-dvi-am install-exec install-exec-am install-html \
923 install-html-am install-includesHEADERS install-info \
924 install-info-am install-libLTLIBRARIES install-man install-pdf \
925 install-pdf-am install-ps install-ps-am install-strip \
926 installcheck installcheck-am installdirs maintainer-clean \
927 maintainer-clean-generic mostlyclean mostlyclean-compile \
928 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
929 tags uninstall uninstall-am uninstall-includesHEADERS \
930 uninstall-libLTLIBRARIES
931
932
933# Tell versions [3.59,3.63) of GNU make to not export all variables.
934# Otherwise a system limit (for SysV at least) may be exceeded.
935.NOEXPORT:
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con.c b/libraries/ecore/src/lib/ecore_con/ecore_con.c
deleted file mode 100644
index fe83478..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con.c
+++ /dev/null
@@ -1,2583 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <string.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <errno.h>
10#include <unistd.h>
11#include <fcntl.h>
12
13#ifdef HAVE_NETINET_TCP_H
14# include <netinet/tcp.h>
15#endif
16
17#ifdef HAVE_NETINET_IN_H
18# include <netinet/in.h>
19#endif
20
21#ifdef HAVE_ARPA_INET_H
22# include <arpa/inet.h>
23#endif
24
25#ifdef HAVE_SYS_SOCKET_H
26# include <sys/socket.h>
27#endif
28
29#ifdef HAVE_SYS_UN_H
30# include <sys/un.h>
31#endif
32
33#ifdef HAVE_WS2TCPIP_H
34# include <ws2tcpip.h>
35#endif
36
37#ifdef HAVE_EVIL
38# include <Evil.h>
39#endif
40
41#include "Ecore.h"
42#include "ecore_private.h"
43#include "Ecore_Con.h"
44#include "ecore_con_private.h"
45
46static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl);
47static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl);
48static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr);
49static void _ecore_con_server_timer_update(Ecore_Con_Server *svr);
50
51static void _ecore_con_cb_tcp_connect(void *data,
52 Ecore_Con_Info *info);
53static void _ecore_con_cb_udp_connect(void *data,
54 Ecore_Con_Info *info);
55static void _ecore_con_cb_tcp_listen(void *data,
56 Ecore_Con_Info *info);
57static void _ecore_con_cb_udp_listen(void *data,
58 Ecore_Con_Info *info);
59
60static void _ecore_con_server_free(Ecore_Con_Server *svr);
61static void _ecore_con_client_free(Ecore_Con_Client *cl);
62
63static void _ecore_con_cl_read(Ecore_Con_Server *svr);
64static Eina_Bool _ecore_con_svr_tcp_handler(void *data,
65 Ecore_Fd_Handler *fd_handler);
66static Eina_Bool _ecore_con_cl_handler(void *data,
67 Ecore_Fd_Handler *fd_handler);
68static Eina_Bool _ecore_con_cl_udp_handler(void *data,
69 Ecore_Fd_Handler *fd_handler);
70static Eina_Bool _ecore_con_svr_udp_handler(void *data,
71 Ecore_Fd_Handler *fd_handler);
72
73static void _ecore_con_svr_cl_read(Ecore_Con_Client *cl);
74static Eina_Bool _ecore_con_svr_cl_handler(void *data,
75 Ecore_Fd_Handler *fd_handler);
76
77static void _ecore_con_server_flush(Ecore_Con_Server *svr);
78static void _ecore_con_client_flush(Ecore_Con_Client *cl);
79
80static void _ecore_con_event_client_add_free(Ecore_Con_Server *svr,
81 void *ev);
82static void _ecore_con_event_client_del_free(Ecore_Con_Server *svr,
83 void *ev);
84static void _ecore_con_event_client_data_free(Ecore_Con_Server *svr,
85 void *ev);
86static void _ecore_con_event_server_add_free(void *data,
87 void *ev);
88static void _ecore_con_event_server_del_free(void *data,
89 void *ev);
90static void _ecore_con_event_server_data_free(void *data,
91 void *ev);
92static void _ecore_con_event_server_error_free(void *data,
93 Ecore_Con_Event_Server_Error *e);
94static void _ecore_con_event_client_error_free(Ecore_Con_Server *svr,
95 Ecore_Con_Event_Client_Error *e);
96static void _ecore_con_event_server_write_free(void *data,
97 Ecore_Con_Event_Server_Write *e);
98static void _ecore_con_event_client_write_free(Ecore_Con_Server *svr,
99 Ecore_Con_Event_Client_Write *e);
100
101static void _ecore_con_lookup_done(void *data,
102 Ecore_Con_Info *infos);
103
104static const char * _ecore_con_pretty_ip(struct sockaddr *client_addr);
105
106
107void
108_ecore_con_client_kill(Ecore_Con_Client *cl)
109{
110 if (cl->delete_me)
111 DBG("Multi kill request for client %p", cl);
112 else
113 {
114 ecore_con_event_client_del(cl);
115 if (cl->buf) return;
116 }
117 INF("Lost client %s", (cl->ip) ? cl->ip : "");
118 if (cl->fd_handler)
119 ecore_main_fd_handler_del(cl->fd_handler);
120
121 cl->fd_handler = NULL;
122}
123
124void
125_ecore_con_server_kill(Ecore_Con_Server *svr)
126{
127 if (svr->delete_me)
128 DBG("Multi kill request for svr %p", svr);
129 else
130 ecore_con_event_server_del(svr);
131
132 if (svr->fd_handler)
133 ecore_main_fd_handler_del(svr->fd_handler);
134
135 svr->fd_handler = NULL;
136}
137
138#define _ecore_con_server_kill(svr) do { \
139 DBG("KILL %p", (svr)); \
140 _ecore_con_server_kill((svr)); \
141} while (0)
142
143#define _ecore_con_client_kill(cl) do { \
144 DBG("KILL %p", (cl)); \
145 _ecore_con_client_kill((cl)); \
146} while (0)
147
148EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0;
149EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0;
150EAPI int ECORE_CON_EVENT_SERVER_ADD = 0;
151EAPI int ECORE_CON_EVENT_SERVER_DEL = 0;
152EAPI int ECORE_CON_EVENT_CLIENT_DATA = 0;
153EAPI int ECORE_CON_EVENT_SERVER_DATA = 0;
154EAPI int ECORE_CON_EVENT_CLIENT_WRITE = 0;
155EAPI int ECORE_CON_EVENT_SERVER_WRITE = 0;
156EAPI int ECORE_CON_EVENT_CLIENT_ERROR = 0;
157EAPI int ECORE_CON_EVENT_SERVER_ERROR = 0;
158EAPI int ECORE_CON_EVENT_PROXY_BIND = 0;
159
160static Eina_List *servers = NULL;
161static int _ecore_con_init_count = 0;
162static int _ecore_con_event_count = 0;
163int _ecore_con_log_dom = -1;
164Ecore_Con_Socks *_ecore_con_proxy_once = NULL;
165Ecore_Con_Socks *_ecore_con_proxy_global = NULL;
166
167EAPI int
168ecore_con_init(void)
169{
170 if (++_ecore_con_init_count != 1)
171 return _ecore_con_init_count;
172
173#ifdef HAVE_EVIL
174 if (!evil_init())
175 return --_ecore_con_init_count;
176
177#endif
178
179 if (!ecore_init())
180 return --_ecore_con_init_count;
181
182 _ecore_con_log_dom = eina_log_domain_register
183 ("ecore_con", ECORE_CON_DEFAULT_LOG_COLOR);
184 if (_ecore_con_log_dom < 0)
185 {
186 EINA_LOG_ERR("Impossible to create a log domain for Ecore Con.");
187 ecore_shutdown();
188 return --_ecore_con_init_count;
189 }
190
191 ecore_con_mempool_init();
192
193 ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new();
194 ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new();
195 ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new();
196 ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new();
197 ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new();
198 ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new();
199 ECORE_CON_EVENT_CLIENT_WRITE = ecore_event_type_new();
200 ECORE_CON_EVENT_SERVER_WRITE = ecore_event_type_new();
201 ECORE_CON_EVENT_CLIENT_ERROR = ecore_event_type_new();
202 ECORE_CON_EVENT_SERVER_ERROR = ecore_event_type_new();
203 ECORE_CON_EVENT_PROXY_BIND = ecore_event_type_new();
204
205
206 eina_magic_string_set(ECORE_MAGIC_CON_SERVER, "Ecore_Con_Server");
207 eina_magic_string_set(ECORE_MAGIC_CON_CLIENT, "Ecore_Con_Server");
208 eina_magic_string_set(ECORE_MAGIC_CON_URL, "Ecore_Con_Url");
209
210 /* TODO Remember return value, if it fails, use gethostbyname() */
211 ecore_con_socks_init();
212 ecore_con_ssl_init();
213 ecore_con_info_init();
214
215 return _ecore_con_init_count;
216}
217
218EAPI int
219ecore_con_shutdown(void)
220{
221 Eina_List *l, *l2;
222 Ecore_Con_Server *svr;
223
224 if (--_ecore_con_init_count != 0)
225 return _ecore_con_init_count;
226
227 EINA_LIST_FOREACH_SAFE(servers, l, l2, svr)
228 {
229 Ecore_Con_Event_Server_Add *ev;
230
231 svr->delete_me = EINA_TRUE;
232 INF("svr %p is dead", svr);
233 /* some pointer hacks here to prevent double frees if people are being stupid */
234 EINA_LIST_FREE(svr->event_count, ev)
235 ev->server = NULL;
236 _ecore_con_server_free(svr);
237 }
238
239 ecore_con_socks_shutdown();
240 if (!_ecore_con_event_count) ecore_con_mempool_shutdown();
241
242 ecore_con_info_shutdown();
243 ecore_con_ssl_shutdown();
244 eina_log_domain_unregister(_ecore_con_log_dom);
245 _ecore_con_log_dom = -1;
246 ecore_shutdown();
247#ifdef HAVE_EVIL
248 evil_shutdown();
249#endif
250
251 return _ecore_con_init_count;
252}
253
254EAPI Eina_Bool
255ecore_con_lookup(const char *name,
256 Ecore_Con_Dns_Cb done_cb,
257 const void *data)
258{
259 Ecore_Con_Server *svr;
260 Ecore_Con_Lookup *lk;
261 struct addrinfo hints;
262
263 if (!name || !done_cb)
264 return EINA_FALSE;
265
266 svr = calloc(1, sizeof(Ecore_Con_Server));
267 if (!svr)
268 return EINA_FALSE;
269
270 lk = malloc(sizeof (Ecore_Con_Lookup));
271 if (!lk)
272 {
273 free(svr);
274 return EINA_FALSE;
275 }
276
277 lk->done_cb = done_cb;
278 lk->data = data;
279
280 svr->name = strdup(name);
281 if (!svr->name)
282 goto on_error;
283
284 svr->type = ECORE_CON_REMOTE_TCP;
285 svr->port = 1025;
286 svr->data = lk;
287 svr->created = EINA_TRUE;
288 svr->reject_excess_clients = EINA_FALSE;
289 svr->client_limit = -1;
290 svr->clients = NULL;
291 svr->ppid = getpid();
292
293 memset(&hints, 0, sizeof(struct addrinfo));
294 hints.ai_family = AF_UNSPEC;
295 hints.ai_socktype = SOCK_STREAM;
296 hints.ai_flags = AI_CANONNAME;
297 hints.ai_protocol = IPPROTO_TCP;
298 hints.ai_canonname = NULL;
299 hints.ai_next = NULL;
300 hints.ai_addr = NULL;
301
302 if (ecore_con_info_get(svr, _ecore_con_lookup_done, svr,
303 &hints))
304 return EINA_TRUE;
305
306 free(svr->name);
307on_error:
308 free(lk);
309 free(svr);
310 return EINA_FALSE;
311}
312
313/**
314 * @addtogroup Ecore_Con_Server_Group Ecore Connection Server Functions
315 *
316 * Functions that operate on Ecore server objects.
317 *
318 * @{
319 */
320
321/**
322 * @example ecore_con_server_example.c
323 * Shows how to write a simple server using the Ecore_Con library.
324 */
325
326EAPI Ecore_Con_Server *
327ecore_con_server_add(Ecore_Con_Type compl_type,
328 const char *name,
329 int port,
330 const void *data)
331{
332 Ecore_Con_Server *svr;
333 Ecore_Con_Type type;
334
335 if (port < 0 || !name)
336 return NULL; /* local user socket: FILE: ~/.ecore/[name]/[port] */
337
338 /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
339 /* remote system socket: TCP/IP: [name]:[port] */
340 svr = calloc(1, sizeof(Ecore_Con_Server));
341 if (!svr)
342 return NULL;
343
344 svr->name = strdup(name);
345 if (!svr->name)
346 goto error;
347
348 svr->type = compl_type;
349 svr->port = port;
350 svr->data = (void *)data;
351 svr->created = EINA_TRUE;
352 svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT;
353 svr->reject_excess_clients = EINA_FALSE;
354 svr->client_limit = -1;
355 svr->clients = NULL;
356 svr->ppid = getpid();
357 if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL))
358 goto error;
359
360 type = compl_type & ECORE_CON_TYPE;
361
362 if ((type == ECORE_CON_LOCAL_USER) ||
363 (type == ECORE_CON_LOCAL_SYSTEM) ||
364 (type == ECORE_CON_LOCAL_ABSTRACT))
365 /* Local */
366#ifdef _WIN32
367 if (!ecore_con_local_listen(svr))
368 goto error;
369#else
370 if (!ecore_con_local_listen(svr, _ecore_con_svr_tcp_handler, svr))
371 goto error;
372#endif
373
374 if ((type == ECORE_CON_REMOTE_TCP) ||
375 (type == ECORE_CON_REMOTE_NODELAY) ||
376 (type == ECORE_CON_REMOTE_CORK))
377 {
378 /* TCP */
379 if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen,
380 svr))
381 goto error;
382 }
383 else if ((type == ECORE_CON_REMOTE_MCAST) ||
384 (type == ECORE_CON_REMOTE_UDP))
385 /* UDP and MCAST */
386 if (!ecore_con_info_udp_listen(svr, _ecore_con_cb_udp_listen,
387 svr))
388 goto error;
389
390 servers = eina_list_append(servers, svr);
391 ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
392
393 return svr;
394
395error:
396 if (svr->name)
397 free(svr->name);
398
399 if (svr->path)
400 free(svr->path);
401
402
403 if (svr->fd_handler)
404 ecore_main_fd_handler_del(svr->fd_handler);
405
406 if (svr->fd > 0)
407 close(svr->fd);
408
409 if (svr->buf)
410 eina_binbuf_free(svr->buf);
411
412 if (svr->ip)
413 eina_stringshare_del(svr->ip);
414
415 ecore_con_ssl_server_shutdown(svr);
416 free(svr);
417 return NULL;
418}
419
420EAPI Ecore_Con_Server *
421ecore_con_server_connect(Ecore_Con_Type compl_type,
422 const char *name,
423 int port,
424 const void *data)
425{
426 Ecore_Con_Server *svr;
427 Ecore_Con_Type type;
428
429 if ((!name) || (!name[0]))
430 return NULL;
431 /* local user socket: FILE: ~/.ecore/[name]/[port] */
432 /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
433 /* remote system socket: TCP/IP: [name]:[port] */
434 svr = calloc(1, sizeof(Ecore_Con_Server));
435 if (!svr)
436 return NULL;
437
438 svr->name = strdup(name);
439 if (!svr->name)
440 goto error;
441
442 svr->type = compl_type;
443 svr->port = port;
444 svr->data = (void *)data;
445 svr->created = EINA_FALSE;
446 svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT;
447 svr->reject_excess_clients = EINA_FALSE;
448 svr->clients = NULL;
449 svr->client_limit = -1;
450
451 type = compl_type & ECORE_CON_TYPE;
452
453 if (type > ECORE_CON_LOCAL_ABSTRACT)
454 {
455 /* never use proxies on local connections */
456 if (_ecore_con_proxy_once)
457 svr->ecs = _ecore_con_proxy_once;
458 else if (_ecore_con_proxy_global)
459 svr->ecs = _ecore_con_proxy_global;
460 _ecore_con_proxy_once = NULL;
461 if (svr->ecs)
462 {
463 if ((!svr->ecs->lookup) &&
464 (!ecore_con_lookup(svr->name, (Ecore_Con_Dns_Cb)ecore_con_socks_dns_cb, svr)))
465 goto error;
466 if (svr->ecs->lookup)
467 svr->ecs_state = ECORE_CON_PROXY_STATE_RESOLVED;
468 }
469 }
470 if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL))
471 goto error;
472
473 if (((type == ECORE_CON_REMOTE_TCP) ||
474 (type == ECORE_CON_REMOTE_NODELAY) ||
475 (type == ECORE_CON_REMOTE_CORK) ||
476 (type == ECORE_CON_REMOTE_UDP) ||
477 (type == ECORE_CON_REMOTE_BROADCAST)) &&
478 (port < 0))
479 goto error;
480
481 if ((type == ECORE_CON_LOCAL_USER) ||
482 (type == ECORE_CON_LOCAL_SYSTEM) ||
483 (type == ECORE_CON_LOCAL_ABSTRACT))
484 /* Local */
485#ifdef _WIN32
486 if (!ecore_con_local_connect(svr, _ecore_con_cl_handler))
487 goto error;
488#else
489 if (!ecore_con_local_connect(svr, _ecore_con_cl_handler, svr))
490 goto error;
491#endif
492
493 if ((type == ECORE_CON_REMOTE_TCP) ||
494 (type == ECORE_CON_REMOTE_NODELAY) ||
495 (type == ECORE_CON_REMOTE_CORK))
496 {
497 /* TCP */
498 if (!ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect,
499 svr))
500 goto error;
501 }
502 else if ((type == ECORE_CON_REMOTE_UDP) ||
503 (type == ECORE_CON_REMOTE_BROADCAST))
504 /* UDP and MCAST */
505 if (!ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect,
506 svr))
507 goto error;
508
509 servers = eina_list_append(servers, svr);
510 ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
511
512 return svr;
513
514error:
515 if (svr->name)
516 free(svr->name);
517
518 if (svr->path)
519 free(svr->path);
520
521 if (svr->fd_handler)
522 ecore_main_fd_handler_del(svr->fd_handler);
523
524 if (svr->fd > 0)
525 close(svr->fd);
526
527 ecore_con_ssl_server_shutdown(svr);
528 free(svr);
529 return NULL;
530}
531
532EAPI void
533ecore_con_server_timeout_set(Ecore_Con_Server *svr,
534 double timeout)
535{
536 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
537 {
538 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_timeout_set");
539 return;
540 }
541
542 if (svr->created)
543 svr->client_disconnect_time = timeout;
544 else
545 svr->disconnect_time = timeout;
546}
547
548EAPI double
549ecore_con_server_timeout_get(Ecore_Con_Server *svr)
550{
551 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
552 {
553 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_timeout_get");
554 return 0;
555 }
556
557 return svr->created ? svr->client_disconnect_time : svr->disconnect_time;
558}
559
560EAPI void *
561ecore_con_server_del(Ecore_Con_Server *svr)
562{
563 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
564 {
565 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del");
566 return NULL;
567 }
568
569 if (svr->delete_me)
570 return NULL;
571
572 _ecore_con_server_kill(svr);
573 return svr->data;
574}
575
576EAPI void *
577ecore_con_server_data_get(Ecore_Con_Server *svr)
578{
579 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
580 {
581 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get");
582 return NULL;
583 }
584
585 return svr->data;
586}
587
588EAPI void *
589ecore_con_server_data_set(Ecore_Con_Server *svr,
590 void *data)
591{
592 void *ret = NULL;
593
594 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
595 {
596 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get");
597 return NULL;
598 }
599
600 ret = svr->data;
601 svr->data = data;
602 return ret;
603}
604
605EAPI Eina_Bool
606ecore_con_server_connected_get(Ecore_Con_Server *svr)
607{
608 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
609 {
610 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_connected_get");
611 return EINA_FALSE;
612 }
613
614 if (svr->connecting)
615 return EINA_FALSE;
616
617 return EINA_TRUE;
618}
619
620EAPI const Eina_List *
621ecore_con_server_clients_get(Ecore_Con_Server *svr)
622{
623 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
624 {
625 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER,
626 "ecore_con_server_clients_get");
627 return NULL;
628 }
629
630 return svr->clients;
631}
632
633EAPI const char *
634ecore_con_server_name_get(Ecore_Con_Server *svr)
635{
636 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
637 {
638 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER,
639 "ecore_con_server_name_get");
640 return NULL;
641 }
642
643 return svr->name;
644}
645
646EAPI int
647ecore_con_server_port_get(Ecore_Con_Server *svr)
648{
649 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
650 {
651 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER,
652 "ecore_con_server_port_get");
653 return -1;
654 }
655 return svr->port;
656}
657
658EAPI int
659ecore_con_server_send(Ecore_Con_Server *svr,
660 const void *data,
661 int size)
662{
663 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
664 {
665 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_send");
666 return 0;
667 }
668
669 EINA_SAFETY_ON_TRUE_RETURN_VAL(svr->delete_me, 0);
670
671 EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0);
672
673 EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0);
674
675 if (svr->fd_handler)
676 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
677
678 if (!svr->buf)
679 {
680 svr->buf = eina_binbuf_new();
681 EINA_SAFETY_ON_NULL_RETURN_VAL(svr->buf, 0);
682#ifdef TCP_CORK
683 if ((svr->fd >= 0) && ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK))
684 {
685 int state = 1;
686 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
687 /* realistically this isn't anything serious so we can just log and continue */
688 ERR("corking failed! %s", strerror(errno));
689 }
690#endif
691 }
692 eina_binbuf_append_length(svr->buf, data, size);
693
694 return size;
695}
696
697EAPI void
698ecore_con_server_client_limit_set(Ecore_Con_Server *svr,
699 int client_limit,
700 char reject_excess_clients)
701{
702 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
703 {
704 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER,
705 "ecore_con_server_client_limit_set");
706 return;
707 }
708
709 svr->client_limit = client_limit;
710 svr->reject_excess_clients = reject_excess_clients;
711}
712
713EAPI const char *
714ecore_con_server_ip_get(Ecore_Con_Server *svr)
715{
716 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
717 {
718 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_ip_get");
719 return NULL;
720 }
721
722 return svr->ip;
723}
724
725EAPI double
726ecore_con_server_uptime_get(Ecore_Con_Server *svr)
727{
728 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
729 {
730 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_uptime_get");
731 return -1;
732 }
733
734 return ecore_time_get() - svr->start_time;
735}
736
737EAPI void
738ecore_con_server_flush(Ecore_Con_Server *svr)
739{
740 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
741 {
742 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_flush");
743 return;
744 }
745
746 _ecore_con_server_flush(svr);
747}
748
749/**
750 * @}
751 */
752
753/**
754 * @addtogroup Ecore_Con_Client_Group Ecore Connection Client Functions
755 *
756 * Functions that operate on Ecore connection client objects.
757 *
758 * @{
759 */
760
761/**
762 * @example ecore_con_client_example.c
763 * Shows how to write a simple client that connects to the example server.
764 */
765
766EAPI int
767ecore_con_client_send(Ecore_Con_Client *cl,
768 const void *data,
769 int size)
770{
771 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
772 {
773 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_send");
774 return 0;
775 }
776
777 EINA_SAFETY_ON_TRUE_RETURN_VAL(cl->delete_me, 0);
778
779 EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0);
780
781 EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0);
782
783 if (cl->fd_handler)
784 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
785
786 if (cl->host_server && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP))
787 sendto(cl->host_server->fd, data, size, 0, (struct sockaddr *)cl->client_addr,
788 cl->client_addr_len);
789 else if (!cl->buf)
790 {
791 cl->buf = eina_binbuf_new();
792 EINA_SAFETY_ON_NULL_RETURN_VAL(cl->buf, 0);
793#ifdef TCP_CORK
794 if ((cl->fd >= 0) && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK))
795 {
796 int state = 1;
797 if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
798 /* realistically this isn't anything serious so we can just log and continue */
799 ERR("corking failed! %s", strerror(errno));
800 }
801#endif
802 }
803 eina_binbuf_append_length(cl->buf, data, size);
804
805 return size;
806}
807
808EAPI Ecore_Con_Server *
809ecore_con_client_server_get(Ecore_Con_Client *cl)
810{
811 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
812 {
813 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT,
814 "ecore_con_client_server_get");
815 return NULL;
816 }
817
818 return cl->host_server;
819}
820
821EAPI Eina_Bool
822ecore_con_client_connected_get(Ecore_Con_Client *cl)
823{
824 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
825 {
826 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT,
827 "ecore_con_client_connected_get");
828 return EINA_FALSE;
829 }
830
831 return !cl->delete_me;
832}
833
834EAPI void
835ecore_con_client_timeout_set(Ecore_Con_Client *cl,
836 double timeout)
837{
838 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
839 {
840 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT,
841 "ecore_con_client_timeout_set");
842 return;
843 }
844
845 cl->disconnect_time = timeout;
846
847 _ecore_con_cl_timer_update(cl);
848}
849
850EAPI double
851ecore_con_client_timeout_get(Ecore_Con_Client *cl)
852{
853 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
854 {
855 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_timeout_get");
856 return 0;
857 }
858
859 return cl->disconnect_time;
860}
861
862EAPI void *
863ecore_con_client_del(Ecore_Con_Client *cl)
864{
865 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
866 {
867 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del");
868 return NULL;
869 }
870
871 _ecore_con_client_kill(cl);
872 return cl->data;
873}
874
875EAPI void
876ecore_con_client_data_set(Ecore_Con_Client *cl,
877 const void *data)
878{
879 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
880 {
881 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_set");
882 return;
883 }
884
885 cl->data = (void *)data;
886}
887
888EAPI void *
889ecore_con_client_data_get(Ecore_Con_Client *cl)
890{
891 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
892 {
893 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_get");
894 return NULL;
895 }
896
897 return cl->data;
898}
899
900EAPI const char *
901ecore_con_client_ip_get(Ecore_Con_Client *cl)
902{
903 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
904 {
905 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_ip_get");
906 return NULL;
907 }
908 if (!cl->ip)
909 cl->ip = _ecore_con_pretty_ip(cl->client_addr);
910
911 return cl->ip;
912}
913
914EAPI int
915ecore_con_client_port_get(Ecore_Con_Client *cl)
916{
917 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
918 {
919 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_port_get");
920 return -1;
921 }
922 if (cl->client_addr->sa_family == AF_INET)
923 return ((struct sockaddr_in*)cl->client_addr)->sin_port;
924#ifdef HAVE_IPV6
925 return ((struct sockaddr_in6*)cl->client_addr)->sin6_port;
926#else
927 return -1;
928#endif
929}
930
931EAPI double
932ecore_con_client_uptime_get(Ecore_Con_Client *cl)
933{
934 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
935 {
936 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_uptime_get");
937 return -1;
938 }
939
940 return ecore_time_get() - cl->start_time;
941}
942
943EAPI void
944ecore_con_client_flush(Ecore_Con_Client *cl)
945{
946 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
947 {
948 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_flush");
949 return;
950 }
951
952 _ecore_con_client_flush(cl);
953}
954
955EAPI int
956ecore_con_server_fd_get(Ecore_Con_Server *svr)
957{
958 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
959 {
960 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
961 return -1;
962 }
963 if (svr->created) return -1;
964 return ecore_main_fd_handler_fd_get(svr->fd_handler);
965}
966
967EAPI int
968ecore_con_client_fd_get(Ecore_Con_Client *cl)
969{
970 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
971 {
972 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__);
973 return -1;
974 }
975 return ecore_main_fd_handler_fd_get(cl->fd_handler);
976}
977
978/**
979 * @}
980 */
981
982void
983ecore_con_event_proxy_bind(Ecore_Con_Server *svr)
984{
985 Ecore_Con_Event_Proxy_Bind *e;
986 int ev = ECORE_CON_EVENT_PROXY_BIND;
987
988 e = ecore_con_event_proxy_bind_alloc();
989 EINA_SAFETY_ON_NULL_RETURN(e);
990
991 svr->event_count = eina_list_append(svr->event_count, e);
992 _ecore_con_server_timer_update(svr);
993 e->server = svr;
994 e->ip = svr->proxyip;
995 e->port = svr->proxyport;
996 ecore_event_add(ev, e,
997 _ecore_con_event_server_add_free, NULL);
998 _ecore_con_event_count++;
999}
1000
1001void
1002ecore_con_event_server_add(Ecore_Con_Server *svr)
1003{
1004 /* we got our server! */
1005 Ecore_Con_Event_Server_Add *e;
1006 int ev = ECORE_CON_EVENT_SERVER_ADD;
1007
1008 e = ecore_con_event_server_add_alloc();
1009 EINA_SAFETY_ON_NULL_RETURN(e);
1010
1011 svr->connecting = EINA_FALSE;
1012 svr->start_time = ecore_time_get();
1013 svr->event_count = eina_list_append(svr->event_count, e);
1014 _ecore_con_server_timer_update(svr);
1015 e->server = svr;
1016 if (svr->upgrade) ev = ECORE_CON_EVENT_SERVER_UPGRADE;
1017 ecore_event_add(ev, e,
1018 _ecore_con_event_server_add_free, NULL);
1019 _ecore_con_event_count++;
1020}
1021
1022void
1023ecore_con_event_server_del(Ecore_Con_Server *svr)
1024{
1025 Ecore_Con_Event_Server_Del *e;
1026
1027 svr->delete_me = EINA_TRUE;
1028 INF("svr %p is dead", svr);
1029 e = ecore_con_event_server_del_alloc();
1030 EINA_SAFETY_ON_NULL_RETURN(e);
1031
1032 svr->event_count = eina_list_append(svr->event_count, e);
1033 _ecore_con_server_timer_update(svr);
1034 e->server = svr;
1035 if (svr->ecs)
1036 {
1037 svr->ecs_state = svr->ecs->lookup ? ECORE_CON_PROXY_STATE_RESOLVED : ECORE_CON_PROXY_STATE_DONE;
1038 eina_stringshare_replace(&svr->proxyip, NULL);
1039 svr->proxyport = 0;
1040 }
1041 ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e,
1042 _ecore_con_event_server_del_free, NULL);
1043 _ecore_con_event_count++;
1044}
1045
1046void
1047ecore_con_event_server_write(Ecore_Con_Server *svr, int num)
1048{
1049 Ecore_Con_Event_Server_Write *e;
1050
1051 e = ecore_con_event_server_write_alloc();
1052 EINA_SAFETY_ON_NULL_RETURN(e);
1053
1054 INF("Wrote %d bytes", num);
1055 svr->event_count = eina_list_append(svr->event_count, e);
1056 e->server = svr;
1057 e->size = num;
1058 ecore_event_add(ECORE_CON_EVENT_SERVER_WRITE, e,
1059 (Ecore_End_Cb)_ecore_con_event_server_write_free, NULL);
1060 _ecore_con_event_count++;
1061}
1062
1063void
1064ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate)
1065{
1066 Ecore_Con_Event_Server_Data *e;
1067
1068 e = ecore_con_event_server_data_alloc();
1069 EINA_SAFETY_ON_NULL_RETURN(e);
1070
1071 svr->event_count = eina_list_append(svr->event_count, e);
1072 _ecore_con_server_timer_update(svr);
1073 e->server = svr;
1074 if (duplicate)
1075 {
1076 e->data = malloc(num);
1077 if (!e->data)
1078 {
1079 ERR("server data allocation failure !");
1080 _ecore_con_event_server_data_free(NULL, e);
1081 return;
1082 }
1083 memcpy(e->data, buf, num);
1084 }
1085 else
1086 e->data = buf;
1087 e->size = num;
1088 ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
1089 _ecore_con_event_server_data_free, NULL);
1090 _ecore_con_event_count++;
1091}
1092
1093void
1094ecore_con_event_client_add(Ecore_Con_Client *cl)
1095{
1096 Ecore_Con_Event_Client_Add *e;
1097 int ev = ECORE_CON_EVENT_CLIENT_ADD;
1098
1099 e = ecore_con_event_client_add_alloc();
1100 EINA_SAFETY_ON_NULL_RETURN(e);
1101
1102 cl->event_count = eina_list_append(cl->event_count, e);
1103 cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e);
1104 _ecore_con_cl_timer_update(cl);
1105 e->client = cl;
1106 if (cl->upgrade) ev = ECORE_CON_EVENT_CLIENT_UPGRADE;
1107 ecore_event_add(ev, e,
1108 (Ecore_End_Cb)_ecore_con_event_client_add_free, cl->host_server);
1109 _ecore_con_event_count++;
1110}
1111
1112void
1113ecore_con_event_client_del(Ecore_Con_Client *cl)
1114{
1115 Ecore_Con_Event_Client_Del *e;
1116
1117 if (!cl) return;
1118 cl->delete_me = EINA_TRUE;
1119 INF("cl %p is dead", cl);
1120 e = ecore_con_event_client_del_alloc();
1121 EINA_SAFETY_ON_NULL_RETURN(e);
1122 cl->event_count = eina_list_append(cl->event_count, e);
1123
1124 cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e);
1125 _ecore_con_cl_timer_update(cl);
1126 e->client = cl;
1127 ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
1128 (Ecore_End_Cb)_ecore_con_event_client_del_free, cl->host_server);
1129 _ecore_con_event_count++;
1130}
1131
1132void
1133ecore_con_event_client_write(Ecore_Con_Client *cl, int num)
1134{
1135 Ecore_Con_Event_Client_Write *e;
1136
1137 e = ecore_con_event_client_write_alloc();
1138 EINA_SAFETY_ON_NULL_RETURN(e);
1139
1140 cl->event_count = eina_list_append(cl->event_count, e);
1141 cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e);
1142 e->client = cl;
1143 e->size = num;
1144 ecore_event_add(ECORE_CON_EVENT_CLIENT_WRITE, e,
1145 (Ecore_End_Cb)_ecore_con_event_client_write_free, cl->host_server);
1146 _ecore_con_event_count++;
1147}
1148
1149void
1150ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate)
1151{
1152 Ecore_Con_Event_Client_Data *e;
1153
1154 e = ecore_con_event_client_data_alloc();
1155 EINA_SAFETY_ON_NULL_RETURN(e);
1156
1157 cl->event_count = eina_list_append(cl->event_count, e);
1158 cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e);
1159 _ecore_con_cl_timer_update(cl);
1160 e->client = cl;
1161 if (duplicate)
1162 {
1163 e->data = malloc(num);
1164 if (!e->data)
1165 {
1166 ERR("client data allocation failure !");
1167 _ecore_con_event_client_data_free(cl->host_server, e);
1168 return;
1169 }
1170 memcpy(e->data, buf, num);
1171 }
1172 else
1173 e->data = buf;
1174 e->size = num;
1175 ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
1176 (Ecore_End_Cb)_ecore_con_event_client_data_free, cl->host_server);
1177 _ecore_con_event_count++;
1178}
1179
1180
1181void
1182ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info)
1183{
1184 svr->infos = eina_list_remove(svr->infos, info);
1185}
1186
1187void
1188_ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate)
1189{
1190 Ecore_Con_Event_Server_Error *e;
1191
1192 e = ecore_con_event_server_error_alloc();
1193 EINA_SAFETY_ON_NULL_RETURN(e);
1194
1195 e->server = svr;
1196 e->error = duplicate ? strdup(error) : error;
1197 ERR("%s", error);
1198 svr->event_count = eina_list_append(svr->event_count, e);
1199 ecore_event_add(ECORE_CON_EVENT_SERVER_ERROR, e, (Ecore_End_Cb)_ecore_con_event_server_error_free, NULL);
1200 _ecore_con_event_count++;
1201}
1202
1203void
1204ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error)
1205{
1206 Ecore_Con_Event_Client_Error *e;
1207
1208 e = ecore_con_event_client_error_alloc();
1209 EINA_SAFETY_ON_NULL_RETURN(e);
1210
1211 e->client = cl;
1212 e->error = strdup(error);
1213 ERR("%s", error);
1214 cl->event_count = eina_list_append(cl->event_count, e);
1215 cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e);
1216 ecore_event_add(ECORE_CON_EVENT_CLIENT_ERROR, e, (Ecore_End_Cb)_ecore_con_event_client_error_free, cl->host_server);
1217 _ecore_con_event_count++;
1218}
1219
1220static void
1221_ecore_con_server_free(Ecore_Con_Server *svr)
1222{
1223 Ecore_Con_Client *cl;
1224 double t_start, t;
1225
1226 if (svr->event_count) return;
1227
1228 while (svr->infos)
1229 {
1230 ecore_con_info_data_clear(svr->infos->data);
1231 svr->infos = eina_list_remove_list(svr->infos, svr->infos);
1232 }
1233
1234 t_start = ecore_time_get();
1235 while (svr->buf && (!svr->delete_me))
1236 {
1237 _ecore_con_server_flush(svr);
1238 t = ecore_time_get();
1239 if ((t - t_start) > 0.5)
1240 {
1241 WRN("ECORE_CON: EEK - stuck in _ecore_con_server_free() trying\n"
1242 " to flush data out from the server, and have been for\n"
1243 " %1.1f seconds. This is taking too long. Aborting flush.",
1244 (t - t_start));
1245 break;
1246 }
1247 }
1248
1249#ifdef _WIN32
1250 ecore_con_local_win32_server_del(svr);
1251#endif
1252 if (svr->event_count) return;
1253 ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
1254
1255 if (svr->buf)
1256 eina_binbuf_free(svr->buf);
1257
1258 EINA_LIST_FREE(svr->clients, cl)
1259 {
1260 Ecore_Con_Event_Server_Add *ev;
1261
1262 /* some pointer hacks here to prevent double frees if people are being stupid */
1263 EINA_LIST_FREE(cl->event_count, ev)
1264 ev->server = NULL;
1265 cl->delete_me = EINA_TRUE;
1266 INF("cl %p is dead", cl);
1267 _ecore_con_client_free(cl);
1268 }
1269 if ((svr->created) && (svr->path) && (svr->ppid == getpid()))
1270 unlink(svr->path);
1271
1272 ecore_con_ssl_server_shutdown(svr);
1273 free(svr->name);
1274
1275 free(svr->path);
1276
1277 eina_stringshare_del(svr->ip);
1278 eina_stringshare_del(svr->verify_name);
1279
1280 if (svr->ecs_buf) eina_binbuf_free(svr->ecs_buf);
1281 if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
1282
1283 if (svr->fd_handler)
1284 ecore_main_fd_handler_del(svr->fd_handler);
1285
1286 if (svr->fd > 0)
1287 close(svr->fd);
1288
1289 if (svr->until_deletion)
1290 ecore_timer_del(svr->until_deletion);
1291
1292 servers = eina_list_remove(servers, svr);
1293 svr->data = NULL;
1294 free(svr);
1295}
1296
1297static void
1298_ecore_con_client_free(Ecore_Con_Client *cl)
1299{
1300 double t_start, t;
1301
1302 if (cl->event_count) return;
1303
1304 t_start = ecore_time_get();
1305 while ((cl->buf) && (!cl->delete_me))
1306 {
1307 _ecore_con_client_flush(cl);
1308 t = ecore_time_get();
1309 if ((t - t_start) > 0.5)
1310 {
1311 WRN("EEK - stuck in _ecore_con_client_free() trying\n"
1312 " to flush data out from the client, and have been for\n"
1313 " %1.1f seconds. This is taking too long. Aborting flush.",
1314 (t - t_start));
1315 break;
1316 }
1317 }
1318
1319#ifdef _WIN32
1320 ecore_con_local_win32_client_del(cl);
1321#endif
1322
1323 if (cl->event_count) return;
1324 ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
1325
1326 if (cl->buf) eina_binbuf_free(cl->buf);
1327
1328 if (cl->host_server->type & ECORE_CON_SSL)
1329 ecore_con_ssl_client_shutdown(cl);
1330
1331 if (cl->fd_handler)
1332 ecore_main_fd_handler_del(cl->fd_handler);
1333
1334 if (cl->fd > 0)
1335 close(cl->fd);
1336
1337 free(cl->client_addr);
1338 cl->client_addr = NULL;
1339
1340 if (cl->until_deletion)
1341 ecore_timer_del(cl->until_deletion);
1342
1343 eina_stringshare_del(cl->ip);
1344 cl->data = NULL;
1345 free(cl);
1346 return;
1347}
1348
1349static Eina_Bool
1350_ecore_con_server_timer(Ecore_Con_Server *svr)
1351{
1352 ecore_con_server_del(svr);
1353
1354 svr->until_deletion = NULL;
1355 return ECORE_CALLBACK_CANCEL;
1356}
1357
1358static void
1359_ecore_con_server_timer_update(Ecore_Con_Server *svr)
1360{
1361 if (svr->disconnect_time)
1362 {
1363 if (svr->disconnect_time > 0)
1364 {
1365 if (svr->until_deletion)
1366 ecore_timer_interval_set(svr->until_deletion, svr->disconnect_time);
1367 else
1368 svr->until_deletion = ecore_timer_add(svr->disconnect_time, (Ecore_Task_Cb)_ecore_con_server_timer, svr);
1369 }
1370 else if (svr->until_deletion)
1371 {
1372 ecore_timer_del(svr->until_deletion);
1373 svr->until_deletion = NULL;
1374 }
1375 }
1376 else
1377 {
1378 if (svr->until_deletion)
1379 {
1380 ecore_timer_del(svr->until_deletion);
1381 svr->until_deletion = NULL;
1382 }
1383 }
1384}
1385
1386static Eina_Bool
1387_ecore_con_client_timer(Ecore_Con_Client *cl)
1388{
1389 ecore_con_client_del(cl);
1390
1391 cl->until_deletion = NULL;
1392 return ECORE_CALLBACK_CANCEL;
1393}
1394
1395static void
1396_ecore_con_cl_timer_update(Ecore_Con_Client *cl)
1397{
1398 if (cl->disconnect_time)
1399 {
1400 if (cl->disconnect_time > 0)
1401 {
1402 if (cl->until_deletion)
1403 ecore_timer_interval_set(cl->until_deletion, cl->disconnect_time);
1404 else
1405 cl->until_deletion = ecore_timer_add(cl->disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl);
1406 }
1407 else if (cl->until_deletion)
1408 {
1409 ecore_timer_del(cl->until_deletion);
1410 cl->until_deletion = NULL;
1411 }
1412 }
1413 else
1414 {
1415 if (cl->host_server->client_disconnect_time > 0)
1416 {
1417 if (cl->until_deletion)
1418 ecore_timer_interval_set(cl->until_deletion, cl->host_server->client_disconnect_time);
1419 else
1420 cl->until_deletion = ecore_timer_add(cl->host_server->client_disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl);
1421 }
1422 else if (cl->until_deletion)
1423 {
1424 ecore_timer_del(cl->until_deletion);
1425 cl->until_deletion = NULL;
1426 }
1427 }
1428}
1429
1430static void
1431_ecore_con_cb_tcp_listen(void *data,
1432 Ecore_Con_Info *net_info)
1433{
1434 Ecore_Con_Server *svr;
1435 struct linger lin;
1436 const char *memerr = NULL;
1437
1438 svr = data;
1439
1440 errno = 0;
1441 if (!net_info) /* error message has already been handled */
1442 goto error;
1443
1444 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1445 net_info->info.ai_protocol);
1446 if (svr->fd < 0) goto error;
1447 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1448 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1449
1450 lin.l_onoff = 1;
1451 lin.l_linger = 0;
1452 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
1453 sizeof(struct linger)) < 0)
1454 goto error;
1455
1456 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY)
1457 {
1458#ifdef HAVE_NETINET_TCP_H
1459 int flag = 1;
1460
1461 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,
1462 sizeof(int)) < 0)
1463#endif
1464 {
1465 goto error;
1466 }
1467 }
1468
1469 if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1470 goto error;
1471
1472 if (listen(svr->fd, 4096) < 0) goto error;
1473
1474 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1475 _ecore_con_svr_tcp_handler, svr, NULL, NULL);
1476 if (!svr->fd_handler)
1477 {
1478 memerr = "Memory allocation failure";
1479 goto error;
1480 }
1481
1482 return;
1483
1484error:
1485 if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno));
1486 ecore_con_ssl_server_shutdown(svr);
1487 _ecore_con_server_kill(svr);
1488}
1489
1490static void
1491_ecore_con_cb_udp_listen(void *data,
1492 Ecore_Con_Info *net_info)
1493{
1494 Ecore_Con_Server *svr;
1495 Ecore_Con_Type type;
1496 struct ip_mreq mreq;
1497#ifdef HAVE_IPV6
1498 struct ipv6_mreq mreq6;
1499#endif
1500 const int on = 1;
1501 const char *memerr = NULL;
1502
1503 svr = data;
1504 type = svr->type;
1505 type &= ECORE_CON_TYPE;
1506
1507 errno = 0;
1508 if (!net_info) /* error message has already been handled */
1509 goto error;
1510
1511 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1512 net_info->info.ai_protocol);
1513 if (svr->fd < 0) goto error;
1514
1515 if (type == ECORE_CON_REMOTE_MCAST)
1516 {
1517 if (net_info->info.ai_family == AF_INET)
1518 {
1519 if (!inet_pton(net_info->info.ai_family, net_info->ip,
1520 &mreq.imr_multiaddr))
1521 goto error;
1522
1523 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
1524 if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1525 (const void *)&mreq, sizeof(mreq)) != 0)
1526 goto error;
1527 }
1528#ifdef HAVE_IPV6
1529 else if (net_info->info.ai_family == AF_INET6)
1530 {
1531 if (!inet_pton(net_info->info.ai_family, net_info->ip,
1532 &mreq6.ipv6mr_multiaddr))
1533 goto error;
1534 mreq6.ipv6mr_interface = htonl(INADDR_ANY);
1535 if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1536 (const void *)&mreq6, sizeof(mreq6)) != 0)
1537 goto error;
1538 }
1539#endif
1540 }
1541
1542 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0)
1543 goto error;
1544 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1545 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1546
1547 if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1548 goto error;
1549
1550 svr->fd_handler =
1551 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1552 _ecore_con_svr_udp_handler, svr, NULL, NULL);
1553 if (!svr->fd_handler)
1554 {
1555 memerr = "Memory allocation failure";
1556 goto error;
1557 }
1558
1559 svr->ip = eina_stringshare_add(net_info->ip);
1560
1561 return;
1562
1563error:
1564 if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno));
1565 ecore_con_ssl_server_shutdown(svr);
1566 _ecore_con_server_kill(svr);
1567}
1568
1569static void
1570_ecore_con_cb_tcp_connect(void *data,
1571 Ecore_Con_Info *net_info)
1572{
1573 Ecore_Con_Server *svr;
1574 int res;
1575 int curstate = 0;
1576 const char *memerr = NULL;
1577
1578 svr = data;
1579
1580 errno = 0;
1581 if (!net_info) /* error message has already been handled */
1582 goto error;
1583
1584 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1585 net_info->info.ai_protocol);
1586 if (svr->fd < 0) goto error;
1587
1588 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1589 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1590
1591 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0)
1592 goto error;
1593
1594 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY)
1595 {
1596#ifdef HAVE_NETINET_TCP_H
1597 int flag = 1;
1598
1599 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0)
1600#endif
1601 {
1602 goto error;
1603 }
1604 }
1605
1606 res = connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen);
1607#ifdef _WIN32
1608 if (res == SOCKET_ERROR)
1609 {
1610 if (WSAGetLastError() != WSAEINPROGRESS)
1611 {
1612 char *err;
1613 err = evil_format_message(WSAGetLastError());
1614 _ecore_con_event_server_error(svr, err, EINA_FALSE);
1615 ecore_con_ssl_server_shutdown(svr);
1616 _ecore_con_server_kill(svr);
1617 return;
1618 }
1619
1620#else
1621 if (res < 0)
1622 {
1623 if (errno != EINPROGRESS) goto error;
1624#endif
1625 svr->connecting = EINA_TRUE;
1626 svr->fd_handler =
1627 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
1628 _ecore_con_cl_handler, svr, NULL, NULL);
1629 }
1630 else
1631 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1632 _ecore_con_cl_handler, svr, NULL, NULL);
1633
1634 if (svr->type & ECORE_CON_SSL)
1635 {
1636 svr->handshaking = EINA_TRUE;
1637 svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
1638 DBG("%s ssl handshake", svr->ecs_state ? "Queuing" : "Beginning");
1639 if ((!svr->ecs_state) && ecore_con_ssl_server_init(svr))
1640 goto error;
1641 }
1642
1643 if (!svr->fd_handler)
1644 {
1645 memerr = "Memory allocation failure";
1646 goto error;
1647 }
1648
1649 if ((!svr->ecs) || (svr->ecs->lookup))
1650 svr->ip = eina_stringshare_add(net_info->ip);
1651
1652 return;
1653
1654error:
1655 if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno));
1656 ecore_con_ssl_server_shutdown(svr);
1657 _ecore_con_server_kill(svr);
1658}
1659
1660static void
1661_ecore_con_cb_udp_connect(void *data,
1662 Ecore_Con_Info *net_info)
1663{
1664 Ecore_Con_Server *svr;
1665 int curstate = 0;
1666 int broadcast = 1;
1667 const char *memerr = NULL;
1668 svr = data;
1669
1670 errno = 0;
1671 if (!net_info) /* error message has already been handled */
1672 goto error;
1673
1674 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1675 net_info->info.ai_protocol);
1676 if (svr->fd < 0) goto error;
1677 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1678 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1679 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_BROADCAST)
1680 {
1681 if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST,
1682 (const void *)&broadcast,
1683 sizeof(broadcast)) < 0)
1684 {
1685 goto error;
1686 }
1687 }
1688 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR,
1689 (const void *)&curstate, sizeof(curstate)) < 0)
1690 goto error;
1691
1692 if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1693 goto error;
1694
1695 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
1696 _ecore_con_cl_udp_handler, svr, NULL, NULL);
1697
1698 if (!svr->fd_handler)
1699 {
1700 memerr = "Memory allocation failure";
1701 goto error;
1702 }
1703
1704 if ((!svr->ecs) || (svr->ecs->lookup))
1705 svr->ip = eina_stringshare_add(net_info->ip);
1706
1707 return;
1708
1709error:
1710 if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno));
1711 ecore_con_ssl_server_shutdown(svr);
1712 _ecore_con_server_kill(svr);
1713}
1714
1715static Ecore_Con_State
1716svr_try_connect_plain(Ecore_Con_Server *svr)
1717{
1718 int res;
1719 int so_err = 0;
1720 socklen_t size = sizeof(int);
1721
1722 res = getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, (void *)&so_err, &size);
1723#ifdef _WIN32
1724 if (res == SOCKET_ERROR)
1725 so_err = WSAGetLastError();
1726
1727 if ((so_err == WSAEINPROGRESS) && !svr->delete_me)
1728 return ECORE_CON_INPROGRESS;
1729
1730#else
1731 if (res < 0)
1732 so_err = errno;
1733
1734 if ((so_err == EINPROGRESS) && !svr->delete_me)
1735 return ECORE_CON_INPROGRESS;
1736
1737#endif
1738
1739 if (so_err)
1740 {
1741 /* we lost our server! */
1742 ecore_con_event_server_error(svr, strerror(so_err));
1743 ERR("Connection lost: %s", strerror(so_err));
1744 _ecore_con_server_kill(svr);
1745 return ECORE_CON_DISCONNECTED;
1746 }
1747
1748 if ((!svr->delete_me) && (!svr->handshaking) && svr->connecting)
1749 {
1750 if (svr->ecs)
1751 {
1752 if (ecore_con_socks_svr_init(svr))
1753 return ECORE_CON_INPROGRESS;
1754 }
1755 else
1756 ecore_con_event_server_add(svr);
1757 }
1758
1759 if (svr->fd_handler && (!svr->buf))
1760 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1761
1762 if (!svr->delete_me)
1763 return ECORE_CON_CONNECTED;
1764 else
1765 return ECORE_CON_DISCONNECTED;
1766}
1767
1768static const char *
1769_ecore_con_pretty_ip(struct sockaddr *client_addr)
1770{
1771#ifndef HAVE_IPV6
1772 char ipbuf[INET_ADDRSTRLEN + 1];
1773#else
1774 char ipbuf[INET6_ADDRSTRLEN + 1];
1775#endif
1776 int family = client_addr->sa_family;
1777 void *src;
1778
1779 switch(family)
1780 {
1781 case AF_INET:
1782 src = &(((struct sockaddr_in *)client_addr)->sin_addr);
1783 break;
1784#ifdef HAVE_IPV6
1785 case AF_INET6:
1786 src = &(((struct sockaddr_in6 *)client_addr)->sin6_addr);
1787
1788 if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src))
1789 {
1790 family = AF_INET;
1791 src = (char*)src + 12;
1792 }
1793 break;
1794#endif
1795 default:
1796 return eina_stringshare_add("0.0.0.0");
1797 }
1798
1799 if (!inet_ntop(family, src, ipbuf, sizeof(ipbuf)))
1800 return eina_stringshare_add("0.0.0.0");
1801
1802 ipbuf[sizeof(ipbuf) - 1] = 0;
1803 return eina_stringshare_add(ipbuf);
1804}
1805
1806static Eina_Bool
1807_ecore_con_svr_tcp_handler(void *data,
1808 Ecore_Fd_Handler *fd_handler __UNUSED__)
1809{
1810 Ecore_Con_Server *svr;
1811 Ecore_Con_Client *cl = NULL;
1812 unsigned char client_addr[256];
1813 unsigned int client_addr_len;
1814 const char *clerr = NULL;
1815
1816 svr = data;
1817 if (svr->delete_me)
1818 return ECORE_CALLBACK_RENEW;
1819
1820 if (svr->delete_me)
1821 return ECORE_CALLBACK_RENEW;
1822
1823 if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) &&
1824 (svr->client_count >= (unsigned int)svr->client_limit))
1825 return ECORE_CALLBACK_RENEW;
1826
1827 /* a new client */
1828
1829 cl = calloc(1, sizeof(Ecore_Con_Client));
1830 if (!cl)
1831 {
1832 ecore_con_event_server_error(svr, "Memory allocation failure when attempting to add a new client");
1833 return ECORE_CALLBACK_RENEW;
1834 }
1835 cl->host_server = svr;
1836
1837 client_addr_len = sizeof(client_addr);
1838 memset(&client_addr, 0, client_addr_len);
1839 cl->fd = accept(svr->fd, (struct sockaddr *)&client_addr, (socklen_t *)&client_addr_len);
1840 if (cl->fd < 0) goto error;
1841 if ((svr->client_limit >= 0) && (svr->reject_excess_clients) &&
1842 (svr->client_count >= (unsigned int)svr->client_limit))
1843 {
1844 clerr = "Maximum client limit reached";
1845 goto error;
1846 }
1847
1848 if (fcntl(cl->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1849 if (fcntl(cl->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1850 cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
1851 _ecore_con_svr_cl_handler, cl, NULL, NULL);
1852 if (!cl->fd_handler) goto error;
1853 ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
1854
1855 if ((!svr->upgrade) && (svr->type & ECORE_CON_SSL))
1856 {
1857 cl->handshaking = EINA_TRUE;
1858 cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
1859 if (ecore_con_ssl_client_init(cl))
1860 goto error;
1861 }
1862
1863 cl->client_addr = malloc(client_addr_len);
1864 if (!cl->client_addr)
1865 {
1866 clerr = "Memory allocation failure when attempting to add a new client";
1867 goto error;
1868 }
1869 cl->client_addr_len = client_addr_len;
1870 memcpy(cl->client_addr, &client_addr, client_addr_len);
1871
1872 svr->clients = eina_list_append(svr->clients, cl);
1873 svr->client_count++;
1874
1875 if ((!cl->delete_me) && (!cl->handshaking))
1876 ecore_con_event_client_add(cl);
1877
1878 return ECORE_CALLBACK_RENEW;
1879
1880error:
1881 if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler);
1882 if (cl->fd >= 0) close(cl->fd);
1883 free(cl);
1884 if (clerr || errno) ecore_con_event_server_error(svr, clerr ?: strerror(errno));
1885 return ECORE_CALLBACK_RENEW;
1886}
1887
1888static void
1889_ecore_con_cl_read(Ecore_Con_Server *svr)
1890{
1891 int num = 0;
1892 Eina_Bool lost_server = EINA_TRUE;
1893 unsigned char buf[READBUFSIZ];
1894
1895 DBG("svr=%p", svr);
1896
1897 /* only possible with non-ssl connections */
1898 if (svr->connecting && (svr_try_connect_plain(svr) != ECORE_CON_CONNECTED))
1899 return;
1900
1901 if (svr->handshaking && (!svr->ecs_state))
1902 {
1903 DBG("Continuing ssl handshake");
1904 if (!ecore_con_ssl_server_init(svr))
1905 lost_server = EINA_FALSE;
1906 _ecore_con_server_timer_update(svr);
1907 }
1908
1909 if (svr->ecs_state || !(svr->type & ECORE_CON_SSL))
1910 {
1911 errno = 0;
1912 num = read(svr->fd, buf, sizeof(buf));
1913 /* 0 is not a valid return value for a tcp socket */
1914 if ((num > 0) || ((num < 0) && (errno == EAGAIN)))
1915 lost_server = EINA_FALSE;
1916 else if (num < 0)
1917 ecore_con_event_server_error(svr, strerror(errno));
1918 }
1919 else
1920 {
1921 num = ecore_con_ssl_server_read(svr, buf, sizeof(buf));
1922 /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */
1923 if (num >= 0)
1924 lost_server = EINA_FALSE;
1925 }
1926
1927 if ((!svr->delete_me) && (num > 0))
1928 {
1929 if (svr->ecs_state)
1930 ecore_con_socks_read(svr, buf, num);
1931 else
1932 ecore_con_event_server_data(svr, buf, num, EINA_TRUE);
1933 }
1934
1935 if (lost_server)
1936 _ecore_con_server_kill(svr);
1937}
1938
1939static Eina_Bool
1940_ecore_con_cl_handler(void *data,
1941 Ecore_Fd_Handler *fd_handler)
1942{
1943 Ecore_Con_Server *svr;
1944 Eina_Bool want_read, want_write;
1945
1946 svr = data;
1947 if (svr->delete_me)
1948 return ECORE_CALLBACK_RENEW;
1949
1950 if (svr->delete_me)
1951 return ECORE_CALLBACK_RENEW;
1952
1953 want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ);
1954 want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE);
1955
1956 if ((!svr->ecs_state) && svr->handshaking && (want_read || want_write))
1957 {
1958 DBG("Continuing ssl handshake: preparing to %s...", want_read ? "read" : "write");
1959#ifdef ISCOMFITOR
1960 if (want_read)
1961 {
1962 char buf[READBUFSIZ];
1963 ssize_t len;
1964 len = recv(svr->fd, buf, sizeof(buf), MSG_DONTWAIT | MSG_PEEK);
1965 DBG("%zu bytes in buffer", len);
1966 }
1967#endif
1968 if (ecore_con_ssl_server_init(svr))
1969 {
1970 ERR("ssl handshaking failed!");
1971 svr->handshaking = EINA_FALSE;
1972 }
1973 else if (!svr->ssl_state)
1974 ecore_con_event_server_add(svr);
1975 return ECORE_CALLBACK_RENEW;
1976 }
1977 if (svr->ecs && svr->ecs_state && (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) && (!svr->ecs_buf))
1978 {
1979 if (svr->ecs_state < ECORE_CON_PROXY_STATE_INIT)
1980 {
1981 INF("PROXY STATE++");
1982 svr->ecs_state++;
1983 }
1984 if (ecore_con_socks_svr_init(svr)) return ECORE_CALLBACK_RENEW;
1985 }
1986 if (want_read)
1987 _ecore_con_cl_read(svr);
1988 else if (want_write) /* only possible with non-ssl connections */
1989 {
1990 if (svr->connecting && (!svr_try_connect_plain(svr)) && (!svr->ecs_state))
1991 return ECORE_CALLBACK_RENEW;
1992
1993 _ecore_con_server_flush(svr);
1994 }
1995
1996 return ECORE_CALLBACK_RENEW;
1997}
1998
1999static Eina_Bool
2000_ecore_con_cl_udp_handler(void *data,
2001 Ecore_Fd_Handler *fd_handler)
2002{
2003 unsigned char buf[READBUFSIZ];
2004 int num;
2005 Ecore_Con_Server *svr;
2006 Eina_Bool want_read, want_write;
2007
2008 want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ);
2009 want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE);
2010
2011 svr = data;
2012 if (svr->delete_me || svr->delete_me || ((!want_read) && (!want_write)))
2013 return ECORE_CALLBACK_RENEW;
2014
2015 if (want_write)
2016 {
2017 _ecore_con_server_flush(svr);
2018 return ECORE_CALLBACK_RENEW;
2019 }
2020
2021 num = read(svr->fd, buf, READBUFSIZ);
2022
2023 if ((!svr->delete_me) && (num > 0))
2024 ecore_con_event_server_data(svr, buf, num, EINA_TRUE);
2025
2026 if (num < 0 && (errno != EAGAIN) && (errno != EINTR))
2027 {
2028 ecore_con_event_server_error(svr, strerror(errno));
2029 _ecore_con_server_kill(svr);
2030 }
2031
2032 return ECORE_CALLBACK_RENEW;
2033}
2034
2035static Eina_Bool
2036_ecore_con_svr_udp_handler(void *data,
2037 Ecore_Fd_Handler *fd_handler)
2038{
2039 unsigned char buf[READBUFSIZ];
2040 unsigned char client_addr[256];
2041 socklen_t client_addr_len = sizeof(client_addr);
2042 int num;
2043 Ecore_Con_Server *svr;
2044 Ecore_Con_Client *cl = NULL;
2045
2046 svr = data;
2047
2048 if (svr->delete_me)
2049 return ECORE_CALLBACK_RENEW;
2050
2051 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
2052 {
2053 _ecore_con_client_flush(cl);
2054 return ECORE_CALLBACK_RENEW;
2055 }
2056
2057 if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
2058 return ECORE_CALLBACK_RENEW;
2059
2060#ifdef _WIN32
2061 num = fcntl(svr->fd, F_SETFL, O_NONBLOCK);
2062 if (num >= 0)
2063 num = recvfrom(svr->fd, (char *)buf, sizeof(buf), 0,
2064 (struct sockaddr *)&client_addr,
2065 &client_addr_len);
2066
2067#else
2068 num = recvfrom(svr->fd, buf, sizeof(buf), MSG_DONTWAIT,
2069 (struct sockaddr *)&client_addr,
2070 &client_addr_len);
2071#endif
2072
2073 if (num < 0 && (errno != EAGAIN) && (errno != EINTR))
2074 {
2075 ecore_con_event_server_error(svr, strerror(errno));
2076 if (!svr->delete_me)
2077 ecore_con_event_client_del(NULL);
2078 _ecore_con_server_kill(svr);
2079 return ECORE_CALLBACK_CANCEL;
2080 }
2081
2082
2083/* Create a new client for use in the client data event */
2084 cl = calloc(1, sizeof(Ecore_Con_Client));
2085 EINA_SAFETY_ON_NULL_RETURN_VAL(cl, ECORE_CALLBACK_RENEW);
2086
2087 cl->host_server = svr;
2088 cl->client_addr = malloc(client_addr_len);
2089 if (!cl->client_addr)
2090 {
2091 free(cl);
2092 return ECORE_CALLBACK_RENEW;
2093 }
2094 cl->client_addr_len = client_addr_len;
2095
2096 memcpy(cl->client_addr, &client_addr, client_addr_len);
2097 ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
2098 svr->clients = eina_list_append(svr->clients, cl);
2099 svr->client_count++;
2100
2101 ecore_con_event_client_add(cl);
2102 ecore_con_event_client_data(cl, buf, num, EINA_TRUE);
2103
2104 return ECORE_CALLBACK_RENEW;
2105}
2106
2107static void
2108_ecore_con_svr_cl_read(Ecore_Con_Client *cl)
2109{
2110 int num = 0;
2111 Eina_Bool lost_client = EINA_TRUE;
2112 unsigned char buf[READBUFSIZ];
2113
2114 DBG("cl=%p", cl);
2115
2116 if (cl->handshaking)
2117 {
2118 /* add an extra handshake attempt just before read, even though
2119 * read also attempts to handshake, to try to finish sooner
2120 */
2121 if (ecore_con_ssl_client_init(cl))
2122 lost_client = EINA_FALSE;
2123
2124 _ecore_con_cl_timer_update(cl);
2125 }
2126
2127 if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade))
2128 {
2129 num = read(cl->fd, buf, sizeof(buf));
2130 /* 0 is not a valid return value for a tcp socket */
2131 if ((num > 0) || ((num < 0) && ((errno == EAGAIN) || (errno == EINTR))))
2132 lost_client = EINA_FALSE;
2133 else if (num < 0)
2134 ecore_con_event_client_error(cl, strerror(errno));
2135 }
2136 else
2137 {
2138 num = ecore_con_ssl_client_read(cl, buf, sizeof(buf));
2139 /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */
2140 if (num >= 0)
2141 lost_client = EINA_FALSE;
2142 }
2143
2144 if ((!cl->delete_me) && (num > 0))
2145 ecore_con_event_client_data(cl, buf, num, EINA_TRUE);
2146
2147 if (lost_client) _ecore_con_client_kill(cl);
2148}
2149
2150static Eina_Bool
2151_ecore_con_svr_cl_handler(void *data,
2152 Ecore_Fd_Handler *fd_handler)
2153{
2154 Ecore_Con_Client *cl;
2155
2156 cl = data;
2157 if (cl->delete_me)
2158 return ECORE_CALLBACK_RENEW;
2159
2160 if (cl->handshaking && ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ | ECORE_FD_WRITE))
2161 {
2162 if (ecore_con_ssl_client_init(cl))
2163 {
2164 ERR("ssl handshaking failed!");
2165 _ecore_con_client_kill(cl);
2166 return ECORE_CALLBACK_RENEW;
2167 }
2168 else if (!cl->ssl_state)
2169 ecore_con_event_client_add(cl);
2170 }
2171 else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
2172 _ecore_con_svr_cl_read(cl);
2173
2174 else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
2175 _ecore_con_client_flush(cl);
2176
2177 return ECORE_CALLBACK_RENEW;
2178}
2179
2180static void
2181_ecore_con_server_flush(Ecore_Con_Server *svr)
2182{
2183 int count, num;
2184 size_t buf_len, buf_offset;
2185 const void *buf;
2186
2187 DBG("(svr=%p,buf=%p)", svr, svr->buf);
2188#ifdef _WIN32
2189 if (ecore_con_local_win32_server_flush(svr))
2190 return;
2191#endif
2192
2193 if ((!svr->buf) && (!svr->ecs_buf) && svr->fd_handler)
2194 {
2195 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
2196 return;
2197 }
2198
2199 buf = svr->buf ? eina_binbuf_string_get(svr->buf) : eina_binbuf_string_get(svr->ecs_buf);
2200 buf_len = svr->buf ? eina_binbuf_length_get(svr->buf) : eina_binbuf_length_get(svr->ecs_buf);
2201 buf_offset = svr->buf ? svr->write_buf_offset : svr->ecs_buf_offset;
2202 num = buf_len - buf_offset;
2203
2204 /* check whether we need to write anything at all.
2205 * we must not write zero bytes with SSL_write() since it
2206 * causes undefined behaviour
2207 */
2208 /* we thank Tommy[D] for needing to check negative buffer sizes
2209 * here because his system is amazing.
2210 */
2211 if (num <= 0) return;
2212
2213 if ((!svr->ecs_state) && svr->handshaking)
2214 {
2215 DBG("Continuing ssl handshake");
2216 if (ecore_con_ssl_server_init(svr))
2217 _ecore_con_server_kill(svr);
2218 _ecore_con_server_timer_update(svr);
2219 return;
2220 }
2221
2222 if (svr->ecs_state || (!(svr->type & ECORE_CON_SSL)))
2223 count = write(svr->fd, buf + buf_offset, num);
2224 else
2225 count = ecore_con_ssl_server_write(svr, buf + buf_offset, num);
2226
2227 if (count < 0)
2228 {
2229 if ((errno != EAGAIN) && (errno != EINTR))
2230 {
2231 ecore_con_event_server_error(svr, strerror(errno));
2232 _ecore_con_server_kill(svr);
2233 }
2234 return;
2235 }
2236
2237 if (count && (!svr->ecs_state)) ecore_con_event_server_write(svr, count);
2238 if (svr->ecs_buf)
2239 buf_offset = svr->ecs_buf_offset += count;
2240 else
2241 buf_offset = svr->write_buf_offset += count;
2242 if (buf_offset >= buf_len)
2243 {
2244 if (svr->ecs_buf)
2245 {
2246 svr->ecs_buf_offset = 0;
2247 eina_binbuf_free(svr->ecs_buf);
2248 svr->ecs_buf = NULL;
2249 INF("PROXY STATE++");
2250 svr->ecs_state++;
2251 }
2252 else
2253 {
2254 svr->write_buf_offset = 0;
2255 eina_binbuf_free(svr->buf);
2256 svr->buf = NULL;
2257#ifdef TCP_CORK
2258 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)
2259 {
2260 int state = 0;
2261 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
2262 /* realistically this isn't anything serious so we can just log and continue */
2263 ERR("uncorking failed! %s", strerror(errno));
2264 }
2265#endif
2266 }
2267 if (svr->fd_handler)
2268 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
2269 }
2270 else if ((count < num) && svr->fd_handler)
2271 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
2272}
2273
2274static void
2275_ecore_con_client_flush(Ecore_Con_Client *cl)
2276{
2277 int num = 0, count = 0;
2278
2279#ifdef _WIN32
2280 if (ecore_con_local_win32_client_flush(cl))
2281 return;
2282#endif
2283
2284 if (!cl->buf && cl->fd_handler)
2285 {
2286 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
2287 return;
2288 }
2289
2290 if (cl->handshaking)
2291 {
2292 if (ecore_con_ssl_client_init(cl))
2293 count = -1;
2294
2295 _ecore_con_cl_timer_update(cl);
2296 }
2297
2298 if (!count)
2299 {
2300 num = eina_binbuf_length_get(cl->buf) - cl->buf_offset;
2301 if (num <= 0) return;
2302 if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade))
2303 count = write(cl->fd, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num);
2304 else
2305 count = ecore_con_ssl_client_write(cl, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num);
2306 }
2307
2308 if (count < 0)
2309 {
2310 if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me))
2311 {
2312 ecore_con_event_client_error(cl, strerror(errno));
2313 _ecore_con_client_kill(cl);
2314 }
2315
2316 return;
2317 }
2318
2319 if (count) ecore_con_event_client_write(cl, count);
2320 cl->buf_offset += count, num -= count;
2321 if (cl->buf_offset >= eina_binbuf_length_get(cl->buf))
2322 {
2323 cl->buf_offset = 0;
2324 eina_binbuf_free(cl->buf);
2325 cl->buf = NULL;
2326#ifdef TCP_CORK
2327 if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)
2328 {
2329 int state = 0;
2330 if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
2331 /* realistically this isn't anything serious so we can just log and continue */
2332 ERR("uncorking failed! %s", strerror(errno));
2333 }
2334#endif
2335 if (cl->fd_handler)
2336 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
2337 }
2338 else if (cl->fd_handler && (num >= 0))
2339 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
2340}
2341
2342static void
2343_ecore_con_event_client_add_free(Ecore_Con_Server *svr,
2344 void *ev)
2345{
2346 Ecore_Con_Event_Client_Add *e;
2347
2348 e = ev;
2349 if (e->client)
2350 {
2351 e->client->event_count = eina_list_remove(e->client->event_count, e);
2352 if (e->client->host_server)
2353 {
2354 e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev);
2355 if ((!svr->event_count) && (svr->delete_me))
2356 _ecore_con_server_free(svr);
2357 }
2358 if ((!e->client->event_count) && (e->client->delete_me))
2359 ecore_con_client_del(e->client);
2360 }
2361
2362 ecore_con_event_client_add_free(e);
2363 _ecore_con_event_count--;
2364 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2365 ecore_con_mempool_shutdown();
2366}
2367
2368static void
2369_ecore_con_event_client_del_free(Ecore_Con_Server *svr,
2370 void *ev)
2371{
2372 Ecore_Con_Event_Client_Del *e;
2373
2374 e = ev;
2375 if (e->client)
2376 {
2377 e->client->event_count = eina_list_remove(e->client->event_count, e);
2378 if (e->client->host_server)
2379 {
2380 e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev);
2381 if ((!svr->event_count) && (svr->delete_me))
2382 _ecore_con_server_free(svr);
2383 }
2384 if (!e->client->event_count)
2385 ecore_con_client_del(e->client);
2386 }
2387 ecore_con_event_client_del_free(e);
2388 _ecore_con_event_count--;
2389 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2390 ecore_con_mempool_shutdown();
2391}
2392
2393static void
2394_ecore_con_event_client_write_free(Ecore_Con_Server *svr,
2395 Ecore_Con_Event_Client_Write *e)
2396{
2397 if (e->client)
2398 {
2399 e->client->event_count = eina_list_remove(e->client->event_count, e);
2400 if (e->client->host_server)
2401 {
2402 e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e);
2403 if ((!svr->event_count) && (svr->delete_me))
2404 _ecore_con_server_free(svr);
2405 }
2406 if (((!e->client->event_count) && (e->client->delete_me)) ||
2407 ((e->client->host_server &&
2408 ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
2409 (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
2410 ecore_con_client_del(e->client);
2411 }
2412 ecore_con_event_client_write_free(e);
2413 _ecore_con_event_count--;
2414 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2415 ecore_con_mempool_shutdown();
2416}
2417
2418static void
2419_ecore_con_event_client_data_free(Ecore_Con_Server *svr,
2420 void *ev)
2421{
2422 Ecore_Con_Event_Client_Data *e;
2423
2424 e = ev;
2425 if (e->client)
2426 {
2427 e->client->event_count = eina_list_remove(e->client->event_count, e);
2428 if (e->client->host_server)
2429 {
2430 e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev);
2431 }
2432 if ((!svr->event_count) && (svr->delete_me))
2433 _ecore_con_server_free(svr);
2434 if (((!e->client->event_count) && (e->client->delete_me)) ||
2435 ((e->client->host_server &&
2436 ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
2437 (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
2438 ecore_con_client_del(e->client);
2439 }
2440 free(e->data);
2441 ecore_con_event_client_data_free(e);
2442 _ecore_con_event_count--;
2443 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2444 ecore_con_mempool_shutdown();
2445}
2446
2447static void
2448_ecore_con_event_server_add_free(void *data __UNUSED__,
2449 void *ev)
2450{
2451 Ecore_Con_Event_Server_Add *e;
2452
2453 e = ev;
2454 if (e->server)
2455 {
2456 e->server->event_count = eina_list_remove(e->server->event_count, ev);
2457 if ((!e->server->event_count) && (e->server->delete_me))
2458 _ecore_con_server_free(e->server);
2459 }
2460 ecore_con_event_server_add_free(e);
2461 _ecore_con_event_count--;
2462 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2463 ecore_con_mempool_shutdown();
2464}
2465
2466static void
2467_ecore_con_event_server_del_free(void *data __UNUSED__,
2468 void *ev)
2469{
2470 Ecore_Con_Event_Server_Del *e;
2471
2472 e = ev;
2473 if (e->server)
2474 {
2475 e->server->event_count = eina_list_remove(e->server->event_count, ev);
2476 if (!e->server->event_count)
2477 _ecore_con_server_free(e->server);
2478 }
2479 ecore_con_event_server_del_free(e);
2480 _ecore_con_event_count--;
2481 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2482 ecore_con_mempool_shutdown();
2483}
2484
2485static void
2486_ecore_con_event_server_write_free(void *data __UNUSED__,
2487 Ecore_Con_Event_Server_Write *e)
2488{
2489 if (e->server)
2490 {
2491 e->server->event_count = eina_list_remove(e->server->event_count, e);
2492 if ((!e->server->event_count) && (e->server->delete_me))
2493 _ecore_con_server_free(e->server);
2494 }
2495
2496 ecore_con_event_server_write_free(e);
2497 _ecore_con_event_count--;
2498 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2499 ecore_con_mempool_shutdown();
2500}
2501
2502static void
2503_ecore_con_event_server_data_free(void *data __UNUSED__,
2504 void *ev)
2505{
2506 Ecore_Con_Event_Server_Data *e;
2507
2508 e = ev;
2509 if (e->server)
2510 {
2511 e->server->event_count = eina_list_remove(e->server->event_count, ev);
2512 if ((!e->server->event_count) && (e->server->delete_me))
2513 _ecore_con_server_free(e->server);
2514 }
2515
2516 free(e->data);
2517 ecore_con_event_server_data_free(e);
2518 _ecore_con_event_count--;
2519 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2520 ecore_con_mempool_shutdown();
2521}
2522
2523
2524static void
2525_ecore_con_event_server_error_free(void *data __UNUSED__, Ecore_Con_Event_Server_Error *e)
2526{
2527 if (e->server)
2528 {
2529 e->server->event_count = eina_list_remove(e->server->event_count, e);
2530 if ((!e->server->event_count) && (e->server->delete_me))
2531 _ecore_con_server_free(e->server);
2532 }
2533 free(e->error);
2534 ecore_con_event_server_error_free(e);
2535 _ecore_con_event_count--;
2536 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2537 ecore_con_mempool_shutdown();
2538}
2539
2540static void
2541_ecore_con_event_client_error_free(Ecore_Con_Server *svr, Ecore_Con_Event_Client_Error *e)
2542{
2543 if (e->client)
2544 {
2545 e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e);
2546 if ((!e->client->event_count) && (e->client->delete_me))
2547 _ecore_con_client_free(e->client);
2548 if (e->client->host_server)
2549 {
2550 e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e);
2551 if ((!svr->event_count) && (svr->delete_me))
2552 _ecore_con_server_free(svr);
2553 }
2554 }
2555 free(e->error);
2556 ecore_con_event_client_error_free(e);
2557 _ecore_con_event_count--;
2558 if ((!_ecore_con_event_count) && (!_ecore_con_init_count))
2559 ecore_con_mempool_shutdown();
2560}
2561
2562static void
2563_ecore_con_lookup_done(void *data,
2564 Ecore_Con_Info *infos)
2565{
2566 Ecore_Con_Server *svr;
2567 Ecore_Con_Lookup *lk;
2568
2569 svr = data;
2570 lk = svr->data;
2571
2572 if (infos)
2573 lk->done_cb(infos->info.ai_canonname, infos->ip,
2574 infos->info.ai_addr, infos->info.ai_addrlen,
2575 (void *)lk->data);
2576 else
2577 lk->done_cb(NULL, NULL, NULL, 0, (void *)lk->data);
2578
2579 free(svr->name);
2580 free(lk);
2581 free(svr);
2582}
2583
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c b/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c
deleted file mode 100644
index d922f20..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c
+++ /dev/null
@@ -1,101 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include "Ecore.h"
6#include "ecore_private.h"
7#include "Ecore_Con.h"
8#include "ecore_con_private.h"
9
10typedef struct _Ecore_Con_Mempool Ecore_Con_Mempool;
11struct _Ecore_Con_Mempool
12{
13 const char *name;
14 Eina_Mempool *mp;
15 size_t size;
16};
17
18#define GENERIC_ALLOC_FREE(TYPE, Type) \
19 Ecore_Con_Mempool Type##_mp = { #TYPE, NULL, sizeof (TYPE) }; \
20 \
21 TYPE * \
22 Type##_alloc(void) \
23 { \
24 return eina_mempool_malloc(Type##_mp.mp, sizeof (TYPE)); \
25 } \
26 \
27 void \
28 Type##_free(TYPE *e) \
29 { \
30 eina_mempool_free(Type##_mp.mp, e); \
31 }
32
33GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Add, ecore_con_event_client_add);
34GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Del, ecore_con_event_client_del);
35GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Write, ecore_con_event_client_write);
36GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Data, ecore_con_event_client_data);
37GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Error, ecore_con_event_server_error);
38GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Error, ecore_con_event_client_error);
39GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Add, ecore_con_event_server_add);
40GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del);
41GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write);
42GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Data, ecore_con_event_server_data);
43GENERIC_ALLOC_FREE(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind);
44
45static Ecore_Con_Mempool *mempool_array[] = {
46 &ecore_con_event_client_add_mp,
47 &ecore_con_event_client_del_mp,
48 &ecore_con_event_client_write_mp,
49 &ecore_con_event_client_data_mp,
50 &ecore_con_event_server_error_mp,
51 &ecore_con_event_client_error_mp,
52 &ecore_con_event_server_add_mp,
53 &ecore_con_event_server_del_mp,
54 &ecore_con_event_server_write_mp,
55 &ecore_con_event_server_data_mp,
56 &ecore_con_event_proxy_bind_mp
57};
58
59void
60ecore_con_mempool_init(void)
61{
62 const char *choice;
63 unsigned int i;
64
65 choice = getenv("EINA_MEMPOOL");
66 if (!choice || !choice[0])
67 choice = "chained_mempool";
68
69 for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i)
70 {
71 retry:
72 mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 64);
73 if (!mempool_array[i]->mp)
74 {
75 if (strcmp(choice, "pass_through") != 0)
76 {
77 ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice);
78 choice = "pass_through";
79 goto retry;
80 }
81 else
82 {
83 ERR("Impossible to allocate mempool '%s' !", choice);
84 return ;
85 }
86 }
87 }
88}
89
90void
91ecore_con_mempool_shutdown(void)
92{
93 unsigned int i;
94
95 for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i)
96 {
97 eina_mempool_del(mempool_array[i]->mp);
98 mempool_array[i]->mp = NULL;
99 }
100}
101
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c b/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c
deleted file mode 100644
index 5dfe70b..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c
+++ /dev/null
@@ -1,628 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5/*
6 * This version of ecore_con_info use c-ares to provide asynchronous dns lookup.
7 *
8 * Note: It doesn't fork nor does it use libc getaddrinfo.
9 * http://c-ares.haxx.se/docs.html
10 */
11
12#include <string.h>
13#include <sys/types.h>
14
15#ifdef HAVE_NETINET_IN_H
16# include <netinet/in.h>
17#endif
18
19#ifdef HAVE_ARPA_INET_H
20# include <arpa/inet.h>
21#endif
22
23#include <ares.h>
24
25#include "Ecore.h"
26#include "Ecore_Con.h"
27#include "ecore_con_private.h"
28
29typedef struct _Ecore_Con_FD Ecore_Con_FD;
30typedef struct _Ecore_Con_CAres Ecore_Con_CAres;
31
32struct _Ecore_Con_FD
33{
34 Ecore_Fd_Handler *handler;
35 Ecore_Timer *timer;
36 int fd;
37};
38
39struct _Ecore_Con_CAres
40{
41 Ecore_Con_Server *svr;
42 Ecore_Con_Info_Cb done_cb;
43 void *data;
44 struct addrinfo hints;
45 Ecore_Con_Info *result;
46
47 union {
48 struct in_addr v4;
49#ifdef HAVE_IPV6
50 struct in6_addr v6;
51#endif
52 } addr;
53
54 Eina_Bool byaddr : 1;
55 Eina_Bool isv6 : 1;
56};
57
58static ares_channel info_channel;
59static int info_init = 0;
60static Eina_List *info_fds = NULL;
61
62static void _ecore_con_info_ares_nameinfo(Ecore_Con_CAres *arg,
63 int status,
64 int timeouts,
65 char *node,
66 char *service);
67static void _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg,
68 int status,
69 int timeouts,
70 struct hostent *hostent);
71static Eina_Bool _ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf,
72 Ecore_Fd_Handler *fd_handler);
73static Eina_Bool _ecore_con_info_cares_timeout_cb(void *data);
74
75static void
76_ecore_con_info_cares_state_cb(void *data,
77 ares_socket_t fd,
78 int readable,
79 int writable);
80static int
81_ecore_con_info_fds_search(const Ecore_Con_FD *fd1,
82 const Ecore_Con_FD *fd2);
83
84int
85ecore_con_info_init(void)
86{
87 struct ares_options opts;
88
89 if (!info_init)
90 {
91 if (ares_library_init(ARES_LIB_INIT_ALL))
92 return 0;
93
94 opts.lookups = "fb"; /* hosts file then dns */
95 opts.sock_state_cb = _ecore_con_info_cares_state_cb;
96
97 if (ares_init_options(&info_channel, &opts,
98 ARES_OPT_LOOKUPS | ARES_OPT_SOCK_STATE_CB) != ARES_SUCCESS)
99 {
100 ares_library_cleanup();
101 return 0;
102 }
103 }
104
105 info_init++;
106 return info_init;
107}
108
109int
110ecore_con_info_shutdown(void)
111{
112 info_init--;
113 if (info_init == 0)
114 {
115 /* Cancel all ongoing request */
116 ares_cancel(info_channel);
117 ares_destroy(info_channel);
118
119 /* Shutdown ares */
120 ares_library_cleanup();
121 }
122
123 return info_init;
124}
125
126int
127ecore_con_info_tcp_connect(Ecore_Con_Server *svr,
128 Ecore_Con_Info_Cb done_cb,
129 void *data)
130{
131 struct addrinfo hints;
132
133 memset(&hints, 0, sizeof(struct addrinfo));
134#ifdef HAVE_IPV6
135 hints.ai_family = AF_INET6;
136#else
137 hints.ai_family = AF_INET;
138#endif
139 hints.ai_socktype = SOCK_STREAM;
140 hints.ai_flags = AI_CANONNAME;
141 hints.ai_protocol = IPPROTO_TCP;
142 hints.ai_canonname = NULL;
143 hints.ai_next = NULL;
144 hints.ai_addr = NULL;
145
146 return ecore_con_info_get(svr, done_cb, data, &hints);
147}
148
149int
150ecore_con_info_tcp_listen(Ecore_Con_Server *svr,
151 Ecore_Con_Info_Cb done_cb,
152 void *data)
153{
154 struct addrinfo hints;
155
156 memset(&hints, 0, sizeof(struct addrinfo));
157#ifdef HAVE_IPV6
158 hints.ai_family = AF_INET6;
159#else
160 hints.ai_family = AF_INET;
161#endif
162 hints.ai_socktype = SOCK_STREAM;
163 hints.ai_flags = AI_PASSIVE;
164 hints.ai_protocol = IPPROTO_TCP;
165 hints.ai_canonname = NULL;
166 hints.ai_next = NULL;
167 hints.ai_addr = NULL;
168
169 return ecore_con_info_get(svr, done_cb, data, &hints);
170}
171
172int
173ecore_con_info_udp_connect(Ecore_Con_Server *svr,
174 Ecore_Con_Info_Cb done_cb,
175 void *data)
176{
177 struct addrinfo hints;
178
179 memset(&hints, 0, sizeof(struct addrinfo));
180#ifdef HAVE_IPV6
181 hints.ai_family = AF_INET6;
182#else
183 hints.ai_family = AF_INET;
184#endif
185 hints.ai_socktype = SOCK_DGRAM;
186 hints.ai_flags = AI_CANONNAME;
187 hints.ai_protocol = IPPROTO_UDP;
188 hints.ai_canonname = NULL;
189 hints.ai_next = NULL;
190 hints.ai_addr = NULL;
191
192 return ecore_con_info_get(svr, done_cb, data, &hints);
193}
194
195int
196ecore_con_info_udp_listen(Ecore_Con_Server *svr,
197 Ecore_Con_Info_Cb done_cb,
198 void *data)
199{
200 struct addrinfo hints;
201
202 memset(&hints, 0, sizeof(struct addrinfo));
203#ifdef HAVE_IPV6
204 hints.ai_family = AF_INET6;
205#else
206 hints.ai_family = AF_INET;
207#endif
208 hints.ai_socktype = SOCK_DGRAM;
209 hints.ai_flags = AI_PASSIVE;
210 hints.ai_protocol = IPPROTO_UDP;
211 hints.ai_canonname = NULL;
212 hints.ai_next = NULL;
213 hints.ai_addr = NULL;
214
215 return ecore_con_info_get(svr, done_cb, data, &hints);
216}
217
218int
219ecore_con_info_mcast_listen(Ecore_Con_Server *svr,
220 Ecore_Con_Info_Cb done_cb,
221 void *data)
222{
223 struct addrinfo hints;
224
225 memset(&hints, 0, sizeof(struct addrinfo));
226#ifdef HAVE_IPV6
227 hints.ai_family = AF_INET6;
228#else
229 hints.ai_family = AF_INET;
230#endif
231 hints.ai_socktype = SOCK_DGRAM;
232 hints.ai_flags = 0;
233 hints.ai_protocol = IPPROTO_UDP;
234 hints.ai_canonname = NULL;
235 hints.ai_next = NULL;
236 hints.ai_addr = NULL;
237
238 return ecore_con_info_get(svr, done_cb, data, &hints);
239}
240
241static Eina_Bool
242_ecore_con_info_ares_getnameinfo(Ecore_Con_CAres *arg,
243 int addrtype,
244 const char *name,
245 struct sockaddr *addr,
246 int addrlen)
247{
248 int length = 0;
249
250 if (name)
251 length = strlen(name) + 1;
252 else
253 length = 1;
254
255 arg->result = malloc(sizeof(Ecore_Con_Info) + length);
256 if (!arg->result)
257 return EINA_FALSE;
258
259 /* FIXME: What to do when hint is not set ? */
260 arg->result->info.ai_flags = arg->hints.ai_flags;
261 arg->result->info.ai_socktype = arg->hints.ai_socktype;
262 arg->result->info.ai_protocol = arg->hints.ai_protocol;
263
264 arg->result->info.ai_family = addrtype;
265 arg->result->info.ai_addrlen = addrlen;
266 arg->result->info.ai_addr = addr;
267 arg->result->info.ai_canonname = (char *)(arg->result + 1);
268
269 if (!name)
270 *arg->result->info.ai_canonname = '\0';
271 else
272 strcpy(arg->result->info.ai_canonname, name);
273
274 arg->result->info.ai_next = NULL;
275
276 ares_getnameinfo(
277 info_channel, addr, addrlen,
278 ARES_NI_NUMERICSERV | ARES_NI_NUMERICHOST |
279 ARES_NI_LOOKUPSERVICE | ARES_NI_LOOKUPHOST,
280 (ares_nameinfo_callback)_ecore_con_info_ares_nameinfo, arg);
281
282 return EINA_TRUE;
283}
284
285EAPI int
286ecore_con_info_get(Ecore_Con_Server *svr,
287 Ecore_Con_Info_Cb done_cb,
288 void *data,
289 struct addrinfo *hints)
290{
291 Ecore_Con_CAres *cares;
292#ifdef HAVE_IPV6
293 int ai_family = AF_INET6;
294#else
295 int ai_family = AF_INET;
296#endif
297
298 cares = calloc(1, sizeof(Ecore_Con_CAres));
299 if (!cares)
300 return 0;
301
302 cares->svr = svr;
303 cares->done_cb = done_cb;
304 cares->data = data;
305
306 if (hints)
307 {
308 ai_family = hints->ai_family;
309 memcpy(&cares->hints, hints, sizeof(struct addrinfo));
310 }
311
312 if (inet_pton(AF_INET, svr->ecs ? svr->ecs->ip : svr->name, &cares->addr.v4) == 1)
313 {
314 cares->byaddr = EINA_TRUE;
315 cares->isv6 = EINA_FALSE;
316 ares_gethostbyaddr(info_channel, &cares->addr.v4,
317 sizeof(cares->addr.v4),
318 AF_INET,
319 (ares_host_callback)_ecore_con_info_ares_host_cb,
320 cares);
321 }
322#ifdef HAVE_IPV6
323 else if (inet_pton(AF_INET6, svr->ecs ? svr->ecs->ip : svr->name, &cares->addr.v6) == 1)
324 {
325 cares->byaddr = EINA_TRUE;
326 cares->isv6 = EINA_TRUE;
327 ares_gethostbyaddr(info_channel, &cares->addr.v6,
328 sizeof(cares->addr.v6),
329 AF_INET6,
330 (ares_host_callback)_ecore_con_info_ares_host_cb,
331 cares);
332 }
333#endif
334 else
335 {
336 cares->byaddr = EINA_FALSE;
337 ares_gethostbyname(info_channel, svr->ecs ? svr->ecs->ip : svr->name, ai_family,
338 (ares_host_callback)_ecore_con_info_ares_host_cb,
339 cares);
340 }
341
342 svr->infos = eina_list_append(svr->infos, cares);
343 return 1;
344}
345
346void
347ecore_con_info_data_clear(void *info)
348{
349 Ecore_Con_CAres *cares = info;
350 if (cares) cares->data = NULL;
351}
352
353static Eina_Bool
354_ecore_con_info_cares_timeout_cb(void *data __UNUSED__)
355{
356 ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
357 return ECORE_CALLBACK_RENEW;
358}
359
360static Eina_Bool
361_ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf,
362 Ecore_Fd_Handler *fd_handler)
363{
364 ares_socket_t read_fd, write_fd;
365
366 read_fd = write_fd = ARES_SOCKET_BAD;
367
368 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
369 read_fd = ecf->fd;
370 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
371 write_fd = ecf->fd;
372
373 ares_process_fd(info_channel, read_fd, write_fd);
374
375 return ECORE_CALLBACK_RENEW;
376}
377
378static int
379_ecore_con_info_fds_search(const Ecore_Con_FD *fd1,
380 const Ecore_Con_FD *fd2)
381{
382 return fd1->fd - fd2->fd;
383}
384
385static void
386_ecore_con_info_cares_state_cb(void *data __UNUSED__,
387 ares_socket_t fd,
388 int readable,
389 int writable)
390{
391 int flags = 0;
392 Ecore_Con_FD *search = NULL, *ecf = NULL;
393
394 search = eina_list_search_unsorted(info_fds,
395 (Eina_Compare_Cb)_ecore_con_info_fds_search, &ecf);
396
397 if (!(readable | writable))
398 {
399 ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
400 if (search)
401 {
402 info_fds = eina_list_remove(info_fds, search);
403 ecore_timer_del(search->timer);
404 ecore_main_fd_handler_del(search->handler);
405 free(search);
406 }
407 return;
408 }
409
410 if (!search)
411 {
412 search = malloc(sizeof(Ecore_Con_FD));
413 EINA_SAFETY_ON_NULL_RETURN(search);
414
415 search->fd = fd;
416 search->handler = ecore_main_fd_handler_add(fd, ECORE_FD_WRITE | ECORE_FD_READ,
417 (Ecore_Fd_Cb)_ecore_con_info_cares_fd_cb, search, NULL, NULL);
418 /* c-ares default timeout is 5 seconds */
419 search->timer = ecore_timer_add(5, _ecore_con_info_cares_timeout_cb, NULL);
420 info_fds = eina_list_append(info_fds, search);
421 }
422
423 if (readable) flags |= ECORE_FD_READ;
424 if (writable) flags |= ECORE_FD_WRITE;
425 ecore_main_fd_handler_active_set(search->handler, flags);
426}
427
428static void
429_ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg,
430 int status,
431 int timeouts __UNUSED__,
432 struct hostent *hostent)
433{
434 struct sockaddr *addr;
435 int addrlen;
436
437 /* Found something ? */
438 switch (status)
439 {
440 case ARES_SUCCESS:
441 if (!hostent->h_addr_list[0])
442 {
443 ERR("No IP found");
444 goto on_error;
445 }
446
447 switch (hostent->h_addrtype)
448 {
449 case AF_INET:
450 {
451 struct sockaddr_in *addri;
452
453 addrlen = sizeof(struct sockaddr_in);
454 addri = malloc(addrlen);
455
456 if (!addri)
457 goto on_mem_error;
458
459 addri->sin_family = AF_INET;
460 addri->sin_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port);
461
462 memcpy(&addri->sin_addr.s_addr,
463 hostent->h_addr_list[0], sizeof(struct in_addr));
464
465 addr = (struct sockaddr *)addri;
466 break;
467 }
468#ifdef HAVE_IPV6
469 case AF_INET6:
470 {
471 struct sockaddr_in6 *addri6;
472
473 addrlen = sizeof(struct sockaddr_in6);
474 addri6 = malloc(addrlen);
475
476 if (!addri6)
477 goto on_mem_error;
478
479 addri6->sin6_family = AF_INET6;
480 addri6->sin6_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port);
481 addri6->sin6_flowinfo = 0;
482 addri6->sin6_scope_id = 0;
483
484 memcpy(&addri6->sin6_addr.s6_addr,
485 hostent->h_addr_list[0], sizeof(struct in6_addr));
486
487 addr = (struct sockaddr *)addri6;
488 break;
489 }
490#endif
491 default:
492 ERR("Unknown addrtype %i", hostent->h_addrtype);
493 goto on_error;
494 }
495
496 if (!_ecore_con_info_ares_getnameinfo(arg, hostent->h_addrtype,
497 hostent->h_name,
498 addr, addrlen))
499 goto on_error;
500
501 break;
502
503 case ARES_ENOTFOUND: /* address notfound */
504 if (arg->byaddr)
505 {
506#ifdef HAVE_IPV6
507 /* This happen when host doesn't have a reverse. */
508 if (arg->isv6)
509 {
510 struct sockaddr_in6 *addri6;
511
512 addrlen = sizeof(struct sockaddr_in6);
513 addri6 = malloc(addrlen);
514
515 if (!addri6)
516 goto on_mem_error;
517
518 addri6->sin6_family = AF_INET6;
519 addri6->sin6_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port);
520 addri6->sin6_flowinfo = 0;
521 addri6->sin6_scope_id = 0;
522
523 memcpy(&addri6->sin6_addr.s6_addr,
524 &arg->addr.v6, sizeof(struct in6_addr));
525
526 addr = (struct sockaddr *)addri6;
527 }
528 else
529#endif
530 {
531 struct sockaddr_in *addri;
532
533 addrlen = sizeof(struct sockaddr_in);
534 addri = malloc(addrlen);
535
536 if (!addri)
537 goto on_mem_error;
538
539 addri->sin_family = AF_INET;
540 addri->sin_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port);
541
542 memcpy(&addri->sin_addr.s_addr,
543 &arg->addr.v4, sizeof(struct in_addr));
544
545 addr = (struct sockaddr *)addri;
546 }
547
548 if (!_ecore_con_info_ares_getnameinfo(arg,
549#ifdef HAVE_IPV6
550 arg->isv6 ? AF_INET6 :
551#endif
552 AF_INET,
553 NULL, addr,
554 addrlen))
555 goto on_error;
556
557 break;
558 }
559
560 case ARES_ENOTIMP: /* unknown family */
561 case ARES_EBADNAME: /* not a valid internet address */
562 case ARES_ENOMEM: /* not enough memory */
563 case ARES_EDESTRUCTION: /* request canceled, shuting down */
564 case ARES_ENODATA: /* no data returned */
565 case ARES_ECONNREFUSED: /* connection refused */
566 case ARES_ETIMEOUT: /* connection timed out */
567 ecore_con_event_server_error(arg->svr, ares_strerror(status));
568 goto on_error;
569
570 default:
571 ERR("Unknown status returned by c-ares: %i assuming error", status);
572 ecore_con_event_server_error(arg->svr, ares_strerror(status));
573 goto on_error;
574 }
575
576 return;
577
578on_mem_error:
579 ERR("Not enough memory");
580
581on_error:
582 if (arg->data)
583 {
584 ecore_con_server_infos_del(arg->data, arg);
585 arg->done_cb(arg->data, NULL);
586 }
587 free(arg);
588}
589
590static void
591_ecore_con_info_ares_nameinfo(Ecore_Con_CAres *arg,
592 int status,
593 int timeouts __UNUSED__,
594 char *node,
595 char *service)
596{
597 switch (status)
598 {
599 case ARES_SUCCESS:
600 if (node)
601 strcpy(arg->result->ip, node);
602 else
603 *arg->result->ip = '\0';
604
605 if (service)
606 strcpy(arg->result->service, service);
607 else
608 *arg->result->service = '\0';
609
610 if (arg->data) arg->done_cb(arg->data, arg->result);
611 break;
612
613 case ARES_ENOTIMP:
614 case ARES_ENOTFOUND:
615 case ARES_ENOMEM:
616 case ARES_EDESTRUCTION:
617 case ARES_EBADFLAGS:
618 ecore_con_event_server_error(arg->svr, ares_strerror(status));
619 if (arg->data) arg->done_cb(arg->data, NULL);
620 break;
621 }
622
623 free(arg->result->info.ai_addr);
624 free(arg->result);
625 if (arg->data) ecore_con_server_infos_del(arg->data, arg);
626 free(arg);
627}
628
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_info.c b/libraries/ecore/src/lib/ecore_con/ecore_con_info.c
deleted file mode 100644
index fdcf0b9..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_info.c
+++ /dev/null
@@ -1,449 +0,0 @@
1/*
2 * getaddrinfo with callback
3 *
4 * man getaddrinfo
5 *
6 */
7
8#ifdef HAVE_CONFIG_H
9# include <config.h>
10#endif
11
12#ifdef HAVE_ALLOCA_H
13# include <alloca.h>
14#elif defined __GNUC__
15# define alloca __builtin_alloca
16#elif defined _AIX
17# define alloca __alloca
18#elif defined _MSC_VER
19# include <malloc.h>
20# define alloca _alloca
21#else
22# include <stddef.h>
23# ifdef __cplusplus
24extern "C"
25# endif
26void *alloca(size_t);
27#endif
28
29#include <string.h>
30#include <sys/types.h>
31#include <unistd.h>
32#include <ctype.h>
33#ifdef __OpenBSD__
34# include <sys/types.h>
35#endif
36
37#ifdef HAVE_NETINET_IN_H
38# include <netinet/in.h>
39#endif
40
41#ifdef HAVE_ARPA_INET_H
42# include <arpa/inet.h>
43#endif
44
45#ifdef HAVE_ARPA_NAMESER_H
46# include <arpa/nameser.h>
47#endif
48
49#ifdef HAVE_SYS_SOCKET_H
50# include <sys/socket.h>
51#endif
52
53#ifdef HAVE_NETDB_H
54# include <netdb.h>
55#endif
56
57#include <errno.h>
58
59#include "Ecore.h"
60#include "ecore_private.h"
61#include "ecore_con_private.h"
62
63typedef struct _CB_Data CB_Data;
64
65struct _CB_Data
66{
67 EINA_INLIST;
68 Ecore_Con_Info_Cb cb_done;
69 void *data;
70 Ecore_Fd_Handler *fdh;
71 pid_t pid;
72 Ecore_Event_Handler *handler;
73 int fd2;
74};
75
76static void _ecore_con_info_readdata(CB_Data *cbdata);
77static void _ecore_con_info_slave_free(CB_Data *cbdata);
78static Eina_Bool _ecore_con_info_data_handler(void *data,
79 Ecore_Fd_Handler *fd_handler);
80static Eina_Bool _ecore_con_info_exit_handler(void *data,
81 int type __UNUSED__,
82 void *event);
83
84static int info_init = 0;
85static CB_Data *info_slaves = NULL;
86
87int
88ecore_con_info_init(void)
89{
90 info_init++;
91 return info_init;
92}
93
94int
95ecore_con_info_shutdown(void)
96{
97 info_init--;
98 if (info_init == 0)
99 while (info_slaves) _ecore_con_info_slave_free(info_slaves);
100
101 return info_init;
102}
103
104int
105ecore_con_info_tcp_connect(Ecore_Con_Server *svr,
106 Ecore_Con_Info_Cb done_cb,
107 void *data)
108{
109 struct addrinfo hints;
110
111 memset(&hints, 0, sizeof(struct addrinfo));
112 hints.ai_family = AF_UNSPEC;
113 hints.ai_socktype = SOCK_STREAM;
114 hints.ai_flags = AI_CANONNAME;
115 hints.ai_protocol = IPPROTO_TCP;
116 hints.ai_canonname = NULL;
117 hints.ai_next = NULL;
118 hints.ai_addr = NULL;
119
120 return ecore_con_info_get(svr, done_cb, data, &hints);
121}
122
123int
124ecore_con_info_tcp_listen(Ecore_Con_Server *svr,
125 Ecore_Con_Info_Cb done_cb,
126 void *data)
127{
128 struct addrinfo hints;
129
130 memset(&hints, 0, sizeof(struct addrinfo));
131 hints.ai_family = AF_UNSPEC;
132 hints.ai_socktype = SOCK_STREAM;
133 hints.ai_flags = AI_PASSIVE;
134 hints.ai_protocol = IPPROTO_TCP;
135 hints.ai_canonname = NULL;
136 hints.ai_next = NULL;
137 hints.ai_addr = NULL;
138
139 return ecore_con_info_get(svr, done_cb, data, &hints);
140}
141
142int
143ecore_con_info_udp_connect(Ecore_Con_Server *svr,
144 Ecore_Con_Info_Cb done_cb,
145 void *data)
146{
147 struct addrinfo hints;
148
149 memset(&hints, 0, sizeof(struct addrinfo));
150 hints.ai_family = AF_UNSPEC;
151 hints.ai_socktype = SOCK_DGRAM;
152 hints.ai_flags = AI_CANONNAME;
153 hints.ai_protocol = IPPROTO_UDP;
154 hints.ai_canonname = NULL;
155 hints.ai_next = NULL;
156 hints.ai_addr = NULL;
157
158 return ecore_con_info_get(svr, done_cb, data, &hints);
159}
160
161int
162ecore_con_info_udp_listen(Ecore_Con_Server *svr,
163 Ecore_Con_Info_Cb done_cb,
164 void *data)
165{
166 struct addrinfo hints;
167
168 memset(&hints, 0, sizeof(struct addrinfo));
169 hints.ai_family = AF_UNSPEC;
170 hints.ai_socktype = SOCK_DGRAM;
171 hints.ai_flags = AI_PASSIVE;
172 hints.ai_protocol = IPPROTO_UDP;
173 hints.ai_canonname = NULL;
174 hints.ai_next = NULL;
175 hints.ai_addr = NULL;
176
177 return ecore_con_info_get(svr, done_cb, data, &hints);
178}
179
180int
181ecore_con_info_mcast_listen(Ecore_Con_Server *svr,
182 Ecore_Con_Info_Cb done_cb,
183 void *data)
184{
185 struct addrinfo hints;
186
187 memset(&hints, 0, sizeof(struct addrinfo));
188 hints.ai_family = AF_UNSPEC;
189 hints.ai_socktype = SOCK_DGRAM;
190 hints.ai_flags = 0;
191 hints.ai_protocol = IPPROTO_UDP;
192 hints.ai_canonname = NULL;
193 hints.ai_next = NULL;
194 hints.ai_addr = NULL;
195
196 return ecore_con_info_get(svr, done_cb, data, &hints);
197}
198
199EAPI int
200ecore_con_info_get(Ecore_Con_Server *svr,
201 Ecore_Con_Info_Cb done_cb,
202 void *data,
203 struct addrinfo *hints)
204{
205 CB_Data *cbdata;
206 int fd[2];
207
208 if (pipe(fd) < 0)
209 {
210 ecore_con_event_server_error(svr, strerror(errno));
211 return 0;
212 }
213
214 cbdata = calloc(1, sizeof(CB_Data));
215 if (!cbdata)
216 {
217 close(fd[0]);
218 close(fd[1]);
219 return 0;
220 }
221
222 cbdata->cb_done = done_cb;
223 cbdata->data = data;
224 cbdata->fd2 = fd[1];
225 if (!(cbdata->fdh = ecore_main_fd_handler_add(fd[0], ECORE_FD_READ,
226 _ecore_con_info_data_handler,
227 cbdata,
228 NULL, NULL)))
229 {
230 ecore_con_event_server_error(svr, "Memory allocation failure");
231 free(cbdata);
232 close(fd[0]);
233 close(fd[1]);
234 return 0;
235 }
236
237 if ((cbdata->pid = fork()) == 0)
238 {
239 Ecore_Con_Info *container;
240 struct addrinfo *result = NULL;
241 char service[NI_MAXSERV] = {0};
242 char hbuf[NI_MAXHOST] = {0};
243 char sbuf[NI_MAXSERV] = {0};
244 unsigned char *tosend = NULL;
245 int tosend_len;
246 int canonname_len = 0;
247
248 eina_convert_itoa(svr->ecs ? svr->ecs->port : svr->port, service);
249 /* CHILD */
250 if (!getaddrinfo(svr->ecs ? svr->ecs->ip : svr->name, service, hints, &result) && result)
251 {
252 if (result->ai_canonname)
253 canonname_len = strlen(result->ai_canonname) + 1;
254
255 tosend_len = sizeof(Ecore_Con_Info) + result->ai_addrlen +
256 canonname_len;
257
258 tosend = alloca(tosend_len);
259 memset(tosend, 0, tosend_len);
260
261 container = (Ecore_Con_Info *)tosend;
262 container->size = tosend_len;
263
264 memcpy(&container->info,
265 result,
266 sizeof(struct addrinfo));
267 memcpy(tosend + sizeof(Ecore_Con_Info),
268 result->ai_addr,
269 result->ai_addrlen);
270 if (result->ai_canonname) /* FIXME: else... */
271 memcpy(tosend + sizeof(Ecore_Con_Info) + result->ai_addrlen,
272 result->ai_canonname,
273 canonname_len);
274
275 if (!getnameinfo(result->ai_addr, result->ai_addrlen,
276 hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
277 NI_NUMERICHOST | NI_NUMERICSERV))
278 {
279 memcpy(container->ip, hbuf, sizeof(container->ip));
280 memcpy(container->service, sbuf, sizeof(container->service));
281 }
282
283 if (write(fd[1], tosend, tosend_len) < 0) perror("write");
284 }
285
286 if (result)
287 freeaddrinfo(result);
288
289 if (write(fd[1], "", 1) < 0) perror("write");
290 close(fd[1]);
291#if defined(__USE_ISOC99) && !defined(__UCLIBC__)
292 _Exit(0);
293#else
294 _exit(0);
295#endif
296 }
297
298 /* PARENT */
299 cbdata->handler =
300 ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _ecore_con_info_exit_handler,
301 cbdata);
302 close(fd[1]);
303 if (!cbdata->handler)
304 {
305 ecore_main_fd_handler_del(cbdata->fdh);
306 free(cbdata);
307 close(fd[0]);
308 return 0;
309 }
310
311 info_slaves = (CB_Data *)eina_inlist_append(EINA_INLIST_GET(
312 info_slaves),
313 EINA_INLIST_GET(cbdata));
314 svr->infos = eina_list_append(svr->infos, cbdata);
315 return 1;
316}
317
318void
319ecore_con_info_data_clear(void *info)
320{
321 CB_Data *cbdata = info;
322 cbdata->data = NULL;
323}
324
325static void
326_ecore_con_info_readdata(CB_Data *cbdata)
327{
328 Ecore_Con_Info container;
329 Ecore_Con_Info *recv_info;
330 unsigned char *torecv;
331 int torecv_len;
332
333 ssize_t size;
334
335 size = read(ecore_main_fd_handler_fd_get(cbdata->fdh), &container,
336 sizeof(Ecore_Con_Info));
337 if (size == sizeof(Ecore_Con_Info))
338 {
339 torecv_len = container.size;
340 torecv = malloc(torecv_len);
341
342 memcpy(torecv, &container, sizeof(Ecore_Con_Info));
343
344 size = read(ecore_main_fd_handler_fd_get(cbdata->fdh),
345 torecv + sizeof(Ecore_Con_Info),
346 torecv_len - sizeof(Ecore_Con_Info));
347 if ((size > 0) &&
348 ((size_t)size == torecv_len - sizeof(Ecore_Con_Info)))
349 {
350 recv_info = (Ecore_Con_Info *)torecv;
351
352 recv_info->info.ai_addr =
353 (struct sockaddr *)(torecv + sizeof(Ecore_Con_Info));
354 if ((size_t)torecv_len !=
355 (sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen))
356 recv_info->info.ai_canonname = (char *)
357 (torecv + sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen);
358 else
359 recv_info->info.ai_canonname = NULL;
360
361 recv_info->info.ai_next = NULL;
362
363 if (cbdata->data)
364 {
365 cbdata->cb_done(cbdata->data, recv_info);
366 ecore_con_server_infos_del(cbdata->data, cbdata);
367 }
368
369 free(torecv);
370 }
371 else
372 {
373 if (cbdata->data)
374 {
375 cbdata->cb_done(cbdata->data, NULL);
376 ecore_con_server_infos_del(cbdata->data, cbdata);
377 }
378 }
379 }
380 else
381 {
382 if (cbdata->data)
383 {
384 ecore_con_event_server_error(cbdata->data, strerror(errno));
385 cbdata->cb_done(cbdata->data, NULL);
386 ecore_con_server_infos_del(cbdata->data, cbdata);
387 }
388 }
389
390 cbdata->cb_done = NULL;
391}
392
393static void
394_ecore_con_info_slave_free(CB_Data *cbdata)
395{
396 info_slaves = (CB_Data *)eina_inlist_remove(EINA_INLIST_GET(info_slaves),
397 EINA_INLIST_GET(cbdata));
398 ecore_main_fd_handler_del(cbdata->fdh);
399 ecore_event_handler_del(cbdata->handler);
400 close(ecore_main_fd_handler_fd_get(cbdata->fdh));
401 if (cbdata->data) ecore_con_server_infos_del(cbdata->data, cbdata);
402 free(cbdata);
403}
404
405static Eina_Bool
406_ecore_con_info_data_handler(void *data,
407 Ecore_Fd_Handler *fd_handler)
408{
409 CB_Data *cbdata;
410
411 cbdata = data;
412 if (cbdata->cb_done)
413 {
414 if (ecore_main_fd_handler_active_get(fd_handler,
415 ECORE_FD_READ))
416 _ecore_con_info_readdata(cbdata);
417 else
418 {
419 if (cbdata->data)
420 {
421 cbdata->cb_done(cbdata->data, NULL);
422 cbdata->cb_done = NULL;
423 ecore_con_server_infos_del(cbdata->data, cbdata);
424 }
425 }
426 }
427
428 _ecore_con_info_slave_free(cbdata);
429 return ECORE_CALLBACK_CANCEL;
430}
431
432static Eina_Bool
433_ecore_con_info_exit_handler(void *data,
434 int type __UNUSED__,
435 void *event)
436{
437 CB_Data *cbdata;
438 Ecore_Exe_Event_Del *ev;
439
440 ev = event;
441 cbdata = data;
442 if (cbdata->pid != ev->pid)
443 return ECORE_CALLBACK_RENEW;
444
445 return ECORE_CALLBACK_CANCEL; /* FIXME: Woot ??? */
446 _ecore_con_info_slave_free(cbdata);
447 return ECORE_CALLBACK_CANCEL;
448}
449
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_local.c b/libraries/ecore/src/lib/ecore_con/ecore_con_local.c
deleted file mode 100644
index f02cc1f..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_local.c
+++ /dev/null
@@ -1,317 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <string.h>
7#include <unistd.h>
8#include <time.h>
9#include <fcntl.h>
10#include <sys/stat.h>
11
12#ifdef HAVE_SYS_SOCKET_H
13# include <sys/socket.h>
14#endif
15
16#ifdef HAVE_SYS_UN_H
17# include <sys/un.h>
18#endif
19
20#ifdef HAVE_WS2TCPIP_H
21# include <ws2tcpip.h>
22#endif
23
24#include <Ecore.h>
25#include <ecore_private.h>
26
27#include "Ecore_Con.h"
28#include "ecore_con_private.h"
29
30#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + \
31 (size_t)(((struct sockaddr_un *)NULL)-> \
32 sun_path))
33#define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + \
34 (size_t)(((struct sockaddr_un \
35 *)NULL)->sun_path))
36
37static int _ecore_con_local_init_count = 0;
38
39int
40ecore_con_local_init(void)
41{
42 if (++_ecore_con_local_init_count != 1)
43 return _ecore_con_local_init_count;
44
45 return _ecore_con_local_init_count;
46}
47
48int
49ecore_con_local_shutdown(void)
50{
51 if (--_ecore_con_local_init_count != 0)
52 return _ecore_con_local_init_count;
53
54 return _ecore_con_local_init_count;
55}
56
57int
58ecore_con_local_connect(Ecore_Con_Server *svr,
59 Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler),
60 void *data __UNUSED__)
61{
62#ifndef HAVE_LOCAL_SOCKETS
63 return 0;
64#else
65 char buf[4096];
66 struct sockaddr_un socket_unix;
67 int curstate = 0;
68 const char *homedir;
69 int socket_unix_len;
70
71 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
72 {
73 homedir = getenv("HOME");
74 if (!homedir)
75 homedir = getenv("TMP");
76
77 if (!homedir)
78 homedir = "/tmp";
79
80 snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, svr->name,
81 svr->port);
82 }
83 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
84 {
85 if (svr->port < 0)
86 {
87 if (svr->name[0] == '/')
88 strncpy(buf, svr->name, sizeof(buf));
89 else
90 snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s", svr->name);
91 }
92 else
93 {
94 if (svr->name[0] ==
95 '/')
96 snprintf(buf, sizeof(buf), "%s|%i", svr->name,
97 svr->port);
98 else
99 snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i",
100 svr->name,
101 svr->port);
102 }
103 }
104 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
105 strncpy(buf, svr->name,
106 sizeof(buf));
107
108 svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
109 if (svr->fd < 0)
110 return 0;
111
112 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
113 return 0;
114
115 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
116 return 0;
117
118 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate,
119 sizeof(curstate)) < 0)
120 return 0;
121
122 socket_unix.sun_family = AF_UNIX;
123
124 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
125 {
126#ifdef HAVE_ABSTRACT_SOCKETS
127 /* copy name insto sun_path, prefixed by null to indicate abstract namespace */
128 snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
129 svr->name);
130 socket_unix.sun_path[0] = '\0';
131 socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
132 svr->name);
133#else
134 WRN("Your system does not support abstract sockets!");
135 return 0;
136#endif
137 }
138 else
139 {
140 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
141 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
142 }
143
144 if (connect(svr->fd, (struct sockaddr *)&socket_unix,
145 socket_unix_len) < 0)
146 return 0;
147
148 svr->path = strdup(buf);
149 if (!svr->path)
150 return 0;
151
152 if (svr->type & ECORE_CON_SSL)
153 ecore_con_ssl_server_init(svr);
154
155 svr->fd_handler =
156 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
157 cb_done, svr, NULL, NULL);
158 if (!svr->fd_handler)
159 return 0;
160
161 if (!svr->delete_me) ecore_con_event_server_add(svr);
162
163 return 1;
164#endif
165}
166
167int
168ecore_con_local_listen(
169 Ecore_Con_Server *svr,
170 Eina_Bool (*
171 cb_listen)(void *data,
172 Ecore_Fd_Handler *
173 fd_handler),
174 void *data
175 __UNUSED__)
176{
177#ifdef HAVE_LOCAL_SOCKETS
178 char buf[4096];
179 struct sockaddr_un socket_unix;
180 struct linger lin;
181 mode_t pmode;
182 const char *homedir;
183 struct stat st;
184 mode_t mask;
185 int socket_unix_len;
186
187 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
188
189 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
190 {
191 homedir = getenv("HOME");
192 if (!homedir)
193 homedir = getenv("TMP");
194
195 if (!homedir)
196 homedir = "/tmp";
197
198 mask = S_IRUSR | S_IWUSR | S_IXUSR;
199 snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
200 if (stat(buf, &st) < 0)
201 mkdir(buf, mask);
202
203 snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, svr->name);
204 if (stat(buf, &st) < 0)
205 mkdir(buf, mask);
206
207 snprintf(buf,
208 sizeof(buf),
209 "%s/.ecore/%s/%i",
210 homedir,
211 svr->name,
212 svr->port);
213 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
214 }
215 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
216 {
217 mask = 0;
218 if (svr->name[0] == '/')
219 {
220 if (svr->port >= 0)
221 snprintf(buf,
222 sizeof(buf),
223 "%s|%i",
224 svr->name,
225 svr->port);
226 else
227 snprintf(buf,
228 sizeof(buf),
229 "%s",
230 svr->name);
231 }
232 else
233 snprintf(buf,
234 sizeof(buf),
235 "/tmp/.ecore_service|%s|%i",
236 svr->name,
237 svr->port);
238 }
239 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
240 strncpy(buf, svr->name,
241 sizeof(buf));
242
243 pmode = umask(mask);
244start:
245 svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
246 if (svr->fd < 0)
247 goto error_umask;
248
249 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
250 goto error_umask;
251
252 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
253 goto error_umask;
254
255 lin.l_onoff = 1;
256 lin.l_linger = 0;
257 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
258 sizeof(struct linger)) < 0)
259 goto error_umask;
260
261 socket_unix.sun_family = AF_UNIX;
262 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
263 {
264#ifdef HAVE_ABSTRACT_SOCKETS
265 /* . is a placeholder */
266 snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
267 svr->name);
268 /* first char null indicates abstract namespace */
269 socket_unix.sun_path[0] = '\0';
270 socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
271 svr->name);
272#else
273 ERR("Your system does not support abstract sockets!");
274 goto error_umask;
275#endif
276 }
277 else
278 {
279 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
280 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
281 }
282
283 if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
284 {
285 if ((((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) ||
286 ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)) &&
287 (connect(svr->fd, (struct sockaddr *)&socket_unix,
288 socket_unix_len) < 0) &&
289 (unlink(buf) >= 0))
290 goto start;
291 else
292 goto error_umask;
293 }
294
295 if (listen(svr->fd, 4096) < 0)
296 goto error_umask;
297
298 svr->path = strdup(buf);
299 if (!svr->path)
300 goto error_umask;
301
302 svr->fd_handler =
303 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
304 cb_listen, svr, NULL, NULL);
305 umask(pmode);
306 if (!svr->fd_handler)
307 goto error;
308
309 return 1;
310
311error_umask:
312 umask(pmode);
313error:
314#endif /* HAVE_LOCAL_SOCKETS */
315 return 0;
316}
317
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c b/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c
deleted file mode 100644
index 2b7e5c5..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c
+++ /dev/null
@@ -1,754 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <process.h>
6
7#include <Evil.h>
8#include <Ecore.h>
9
10#include "Ecore_Con.h"
11#include "ecore_con_private.h"
12
13#define BUFSIZE 512
14
15
16static int _ecore_con_local_init_count = 0;
17
18int
19ecore_con_local_init(void)
20{
21 if (++_ecore_con_local_init_count != 1)
22 return _ecore_con_local_init_count;
23
24 return _ecore_con_local_init_count;
25}
26
27int
28ecore_con_local_shutdown(void)
29{
30 if (--_ecore_con_local_init_count != 0)
31 return _ecore_con_local_init_count;
32
33 return _ecore_con_local_init_count;
34}
35
36
37static Eina_Bool
38_ecore_con_local_win32_server_read_client_handler(void *data, Ecore_Win32_Handler *wh)
39{
40 Ecore_Con_Client *cl;
41 void *buf;
42 DWORD n;
43 Eina_Bool broken_pipe = EINA_FALSE;
44
45 cl = (Ecore_Con_Client *)data;
46
47 if (!ResetEvent(cl->host_server->event_read))
48 return ECORE_CALLBACK_RENEW;
49
50 buf = malloc(cl->host_server->nbr_bytes);
51 if (!buf)
52 return ECORE_CALLBACK_RENEW;
53
54 if (ReadFile(cl->host_server->pipe, buf, cl->host_server->nbr_bytes, &n, NULL))
55 {
56 if (!cl->delete_me)
57 ecore_con_event_client_data(cl, buf, cl->host_server->nbr_bytes, EINA_FALSE);
58 cl->host_server->want_write = 1;
59 }
60 else
61 {
62 if (GetLastError() == ERROR_BROKEN_PIPE)
63 broken_pipe = EINA_TRUE;
64 }
65
66 if (broken_pipe)
67 {
68#if 0
69 char *msg;
70
71 msg = evil_last_error_get();
72 if (msg)
73 {
74 ecore_con_event_client_error(cl, msg);
75 free(msg);
76 }
77#endif
78 _ecore_con_client_kill(cl);
79 return ECORE_CALLBACK_CANCEL;
80 }
81
82 if (cl->host_server->want_write)
83 ecore_con_local_win32_client_flush(cl);
84
85 ecore_main_win32_handler_del(wh);
86
87 return ECORE_CALLBACK_DONE;
88}
89
90static Eina_Bool
91_ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handler *wh)
92{
93 Ecore_Con_Client *cl;
94#if 0
95 char *msg;
96#endif
97
98 cl = (Ecore_Con_Client *)data;
99
100 if (!ResetEvent(cl->host_server->event_peek))
101 return ECORE_CALLBACK_RENEW;
102
103#if 0
104 msg = evil_last_error_get();
105 if (msg)
106 {
107 ecore_con_event_server_error(cl->host_server, msg);
108 free(msg);
109 }
110#endif
111 _ecore_con_server_kill(cl->host_server);
112 return ECORE_CALLBACK_CANCEL;
113
114 ecore_main_win32_handler_del(wh);
115
116 return ECORE_CALLBACK_DONE;
117}
118
119static Eina_Bool
120_ecore_con_local_win32_client_peek_server_handler(void *data, Ecore_Win32_Handler *wh)
121{
122 Ecore_Con_Server *svr;
123#if 0
124 char *msg;
125#endif
126
127 svr = (Ecore_Con_Server *)data;
128
129 if (!ResetEvent(svr->event_peek))
130 return ECORE_CALLBACK_RENEW;
131#if 0
132 msg = evil_last_error_get();
133 if (msg)
134 {
135 ecore_con_event_server_error(svr, msg);
136 free(msg);
137 }
138#endif
139 _ecore_con_server_kill(svr);
140 return ECORE_CALLBACK_CANCEL;
141
142 ecore_main_win32_handler_del(wh);
143
144 return ECORE_CALLBACK_DONE;
145}
146
147static Eina_Bool
148_ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handler *wh)
149{
150 Ecore_Con_Server *svr;
151 void *buf;
152 DWORD n;
153 Eina_Bool broken_pipe = EINA_FALSE;
154
155 svr = (Ecore_Con_Server *)data;
156
157 if (!ResetEvent(svr->event_read))
158 return ECORE_CALLBACK_RENEW;
159
160 buf = malloc(svr->nbr_bytes);
161 if (!buf)
162 return ECORE_CALLBACK_RENEW;
163
164 if (ReadFile(svr->pipe, buf, svr->nbr_bytes, &n, NULL))
165 {
166 if (!svr->delete_me)
167 ecore_con_event_server_data(svr, buf, svr->nbr_bytes, EINA_FALSE);
168 svr->want_write = 1;
169 }
170 else
171 {
172 if (GetLastError() == ERROR_BROKEN_PIPE)
173 broken_pipe = EINA_TRUE;
174 }
175
176 if (broken_pipe)
177 {
178#if 0
179 char *msg;
180
181 msg = evil_last_error_get();
182 if (msg)
183 {
184 ecore_con_event_server_error(svr, msg);
185 free(msg);
186 }
187#endif
188 _ecore_con_server_kill(svr);
189 return ECORE_CALLBACK_CANCEL;
190 }
191
192 if (svr->want_write)
193 ecore_con_local_win32_server_flush(svr);
194
195 ecore_main_win32_handler_del(wh);
196
197 return ECORE_CALLBACK_DONE;
198}
199
200/* thread to read data sent by the server to the client */
201static unsigned int __stdcall
202_ecore_con_local_win32_client_read_server_thread(void *data)
203{
204 Ecore_Con_Server *svr;
205 DWORD nbr_bytes = 0;
206
207 svr = (Ecore_Con_Server *)data;
208
209 svr->read_stopped = EINA_FALSE;
210
211 while (!svr->read_stop)
212 {
213 if (PeekNamedPipe(svr->pipe, NULL, 0, NULL, &nbr_bytes, NULL))
214 {
215 if (nbr_bytes <= 0)
216 continue;
217
218 svr->nbr_bytes = nbr_bytes;
219 if (!SetEvent(svr->event_read))
220 continue;
221 }
222 else
223 {
224 if (GetLastError() == ERROR_BROKEN_PIPE)
225 {
226 if (!SetEvent(svr->event_peek))
227 continue;
228 break;
229 }
230 }
231 }
232
233 printf(" ### %s\n", __FUNCTION__);
234 svr->read_stopped = EINA_TRUE;
235 _endthreadex(0);
236 return 0;
237}
238
239/* thread to read data sent by the client to the server */
240static unsigned int __stdcall
241_ecore_con_local_win32_server_read_client_thread(void *data)
242{
243 Ecore_Con_Client *cl;
244 DWORD nbr_bytes = 0;
245
246 cl = (Ecore_Con_Client *)data;
247
248 cl->host_server->read_stopped = EINA_FALSE;
249
250 while (!cl->host_server->read_stop)
251 {
252 if (PeekNamedPipe(cl->host_server->pipe, NULL, 0, NULL, &nbr_bytes, NULL))
253 {
254 if (nbr_bytes <= 0)
255 continue;
256
257 cl->host_server->nbr_bytes = nbr_bytes;
258 if (!SetEvent(cl->host_server->event_read))
259 continue;
260 }
261 else
262 {
263 if (GetLastError() == ERROR_BROKEN_PIPE)
264 {
265 if (!SetEvent(cl->host_server->event_peek))
266 continue;
267 break;
268 }
269 }
270 }
271
272 printf(" ### %s\n", __FUNCTION__);
273 cl->host_server->read_stopped = EINA_TRUE;
274 _endthreadex(0);
275 return 0;
276}
277
278static Eina_Bool
279_ecore_con_local_win32_client_add(void *data, Ecore_Win32_Handler *wh)
280{
281 Ecore_Con_Client *cl = NULL;
282 Ecore_Con_Server *svr;
283 Ecore_Win32_Handler *handler_read;
284 Ecore_Win32_Handler *handler_peek;
285
286 svr = (Ecore_Con_Server *)data;
287
288 if (!svr->pipe)
289 return ECORE_CALLBACK_CANCEL;
290
291 if (svr->delete_me)
292 return ECORE_CALLBACK_CANCEL;
293
294 if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) &&
295 (svr->client_count >= (unsigned int)svr->client_limit))
296 return ECORE_CALLBACK_CANCEL;
297
298 cl = calloc(1, sizeof(Ecore_Con_Client));
299 if (!cl)
300 {
301 ERR("allocation failed");
302 return ECORE_CALLBACK_CANCEL;
303 }
304
305 cl->host_server = svr;
306 ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
307
308 cl->host_server->event_read = CreateEvent(NULL, TRUE, FALSE, NULL);
309 if (!cl->host_server->event_read)
310 {
311 ERR("Can not create event read");
312 goto free_cl;
313 }
314
315 handler_read = ecore_main_win32_handler_add(cl->host_server->event_read,
316 _ecore_con_local_win32_server_read_client_handler,
317 cl);
318 if (!handler_read)
319 {
320 ERR("Can not create handler read");
321 goto close_event_read;
322 }
323
324 cl->host_server->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL);
325 if (!cl->host_server->event_peek)
326 {
327 ERR("Can not create event peek");
328 goto del_handler_read;
329 }
330
331 handler_peek = ecore_main_win32_handler_add(cl->host_server->event_peek,
332 _ecore_con_local_win32_server_peek_client_handler,
333 cl);
334 if (!handler_peek)
335 {
336 ERR("Can not create handler peek");
337 goto close_event_peek;
338 }
339
340 cl->host_server->read_stopped = EINA_TRUE;
341 cl->host_server->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_server_read_client_thread, cl, CREATE_SUSPENDED, NULL);
342 if (!cl->host_server->thread_read)
343 {
344 ERR("Can not launch thread");
345 goto del_handler_peek;
346 }
347
348 svr->clients = eina_list_append(svr->clients, cl);
349 svr->client_count++;
350
351 if (!cl->delete_me)
352 ecore_con_event_client_add(cl);
353
354 ecore_main_win32_handler_del(wh);
355
356 ResumeThread(cl->host_server->thread_read);
357 return ECORE_CALLBACK_DONE;
358
359 del_handler_peek:
360 ecore_main_win32_handler_del(handler_peek);
361 close_event_peek:
362 CloseHandle(cl->host_server->event_peek);
363 del_handler_read:
364 ecore_main_win32_handler_del(handler_read);
365 close_event_read:
366 CloseHandle(cl->host_server->event_read);
367 free_cl:
368 free(cl);
369
370 return ECORE_CALLBACK_CANCEL;
371}
372
373static unsigned int __stdcall
374_ecore_con_local_win32_listening(void *data)
375{
376 Ecore_Con_Server *svr;
377 BOOL res;
378
379 svr = (Ecore_Con_Server *)data;
380
381 while (1)
382 {
383 res = ConnectNamedPipe(svr->pipe, NULL);
384 if (!res)
385 {
386 ERR("Opening the connection to the client failed");
387 CloseHandle(svr->pipe);
388 svr->pipe = NULL;
389 }
390 break;
391 }
392
393 DBG("Client connected");
394
395 printf(" ### %s\n", __FUNCTION__);
396 _endthreadex(0);
397 return 0;
398}
399
400Eina_Bool
401ecore_con_local_listen(Ecore_Con_Server *svr)
402{
403 char buf[256];
404 HANDLE thread_listening;
405 Ecore_Win32_Handler *handler;
406
407 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
408 {
409 ERR("Your system does not support abstract sockets!");
410 return EINA_FALSE;
411 }
412
413 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
414 snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name);
415 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
416 {
417 const char *computername;
418
419 computername = getenv("CoMPUTERNAME");
420 snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name);
421 }
422
423 svr->path = strdup(buf);
424 if (!svr->path)
425 {
426 ERR("Allocation failed");
427 return EINA_FALSE;
428 }
429
430 /*
431 * synchronuous
432 * block mode
433 * wait mode
434 */
435 svr->pipe = CreateNamedPipe(svr->path,
436 PIPE_ACCESS_DUPLEX,
437 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
438 PIPE_UNLIMITED_INSTANCES,
439 BUFSIZE,
440 BUFSIZE,
441 5000,
442 NULL);
443 if (svr->pipe == INVALID_HANDLE_VALUE)
444 {
445 ERR("Creation of the named pipe failed");
446 goto free_path;
447 }
448
449 /*
450 * We use ConnectNamedPipe() to wait for a client to connect.
451 * As the function is blocking, to let the main loop continuing
452 * its iterations, we call ConnectNamedPipe() in a thread
453 */
454 thread_listening = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_listening, svr, CREATE_SUSPENDED, NULL);
455 if (!thread_listening)
456 {
457 ERR("Creation of the listening thread failed");
458 goto close_pipe;
459 }
460
461 handler = ecore_main_win32_handler_add(thread_listening,
462 _ecore_con_local_win32_client_add,
463 svr);
464 if (!handler)
465 {
466 ERR("Creation of the client add handler failed");
467 goto del_handler;
468 }
469
470 svr->read_stopped = EINA_TRUE;
471 ResumeThread(thread_listening);
472
473 return EINA_TRUE;
474
475 del_handler:
476 ecore_main_win32_handler_del(handler);
477 close_pipe:
478 CloseHandle(svr->pipe);
479 free_path:
480 free(svr->path);
481 svr->path = NULL;
482
483 return EINA_FALSE;
484}
485
486void
487ecore_con_local_win32_server_del(Ecore_Con_Server *svr)
488{
489 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
490 return;
491
492 if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) &&
493 ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM))
494 return;
495
496 svr->read_stop = 1;
497 while (!svr->read_stopped)
498 Sleep(100);
499
500 if (svr->event_peek)
501 CloseHandle(svr->event_peek);
502 svr->event_peek = NULL;
503 if (svr->event_read)
504 CloseHandle(svr->event_read);
505 svr->event_read = NULL;
506 free(svr->path);
507 svr->path = NULL;
508 if (svr->pipe)
509 CloseHandle(svr->pipe);
510 svr->pipe = NULL;
511}
512
513void
514ecore_con_local_win32_client_del(Ecore_Con_Client *cl)
515{
516 if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
517 return;
518
519 if (((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) &&
520 ((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM))
521 return;
522
523 cl->host_server->read_stop = 1;
524 while (!cl->host_server->read_stopped)
525 Sleep(100);
526
527 if (cl->host_server->event_peek)
528 CloseHandle(cl->host_server->event_peek);
529 cl->host_server->event_peek = NULL;
530 if (cl->host_server->event_read)
531 CloseHandle(cl->host_server->event_read);
532 cl->host_server->event_read = NULL;
533 free(cl->host_server->path);
534 cl->host_server->path = NULL;
535 if (cl->host_server->pipe)
536 CloseHandle(cl->host_server->pipe);
537 cl->host_server->pipe = NULL;
538}
539
540Eina_Bool
541ecore_con_local_connect(Ecore_Con_Server *svr,
542 Eina_Bool (*cb_done)(void *data,
543 Ecore_Fd_Handler *fd_handler))
544{
545 char buf[256];
546 Ecore_Win32_Handler *handler_read;
547 Ecore_Win32_Handler *handler_peek;
548
549 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
550 {
551 ERR("Your system does not support abstract sockets!");
552 return EINA_FALSE;
553 }
554
555 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
556 snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name);
557 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
558 {
559 const char *computername;
560
561 computername = getenv("COMPUTERNAME");
562 snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name);
563 }
564
565 while (1)
566 {
567 svr->pipe = CreateFile(buf,
568 GENERIC_READ | GENERIC_WRITE,
569 0,
570 NULL,
571 OPEN_EXISTING,
572 0,
573 NULL);
574 if (svr->pipe != INVALID_HANDLE_VALUE)
575 break;
576
577 /* if pipe not busy, we exit */
578 if (GetLastError() != ERROR_PIPE_BUSY)
579 {
580 ERR("Connection to a server failed");
581 return EINA_FALSE;
582 }
583
584 /* pipe busy, so we wait for it */
585 if (!WaitNamedPipe(buf, NMPWAIT_WAIT_FOREVER))
586 {
587 ERR("Can not wait for a server");
588 goto close_pipe;
589 }
590 }
591
592 svr->path = strdup(buf);
593 if (!svr->path)
594 {
595 ERR("Allocation failed");
596 goto close_pipe;
597 }
598
599 svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL);
600 if (!svr->event_read)
601 {
602 ERR("Can not create event read");
603 goto free_path;
604 }
605
606 handler_read = ecore_main_win32_handler_add(svr->event_read,
607 _ecore_con_local_win32_client_read_server_handler,
608 svr);
609 if (!handler_read)
610 {
611 ERR("Can not create handler read");
612 goto close_event_read;
613 }
614
615 svr->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL);
616 if (!svr->event_peek)
617 {
618 ERR("Can not create event peek");
619 goto del_handler_read;
620 }
621
622 handler_peek = ecore_main_win32_handler_add(svr->event_peek,
623 _ecore_con_local_win32_client_peek_server_handler,
624 svr);
625 if (!handler_peek)
626 {
627 ERR("Can not create handler peek");
628 goto close_event_peek;
629 }
630
631 svr->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_client_read_server_thread, svr, CREATE_SUSPENDED, NULL);
632 if (!svr->thread_read)
633 {
634 ERR("Can not launch thread");
635 goto del_handler_peek;
636 }
637
638 if (!svr->delete_me) ecore_con_event_server_add(svr);
639
640 ResumeThread(svr->thread_read);
641
642 return EINA_TRUE;
643
644 del_handler_peek:
645 ecore_main_win32_handler_del(handler_peek);
646 close_event_peek:
647 CloseHandle(svr->event_peek);
648 del_handler_read:
649 ecore_main_win32_handler_del(handler_read);
650 close_event_read:
651 CloseHandle(svr->event_read);
652 free_path:
653 free(svr->path);
654 svr->path = NULL;
655 close_pipe:
656 CloseHandle(svr->pipe);
657
658 return EINA_FALSE;
659}
660
661Eina_Bool
662ecore_con_local_win32_server_flush(Ecore_Con_Server *svr)
663{
664 int num;
665 BOOL res;
666 DWORD written;
667
668 /* This check should never be true */
669 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
670 return EINA_TRUE;
671
672 if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) &&
673 ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM))
674 return EINA_FALSE;
675
676 num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset;
677 if (num <= 0) return EINA_TRUE;
678
679 res = WriteFile(svr->pipe, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num, &written, NULL);
680 if (!res)
681 {
682 char *msg;
683
684 msg = evil_last_error_get();
685 if (msg)
686 {
687 ecore_con_event_server_error(svr, msg);
688 free(msg);
689 }
690 _ecore_con_server_kill(svr);
691 }
692
693 svr->write_buf_offset += written;
694 if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf))
695 {
696 svr->write_buf_offset = 0;
697 eina_binbuf_free(svr->buf);
698 svr->buf = NULL;
699 svr->want_write = 0;
700 }
701 else if (written < (DWORD)num)
702 svr->want_write = 1;
703
704 return EINA_TRUE;
705}
706
707Eina_Bool
708ecore_con_local_win32_client_flush(Ecore_Con_Client *cl)
709{
710 Ecore_Con_Type type;
711 int num;
712 BOOL res;
713 DWORD written;
714
715 type = cl->host_server->type & ECORE_CON_TYPE;
716
717 /* This check should never be true */
718 if (type == ECORE_CON_LOCAL_ABSTRACT)
719 return EINA_TRUE;
720
721 if ((type != ECORE_CON_LOCAL_USER) &&
722 (type != ECORE_CON_LOCAL_SYSTEM))
723 return EINA_FALSE;
724
725 num = eina_binbuf_length_get(cl->buf) - cl->buf_offset;
726 if (num <= 0) return EINA_TRUE;
727
728 res = WriteFile(cl->host_server->pipe, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num, &written, NULL);
729 if (!res)
730 {
731 char *msg;
732
733 msg = evil_last_error_get();
734 if (msg)
735 {
736 ecore_con_event_client_error(cl, msg);
737 free(msg);
738 }
739 _ecore_con_client_kill(cl);
740 }
741
742 cl->buf_offset += written;
743 if (cl->buf_offset >= eina_binbuf_length_get(cl->buf))
744 {
745 cl->buf_offset = 0;
746 eina_binbuf_free(cl->buf);
747 cl->buf = NULL;
748 cl->host_server->want_write = 0;
749 }
750 else if (written < (DWORD)num)
751 cl->host_server->want_write = 1;
752
753 return EINA_TRUE;
754}
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_private.h b/libraries/ecore/src/lib/ecore_con/ecore_con_private.h
deleted file mode 100644
index 91f5d39..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_private.h
+++ /dev/null
@@ -1,397 +0,0 @@
1#ifndef _ECORE_CON_PRIVATE_H
2#define _ECORE_CON_PRIVATE_H
3
4#include "ecore_private.h"
5#include "Ecore_Con.h"
6
7#define ECORE_MAGIC_CON_SERVER 0x77665544
8#define ECORE_MAGIC_CON_CLIENT 0x77556677
9#define ECORE_MAGIC_CON_URL 0x77074255
10
11#define ECORE_CON_TYPE 0x0f
12#define ECORE_CON_SSL 0xf0
13
14#if USE_GNUTLS
15# include <gnutls/gnutls.h>
16#elif USE_OPENSSL
17# include <openssl/ssl.h>
18#endif
19#ifdef HAVE_CURL
20#include <curl/curl.h>
21#endif
22
23#define READBUFSIZ 65536
24
25extern int _ecore_con_log_dom;
26
27#ifdef ECORE_CON_DEFAULT_LOG_COLOR
28#undef ECORE_LOG_DEFAULT_LOG_COLOR
29#endif
30#define ECORE_CON_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
31
32#ifdef ERR
33# undef ERR
34#endif
35#define ERR(...) EINA_LOG_DOM_ERR(_ecore_con_log_dom, __VA_ARGS__)
36
37#ifdef DBG
38# undef DBG
39#endif
40#define DBG(...) EINA_LOG_DOM_DBG(_ecore_con_log_dom, __VA_ARGS__)
41
42#ifdef INF
43# undef INF
44#endif
45#define INF(...) EINA_LOG_DOM_INFO(_ecore_con_log_dom, __VA_ARGS__)
46
47#ifdef WRN
48# undef WRN
49#endif
50#define WRN(...) EINA_LOG_DOM_WARN(_ecore_con_log_dom, __VA_ARGS__)
51
52#ifdef CRIT
53# undef CRIT
54#endif
55#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_con_log_dom, __VA_ARGS__)
56
57typedef struct _Ecore_Con_Lookup Ecore_Con_Lookup;
58typedef struct _Ecore_Con_Info Ecore_Con_Info;
59typedef struct Ecore_Con_Socks Ecore_Con_Socks_v4;
60typedef struct Ecore_Con_Socks_v5 Ecore_Con_Socks_v5;
61typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos);
62
63typedef enum _Ecore_Con_State
64{
65 ECORE_CON_CONNECTED,
66 ECORE_CON_DISCONNECTED,
67 ECORE_CON_INPROGRESS
68} Ecore_Con_State;
69
70typedef enum _Ecore_Con_Ssl_Error
71{
72 ECORE_CON_SSL_ERROR_NONE = 0,
73 ECORE_CON_SSL_ERROR_NOT_SUPPORTED,
74 ECORE_CON_SSL_ERROR_INIT_FAILED,
75 ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED,
76 ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED
77} Ecore_Con_Ssl_Error;
78
79typedef enum _Ecore_Con_Ssl_Handshake
80{
81 ECORE_CON_SSL_STATE_DONE = 0,
82 ECORE_CON_SSL_STATE_HANDSHAKING,
83 ECORE_CON_SSL_STATE_INIT
84} Ecore_Con_Ssl_State;
85
86typedef enum Ecore_Con_Proxy_State
87{ /* named PROXY instead of SOCKS in case some handsome and enterprising
88 * developer decides to add HTTP CONNECT support
89 */
90 ECORE_CON_PROXY_STATE_DONE = 0,
91 ECORE_CON_PROXY_STATE_RESOLVED,
92 ECORE_CON_PROXY_STATE_INIT,
93 ECORE_CON_PROXY_STATE_READ,
94 ECORE_CON_PROXY_STATE_AUTH,
95 ECORE_CON_PROXY_STATE_REQUEST,
96 ECORE_CON_PROXY_STATE_CONFIRM,
97} Ecore_Con_Proxy_State;
98
99struct _Ecore_Con_Client
100{
101 ECORE_MAGIC;
102 int fd;
103 Ecore_Con_Server *host_server;
104 void *data;
105 Ecore_Fd_Handler *fd_handler;
106 unsigned int buf_offset;
107 Eina_Binbuf *buf;
108 const char *ip;
109 Eina_List *event_count;
110 struct sockaddr *client_addr;
111 int client_addr_len;
112 double start_time;
113 Ecore_Timer *until_deletion;
114 double disconnect_time;
115#if USE_GNUTLS
116 gnutls_datum_t session_ticket;
117 gnutls_session_t session;
118#elif USE_OPENSSL
119 SSL *ssl;
120 int ssl_err;
121#endif
122 Ecore_Con_Ssl_State ssl_state;
123 Eina_Bool handshaking : 1;
124 Eina_Bool upgrade : 1; /* STARTTLS queued */
125 Eina_Bool delete_me : 1; /* del event has been queued */
126};
127
128struct _Ecore_Con_Server
129{
130 ECORE_MAGIC;
131 int fd;
132 Ecore_Con_Type type;
133 char *name;
134 int port;
135 char *path;
136 void *data;
137 Ecore_Fd_Handler *fd_handler;
138 Eina_List *clients;
139 unsigned int client_count;
140 Eina_Binbuf *buf;
141 unsigned int write_buf_offset;
142 Eina_List *infos;
143 Eina_List *event_count;
144 int client_limit;
145 pid_t ppid;
146 /* socks */
147 Ecore_Con_Socks *ecs;
148 Ecore_Con_Proxy_State ecs_state;
149 int ecs_addrlen;
150 unsigned char ecs_addr[16];
151 unsigned int ecs_buf_offset;
152 Eina_Binbuf *ecs_buf;
153 Eina_Binbuf *ecs_recvbuf;
154 const char *proxyip;
155 int proxyport;
156 /* endsocks */
157 const char *verify_name;
158#if USE_GNUTLS
159 gnutls_session_t session;
160 gnutls_anon_client_credentials_t anoncred_c;
161 gnutls_anon_server_credentials_t anoncred_s;
162 gnutls_psk_client_credentials_t pskcred_c;
163 gnutls_psk_server_credentials_t pskcred_s;
164 gnutls_certificate_credentials_t cert;
165 char *cert_file;
166 gnutls_dh_params_t dh_params;
167#elif USE_OPENSSL
168 SSL_CTX *ssl_ctx;
169 SSL *ssl;
170 int ssl_err;
171#endif
172 double start_time;
173 Ecore_Timer *until_deletion;
174 double disconnect_time;
175 double client_disconnect_time;
176 const char *ip;
177 Eina_Bool created : 1; /* EINA_TRUE if server is our listening server */
178 Eina_Bool connecting : 1; /* EINA_FALSE if just initialized or connected */
179 Eina_Bool handshaking : 1; /* EINA_TRUE if server is ssl handshaking */
180 Eina_Bool upgrade : 1; /* STARTTLS queued */
181 Eina_Bool ssl_prepared : 1;
182 Eina_Bool use_cert : 1; /* EINA_TRUE if using certificate auth */
183 Ecore_Con_Ssl_State ssl_state; /* current state of ssl handshake on the server */
184 Eina_Bool verify : 1; /* EINA_TRUE if certificates will be verified */
185 Eina_Bool verify_basic : 1; /* EINA_TRUE if certificates will be verified only against the hostname */
186 Eina_Bool reject_excess_clients : 1;
187 Eina_Bool delete_me : 1; /* del event has been queued */
188#ifdef _WIN32
189 Eina_Bool want_write : 1;
190 Eina_Bool read_stop : 1;
191 Eina_Bool read_stopped : 1;
192 HANDLE pipe;
193 HANDLE thread_read;
194 HANDLE event_read;
195 HANDLE event_peek;
196 DWORD nbr_bytes;
197#endif
198};
199
200#ifdef HAVE_CURL
201struct _Ecore_Con_Url
202{
203 ECORE_MAGIC;
204 CURL *curl_easy;
205 struct curl_slist *headers;
206 Eina_List *additional_headers;
207 Eina_List *response_headers;
208 const char *url;
209 long proxy_type;
210 int status;
211
212 Ecore_Timer *timer;
213
214 Ecore_Con_Url_Time time_condition;
215 double timestamp;
216 void *data;
217
218 void *post_data;
219
220 int received;
221 int write_fd;
222
223 unsigned int event_count;
224 Eina_Bool dead : 1;
225 Eina_Bool multi : 1;
226};
227#endif
228
229struct _Ecore_Con_Info
230{
231 unsigned int size;
232 struct addrinfo info;
233 char ip[NI_MAXHOST];
234 char service[NI_MAXSERV];
235};
236
237struct _Ecore_Con_Lookup
238{
239 Ecore_Con_Dns_Cb done_cb;
240 const void *data;
241};
242
243#define ECORE_CON_SOCKS_CAST_ELSE(X) \
244 Ecore_Con_Socks_v4 *v4 = NULL; \
245 Ecore_Con_Socks_v5 *v5 = NULL; \
246 if ((X) && ((X)->version == 4)) \
247 v4 = (Ecore_Con_Socks_v4*)(X); \
248 else if ((X) && ((X)->version == 5)) \
249 v5 = (Ecore_Con_Socks_v5*)(X); \
250 else
251
252struct Ecore_Con_Socks /* v4 */
253{
254 unsigned char version;
255
256 const char *ip;
257 int port;
258 const char *username;
259 unsigned int ulen;
260 Eina_Bool lookup : 1;
261 Eina_Bool bind : 1;
262};
263
264struct Ecore_Con_Socks_v5
265{
266 unsigned char version;
267
268 const char *ip;
269 int port;
270 const char *username;
271 unsigned int ulen;
272 Eina_Bool lookup : 1;
273 Eina_Bool bind : 1;
274 /* v5 only */
275 unsigned char method;
276 const char *password;
277 unsigned int plen;
278};
279
280extern Ecore_Con_Socks *_ecore_con_proxy_once;
281extern Ecore_Con_Socks *_ecore_con_proxy_global;
282void ecore_con_socks_init(void);
283void ecore_con_socks_shutdown(void);
284Eina_Bool ecore_con_socks_svr_init(Ecore_Con_Server *svr);
285void ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num);
286void ecore_con_socks_dns_cb(const char *canonname, const char *ip, struct sockaddr *addr, int addrlen, Ecore_Con_Server *svr);
287/* from ecore_con.c */
288void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info);
289void ecore_con_event_proxy_bind(Ecore_Con_Server *svr);
290void ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate);
291void ecore_con_event_server_del(Ecore_Con_Server *svr);
292#define ecore_con_event_server_error(svr, error) _ecore_con_event_server_error((svr), (char*)(error), EINA_TRUE)
293void _ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate);
294void ecore_con_event_client_add(Ecore_Con_Client *cl);
295void ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate);
296void ecore_con_event_client_del(Ecore_Con_Client *cl);
297void ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error);
298void _ecore_con_server_kill(Ecore_Con_Server *svr);
299void _ecore_con_client_kill(Ecore_Con_Client *cl);
300/* from ecore_local_win32.c */
301#ifdef _WIN32
302Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr);
303Eina_Bool ecore_con_local_connect(Ecore_Con_Server *svr,
304 Eina_Bool (*cb_done)(void *data,
305 Ecore_Fd_Handler *fd_handler));
306Eina_Bool ecore_con_local_win32_server_flush(Ecore_Con_Server *svr);
307Eina_Bool ecore_con_local_win32_client_flush(Ecore_Con_Client *cl);
308void ecore_con_local_win32_server_del(Ecore_Con_Server *svr);
309void ecore_con_local_win32_client_del(Ecore_Con_Client *cl);
310#else
311/* from ecore_local.c */
312int ecore_con_local_init(void);
313int ecore_con_local_shutdown(void);
314int ecore_con_local_connect(Ecore_Con_Server *svr,
315 Eina_Bool (*cb_done)(
316 void *data,
317 Ecore_Fd_Handler *fd_handler),
318 void *data);
319int ecore_con_local_listen(Ecore_Con_Server *svr,
320 Eina_Bool (*cb_listen)(
321 void *data,
322 Ecore_Fd_Handler *fd_handler),
323 void *data);
324#endif
325
326/* from ecore_con_info.c */
327int ecore_con_info_init(void);
328int ecore_con_info_shutdown(void);
329int ecore_con_info_tcp_connect(Ecore_Con_Server *svr,
330 Ecore_Con_Info_Cb done_cb,
331 void *data);
332int ecore_con_info_tcp_listen(Ecore_Con_Server *svr,
333 Ecore_Con_Info_Cb done_cb,
334 void *data);
335int ecore_con_info_udp_connect(Ecore_Con_Server *svr,
336 Ecore_Con_Info_Cb done_cb,
337 void *data);
338int ecore_con_info_udp_listen(Ecore_Con_Server *svr,
339 Ecore_Con_Info_Cb done_cb,
340 void *data);
341int ecore_con_info_mcast_listen(Ecore_Con_Server *svr,
342 Ecore_Con_Info_Cb done_cb,
343 void *data);
344void ecore_con_info_data_clear(void *info);
345
346void ecore_con_event_server_add(Ecore_Con_Server *svr);
347
348
349/* from ecore_con_ssl.c */
350Ecore_Con_Ssl_Error ecore_con_ssl_init(void);
351Ecore_Con_Ssl_Error ecore_con_ssl_shutdown(void);
352Ecore_Con_Ssl_Error ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, int ssl_type);
353Ecore_Con_Ssl_Error ecore_con_ssl_server_init(Ecore_Con_Server *svr);
354Ecore_Con_Ssl_Error ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr);
355int ecore_con_ssl_server_read(Ecore_Con_Server *svr,
356 unsigned char *buf,
357 int size);
358int ecore_con_ssl_server_write(Ecore_Con_Server *svr,
359 const unsigned char *buf,
360 int size);
361Ecore_Con_Ssl_Error ecore_con_ssl_client_init(Ecore_Con_Client *svr);
362Ecore_Con_Ssl_Error ecore_con_ssl_client_shutdown(Ecore_Con_Client *svr);
363int ecore_con_ssl_client_read(Ecore_Con_Client *svr,
364 unsigned char *buf,
365 int size);
366int ecore_con_ssl_client_write(Ecore_Con_Client *svr,
367 const unsigned char *buf,
368 int size);
369
370int ecore_con_info_get(Ecore_Con_Server *svr,
371 Ecore_Con_Info_Cb done_cb,
372 void *data,
373 struct addrinfo *hints);
374
375
376#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \
377 TYPE *Type##_alloc(void); \
378 void Type##_free(TYPE *e);
379
380GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Add, ecore_con_event_client_add);
381GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Del, ecore_con_event_client_del);
382GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Write, ecore_con_event_client_write);
383GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Data, ecore_con_event_client_data);
384GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Error, ecore_con_event_server_error);
385GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Error, ecore_con_event_client_error);
386GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Add, ecore_con_event_server_add);
387GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Del, ecore_con_event_server_del);
388GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Write, ecore_con_event_server_write);
389GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Data, ecore_con_event_server_data);
390GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind);
391
392void ecore_con_mempool_init(void);
393void ecore_con_mempool_shutdown(void);
394
395#undef GENERIC_ALLOC_FREE_HEADER
396
397#endif
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_socks.c b/libraries/ecore/src/lib/ecore_con/ecore_con_socks.c
deleted file mode 100644
index 686f73b..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_socks.c
+++ /dev/null
@@ -1,940 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <string.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <errno.h>
10#include <unistd.h>
11#include <fcntl.h>
12
13#ifdef HAVE_SYS_SOCKET_H
14# include <sys/socket.h>
15#endif
16
17#ifdef HAVE_NETINET_TCP_H
18# include <netinet/tcp.h>
19#endif
20
21#ifdef HAVE_NET_IF_H
22# include <net/if.h>
23#endif
24
25/* if net/if.h is not found or if an older versions of net/if.h is provided
26 which does not define IF_NAMESIZE. We must define it ourselves */
27#ifndef IF_NAMESIZE
28# ifdef IFNAMSIZ
29# define IF_NAMESIZE IFNAMSIZ
30# else
31# define IF_NAMESIZE 16
32# endif
33#endif
34
35#ifdef HAVE_NETINET_IN_H
36# include <netinet/in.h>
37#endif
38
39#ifdef HAVE_ARPA_INET_H
40# include <arpa/inet.h>
41#endif
42
43#ifdef HAVE_SYS_UN_H
44# include <sys/un.h>
45#endif
46
47#ifdef HAVE_WS2TCPIP_H
48# include <ws2tcpip.h>
49#endif
50
51#ifdef HAVE_EVIL
52# include <Evil.h>
53#endif
54
55#include "Ecore.h"
56#include "ecore_private.h"
57#include "Ecore_Con.h"
58#include "ecore_con_private.h"
59
60/* http://tools.ietf.org/html/rfc1928
61 o X'00' NO AUTHENTICATION REQUIRED
62 o X'01' GSSAPI
63 o X'02' USERNAME/PASSWORD
64 o X'03' to X'7F' IANA ASSIGNED
65 o X'80' to X'FE' RESERVED FOR PRIVATE METHODS
66 o X'FF' NO ACCEPTABLE METHODS
67*/
68#define ECORE_CON_SOCKS_V5_METHOD_NONE 0
69#define ECORE_CON_SOCKS_V5_METHOD_GSSAPI 1
70#define ECORE_CON_SOCKS_V5_METHOD_USERPASS 2
71
72static int ECORE_CON_SOCKS_V5_METHODS[] =
73{
74 ECORE_CON_SOCKS_V5_METHOD_NONE,
75// ECORE_CON_SOCKS_V5_METHOD_GSSAPI, TODO
76 ECORE_CON_SOCKS_V5_METHOD_USERPASS
77};
78
79#define ECORE_CON_SOCKS_V5_TOTAL_METHODS sizeof(ECORE_CON_SOCKS_V5_METHODS)
80
81#define _ecore_con_server_kill(svr) do { \
82 DBG("KILL %p", (svr)); \
83 _ecore_con_server_kill((svr)); \
84} while (0)
85
86Eina_List *ecore_con_socks_proxies = NULL;
87
88static Ecore_Con_Socks *
89_ecore_con_socks_find(unsigned char version, const char *ip, int port, const char *username, size_t ulen, const char *password, size_t plen)
90{
91 Eina_List *l;
92 Ecore_Con_Socks_v5 *ecs;
93
94 if (!ecore_con_socks_proxies) return NULL;
95
96 EINA_LIST_FOREACH(ecore_con_socks_proxies, l, ecs)
97 {
98 if (ecs->version != version) continue;
99 if (strcmp(ecs->ip, ip)) continue;
100 if ((port != -1) && (port != ecs->port)) continue;
101 if (ulen != ecs->ulen) continue;
102 if (username && strcmp(ecs->username, username)) continue;
103 if (version == 5)
104 {
105 if (plen != ecs->plen) continue;
106 if (password && strcmp(ecs->password, password)) continue;
107 }
108 return (Ecore_Con_Socks*)ecs;
109 }
110 return NULL;
111}
112
113static void
114_ecore_con_socks_free(Ecore_Con_Socks *ecs)
115{
116 ECORE_CON_SOCKS_CAST_ELSE(ecs) return;
117
118 if (_ecore_con_proxy_once == ecs) _ecore_con_proxy_once = NULL;
119 if (_ecore_con_proxy_global == ecs) _ecore_con_proxy_global = NULL;
120 eina_stringshare_del(ecs->ip);
121 eina_stringshare_del(ecs->username);
122 free(ecs);
123}
124
125static Eina_Bool
126_ecore_con_socks_svr_init_v4(Ecore_Con_Server *svr, Ecore_Con_Socks_v4 *v4)
127{
128 size_t addrlen, buflen, ulen = 1;
129 unsigned char *sbuf;
130
131 addrlen = v4->lookup ? strlen(svr->name) + 1 : 0;
132 if (v4->username) ulen += v4->ulen;
133 buflen = sizeof(char) * (8 + ulen + addrlen);
134 sbuf = malloc(buflen);
135 if (!sbuf)
136 {
137 ecore_con_event_server_error(svr, "Memory allocation failure!");
138 _ecore_con_server_kill(svr);
139 return EINA_FALSE;
140 }
141 /* http://en.wikipedia.org/wiki/SOCKS */
142 sbuf[0] = 4;
143 sbuf[1] = v4->bind ? 2 : 1;
144 sbuf[2] = svr->port >> 8;
145 sbuf[3] = svr->port & 0xff;
146 if (addrlen)
147 {
148 sbuf[4] = sbuf[5] = sbuf[6] = 0;
149 sbuf[7] = 1;
150 }
151 else
152 /* SOCKSv4 only handles IPV4, so addrlen is always 4 */
153 memcpy(sbuf + 4, svr->ecs_addr, 4);
154 if (v4->username)
155 memcpy(sbuf + 8, v4->username, ulen);
156 else
157 sbuf[8] = 0;
158 if (addrlen) memcpy(sbuf + 8 + ulen, svr->name, addrlen);
159
160 svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen);
161 return EINA_TRUE;
162}
163
164static Eina_Bool
165_ecore_con_socks_svr_init_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5)
166{
167 size_t buflen;
168 unsigned int x;
169 unsigned char *sbuf;
170
171 if (v5->username)
172 buflen = sizeof(char) * (2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS);
173 else
174 buflen = 3;
175 sbuf = malloc(buflen);
176 if (!sbuf)
177 {
178 ecore_con_event_server_error(svr, "Memory allocation failure!");
179 _ecore_con_server_kill(svr);
180 return EINA_FALSE;
181 }
182 /* http://en.wikipedia.org/wiki/SOCKS
183 * http://tools.ietf.org/html/rfc1928
184 */
185 sbuf[0] = 5;
186 if (v5->username)
187 {
188 sbuf[1] = ECORE_CON_SOCKS_V5_TOTAL_METHODS;
189 for (x = 2; x < 2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS; x++)
190 sbuf[x] = ECORE_CON_SOCKS_V5_METHODS[x - 2];
191 }
192 else
193 {
194 sbuf[1] = 1;
195 sbuf[2] = ECORE_CON_SOCKS_V5_METHOD_NONE;
196 }
197
198 svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen);
199 return EINA_TRUE;
200}
201
202#define ECORE_CON_SOCKS_READ(EXACT) \
203 if (num < EXACT) \
204 { \
205 if (!svr->ecs_recvbuf) svr->ecs_recvbuf = eina_binbuf_new(); \
206 if (!svr->ecs_recvbuf) goto error; \
207 eina_binbuf_append_length(svr->ecs_recvbuf, buf, num); \
208 /* the slowest connection on earth */ \
209 if (eina_binbuf_length_get(svr->ecs_recvbuf) != EXACT) return; \
210 data = eina_binbuf_string_get(svr->ecs_recvbuf); \
211 } \
212 else if (num > EXACT) goto error; \
213 else \
214 data = buf
215
216static void
217_ecore_con_socks_read_v4(Ecore_Con_Server *svr, Ecore_Con_Socks_v4 *v4 __UNUSED__, const unsigned char *buf, unsigned int num)
218{
219 const unsigned char *data;
220 DBG("SOCKS: %d bytes", num);
221 ECORE_CON_SOCKS_READ(8);
222
223/* http://ufasoft.com/doc/socks4_protocol.htm */
224 if (data[0]) goto error;
225 switch (data[1])
226 {
227 case 90:
228 /* success! */
229 break;
230 case 91:
231 ecore_con_event_server_error(svr, "proxy request rejected or failed");
232 goto error;
233 case 92:
234 ecore_con_event_server_error(svr, "proxying SOCKS server could not perform authentication");
235 goto error;
236 case 93:
237 ecore_con_event_server_error(svr, "proxy request authentication rejected");
238 goto error;
239 default:
240 ecore_con_event_server_error(svr, "garbage data from proxy");
241 goto error;
242 }
243 if (svr->ecs->bind)
244 {
245 unsigned int nport;
246 char naddr[IF_NAMESIZE];
247
248 memcpy(&nport, &data[2], 2);
249 svr->proxyport = ntohl(nport);
250
251 if (!inet_ntop(AF_INET, &data[4], naddr, sizeof(naddr))) goto error;
252 svr->proxyip = eina_stringshare_add(naddr);
253 ecore_con_event_proxy_bind(svr);
254 }
255 svr->ecs_state = ECORE_CON_PROXY_STATE_DONE;
256 INF("PROXY CONNECTED");
257 if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
258 svr->ecs_recvbuf = NULL;
259 svr->ecs_buf_offset = svr->ecs_addrlen = 0;
260 memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr));
261 if (!svr->ssl_state)
262 ecore_con_event_server_add(svr);
263 if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf)))
264 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
265 return;
266error:
267 _ecore_con_server_kill(svr);
268}
269
270static Eina_Bool
271_ecore_con_socks_auth_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5)
272{
273 size_t size;
274 unsigned char *data;
275 switch (v5->method)
276 {
277 case ECORE_CON_SOCKS_V5_METHOD_NONE:
278 svr->ecs_state = ECORE_CON_PROXY_STATE_REQUEST;
279 return EINA_TRUE;
280 case ECORE_CON_SOCKS_V5_METHOD_GSSAPI:
281 return EINA_TRUE;
282 case ECORE_CON_SOCKS_V5_METHOD_USERPASS:
283 if (!v5->username) return EINA_FALSE;
284 if (!v5->password) v5->plen = 1;
285 /* http://tools.ietf.org/html/rfc1929 */
286 size = sizeof(char) * (3 + v5->ulen + v5->plen);
287 data = malloc(size);
288 if (!data) break;
289 data[0] = 1;
290 data[1] = v5->ulen;
291 memcpy(&data[2], v5->username, v5->ulen);
292 data[1 + v5->ulen] = v5->plen;
293 if (v5->password)
294 memcpy(&data[2 + v5->ulen], v5->password, v5->plen);
295 else
296 data[2 + v5->ulen] = 0;
297 svr->ecs_buf = eina_binbuf_manage_new_length(data, size);
298 return EINA_TRUE;
299 default:
300 break;
301 }
302 return EINA_FALSE;
303}
304
305static void
306_ecore_con_socks_read_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5, const unsigned char *buf, unsigned int num)
307{
308 const unsigned char *data;
309
310 DBG("SOCKS: %d bytes", num);
311 switch (svr->ecs_state)
312 {
313
314 case ECORE_CON_PROXY_STATE_READ:
315 ECORE_CON_SOCKS_READ(2);
316 /* http://en.wikipedia.org/wiki/SOCKS */
317 if (data[0] != 5) goto error;
318 if (data[1] == 0xFF)
319 {
320 ecore_con_event_server_error(svr, "proxy authentication methods rejected");
321 goto error;
322 }
323 v5->method = data[1];
324 if (!_ecore_con_socks_auth_v5(svr, v5)) goto error;
325 if (svr->ecs_state == ECORE_CON_PROXY_STATE_REQUEST)
326 {
327 /* run again to skip auth reading */
328 _ecore_con_socks_read_v5(svr, v5, NULL, 0);
329 return;
330 }
331 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
332 svr->ecs_state = ECORE_CON_PROXY_STATE_AUTH;
333 break;
334 case ECORE_CON_PROXY_STATE_AUTH:
335 ECORE_CON_SOCKS_READ(2);
336 switch (v5->method)
337 {
338 case ECORE_CON_SOCKS_V5_METHOD_NONE:
339 CRIT("HOW DID THIS HAPPEN?????????");
340 goto error;
341 case ECORE_CON_SOCKS_V5_METHOD_GSSAPI:
342 /* TODO: this */
343 break;
344 case ECORE_CON_SOCKS_V5_METHOD_USERPASS:
345 if (data[0] != 1)
346 {
347 ecore_con_event_server_error(svr, "protocol error");
348 goto error; /* wrong version */
349 }
350 if (data[1])
351 {
352 ecore_con_event_server_error(svr, "proxy request authentication rejected");
353 goto error;
354 }
355 default:
356 break;
357 }
358 case ECORE_CON_PROXY_STATE_REQUEST:
359 {
360 size_t addrlen, buflen;
361 unsigned char *sbuf;
362 addrlen = v5->lookup ? strlen(svr->name) + 1 : (unsigned int)svr->ecs_addrlen;
363 buflen = sizeof(char) * (6 + addrlen);
364 sbuf = malloc(buflen);
365 if (!sbuf)
366 {
367 ecore_con_event_server_error(svr, "Memory allocation failure!");
368 goto error;
369 }
370 sbuf[0] = 5;
371 sbuf[1] = v5->bind ? 2 : 1; /* TODO: 0x03 for UDP port association */
372 sbuf[2] = 0;
373 if (v5->lookup) /* domain name */
374 {
375 sbuf[3] = 3;
376 sbuf[4] = addrlen - 1;
377 memcpy(sbuf + 5, svr->name, addrlen - 1);
378 }
379 else
380 {
381 sbuf[3] = (svr->ecs_addrlen == 4) ? 1 : 4;
382 memcpy(sbuf + 4, svr->ecs_addr, addrlen);
383 }
384 sbuf[addrlen + 4] = svr->port >> 8;
385 sbuf[addrlen + 5] = svr->port & 0xff;
386
387 svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen);
388 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
389 break;
390 }
391 case ECORE_CON_PROXY_STATE_CONFIRM:
392 {
393 /* this is ugly because we have to read an exact number of bytes,
394 * but we don't know what that number is until we've already read
395 * at least 5 bytes to determine the length of the unknown stream.
396 * yep.
397 */
398 size_t to_read, len = svr->ecs_recvbuf ? eina_binbuf_length_get(svr->ecs_recvbuf) : 0;
399 if (num + len < 5)
400 {
401 /* guarantees we get called again */
402 ECORE_CON_SOCKS_READ(5);
403 }
404 if (len >= 5)
405 {
406 data = eina_binbuf_string_get(svr->ecs_recvbuf);
407 data += 3;
408 }
409 else
410 data = buf + 3 - len;
411 switch (data[0])
412 {
413 case 1:
414 to_read = 4;
415 break;
416 case 3:
417 to_read = data[1] + 1;
418 break;
419 case 4:
420 to_read = 16;
421 /* lazy debugging stub comment */
422 break;
423 default:
424 ecore_con_event_server_error(svr, "protocol error");
425 goto error;
426 }
427 /* at this point, we finally know exactly how much we need to read */
428 ECORE_CON_SOCKS_READ(6 + to_read);
429
430 if (data[0] != 5)
431 {
432 ecore_con_event_server_error(svr, "protocol error");
433 goto error; /* wrong version */
434 }
435 switch (data[1])
436 {
437 case 0:
438 break;
439 case 1:
440 ecore_con_event_server_error(svr, "general proxy failure");
441 goto error;
442 case 2:
443 ecore_con_event_server_error(svr, "connection not allowed by ruleset");
444 goto error;
445 case 3:
446 ecore_con_event_server_error(svr, "network unreachable");
447 goto error;
448 case 4:
449 ecore_con_event_server_error(svr, "host unreachable");
450 goto error;
451 case 5:
452 ecore_con_event_server_error(svr, "connection refused by destination host");
453 goto error;
454 case 6:
455 ecore_con_event_server_error(svr, "TTL expired");
456 goto error;
457 case 7:
458 ecore_con_event_server_error(svr, "command not supported / protocol error");
459 goto error;
460 case 8:
461 ecore_con_event_server_error(svr, "address type not supported");
462 default:
463 goto error;
464 }
465 if (data[2])
466 {
467 ecore_con_event_server_error(svr, "protocol error");
468 goto error;
469 }
470 memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr));
471 if (!svr->ssl_state)
472 ecore_con_event_server_add(svr);
473 if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf)))
474 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
475 svr->ecs_buf_offset = svr->ecs_addrlen = 0;
476 svr->ecs_state = ECORE_CON_PROXY_STATE_DONE;
477 INF("PROXY CONNECTED");
478 break;
479 }
480 default:
481 break;
482 }
483 if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
484 svr->ecs_recvbuf = NULL;
485
486 return;
487error:
488 _ecore_con_server_kill(svr);
489}
490
491/////////////////////////////////////////////////////////////////////////////////////
492void
493ecore_con_socks_shutdown(void)
494{
495 Ecore_Con_Socks *ecs;
496 EINA_LIST_FREE(ecore_con_socks_proxies, ecs)
497 _ecore_con_socks_free(ecs);
498 _ecore_con_proxy_once = NULL;
499 _ecore_con_proxy_global = NULL;
500}
501
502void
503ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num)
504{
505 ECORE_CON_SOCKS_CAST_ELSE(svr->ecs) return;
506
507 if (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) return;
508
509 if (v4) _ecore_con_socks_read_v4(svr, v4, buf, (unsigned int)num);
510 else _ecore_con_socks_read_v5(svr, v5, buf, (unsigned int)num);
511}
512
513Eina_Bool
514ecore_con_socks_svr_init(Ecore_Con_Server *svr)
515{
516 ECORE_CON_SOCKS_CAST_ELSE(svr->ecs) return EINA_FALSE;
517
518 if (!svr->ip) return EINA_FALSE;
519 if (svr->ecs_buf) return EINA_FALSE;
520 if (svr->ecs_state != ECORE_CON_PROXY_STATE_INIT) return EINA_FALSE;
521 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
522 if (v4) return _ecore_con_socks_svr_init_v4(svr, v4);
523 return _ecore_con_socks_svr_init_v5(svr, v5);
524}
525
526void
527ecore_con_socks_dns_cb(const char *canonname __UNUSED__, const char *ip, struct sockaddr *addr, int addrlen __UNUSED__, Ecore_Con_Server *svr)
528{
529 svr->ip = eina_stringshare_add(ip);
530 svr->ecs_state++;
531 if (addr->sa_family == AF_INET)
532 {
533 memcpy(svr->ecs_addr, &((struct sockaddr_in *)addr)->sin_addr.s_addr, 4);
534 svr->ecs_addrlen = 4;
535 }
536#ifdef HAVE_IPV6
537 else
538 {
539 memcpy(svr->ecs_addr, &((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, 16);
540 svr->ecs_addrlen = 16;
541 }
542#endif
543 ecore_con_socks_svr_init(svr);
544}
545
546void
547ecore_con_socks_init(void)
548{
549 const char *socks;
550 char *h, *p, *l, *u = NULL;
551 char buf[512];
552 int port, lookup = 0;
553 Eina_Bool v5 = EINA_FALSE;
554 Ecore_Con_Socks *ecs;
555 unsigned char addr[sizeof(struct in_addr)];
556#ifdef HAVE_IPV6
557 unsigned char addr6[sizeof(struct in6_addr)];
558#endif
559
560 /* ECORE_CON_SOCKS_V4=[user@]host:port-[1|0] */
561 socks = getenv("ECORE_CON_SOCKS_V4");
562 if (!socks)
563 {
564 /* ECORE_CON_SOCKS_V5=[user@]host-port:[1|0] */
565 socks = getenv("ECORE_CON_SOCKS_V5");
566 v5 = EINA_TRUE;
567 }
568 if ((!socks) || (!socks[0]) || (strlen(socks) > 512)) return;
569 strncpy(buf, socks, sizeof(buf));
570 h = strchr(buf, '@');
571 /* username */
572 if (h && (h - buf > 0)) *h++ = 0, u = buf;
573 else h = buf;
574
575 /* host ip; I ain't resolvin shit here */
576 p = strchr(h, '-');
577 if (!p) return;
578 *p++ = 0;
579 if (!inet_pton(AF_INET, h, addr))
580#ifdef HAVE_IPV6
581 {
582 if (!v5) return;
583 if (!inet_pton(AF_INET6, h, addr6))
584 return;
585 }
586#else
587 return;
588#endif
589
590 errno = 0;
591 port = strtol(p, &l, 10);
592 if (errno || (port < 0) || (port > 65535)) return;
593 if (l && (l[0] == ':'))
594 lookup = (l[1] == '1');
595 if (v5)
596 ecs = ecore_con_socks5_remote_add(h, port, u, NULL);
597 else
598 ecs = ecore_con_socks4_remote_add(h, port, u);
599 if (!ecs) return;
600 ecore_con_socks_lookup_set(ecs, lookup);
601 ecore_con_socks_apply_always(ecs);
602 INF("Added global proxy server %s%s%s:%d - DNS lookup %s",
603 u ?: "", u ? "@" : "", h, port, lookup ? "ENABLED" : "DISABLED");
604}
605
606/////////////////////////////////////////////////////////////////////////////////////
607
608/**
609 * @defgroup Ecore_Con_Socks_Group Ecore Connection SOCKS functions
610 * @{
611 */
612
613/**
614 * Add a SOCKS v4 proxy to the proxy list
615 *
616 * Use this to create (or return, if previously added) a SOCKS proxy
617 * object which can be used by any ecore_con servers.
618 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
619 * @param port The port to connect to on the proxy
620 * @param username The username to use for the proxy (OPTIONAL)
621 * @return An allocated proxy object, or NULL on failure
622 * @note This object NEVER needs to be explicitly freed.
623 * @since 1.2
624 */
625EAPI Ecore_Con_Socks *
626ecore_con_socks4_remote_add(const char *ip, int port, const char *username)
627{
628 Ecore_Con_Socks *ecs;
629 size_t ulen = 0;
630
631 if ((!ip) || (!ip[0]) || (port < 0) || (port > 65535)) return NULL;
632
633 if (username)
634 {
635 ulen = strlen(username);
636 /* max length for protocol */
637 if ((!ulen) || (ulen > 255)) return NULL;
638 }
639 ecs = _ecore_con_socks_find(4, ip, port, username, ulen, NULL, 0);
640 if (ecs) return ecs;
641
642 ecs = calloc(1, sizeof(Ecore_Con_Socks_v4));
643 if (!ecs) return NULL;
644
645 ecs->version = 4;
646 ecs->ip = eina_stringshare_add(ip);
647 ecs->port = port;
648 ecs->username = eina_stringshare_add(username);
649 ecs->ulen = ulen;
650 ecore_con_socks_proxies = eina_list_append(ecore_con_socks_proxies, ecs);
651 return ecs;
652}
653
654/**
655 * Find a SOCKS v4 proxy in the proxy list
656 *
657 * Use this to determine if a SOCKS proxy was previously added by checking
658 * the proxy list against the parameters given.
659 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
660 * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip
661 * @param username The username used for the proxy (OPTIONAL)
662 * @return true only if a proxy exists matching the given params
663 * @note This function matches slightly more loosely than ecore_con_socks4_remote_add(), and
664 * ecore_con_socks4_remote_add() should be used to return the actual object.
665 * @since 1.2
666 */
667EAPI Eina_Bool
668ecore_con_socks4_remote_exists(const char *ip, int port, const char *username)
669{
670 if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])))
671 return EINA_FALSE;
672 return !!_ecore_con_socks_find(4, ip, port, username, username ? strlen(username) : 0, NULL, 0);
673}
674
675/**
676 * Remove a SOCKS v4 proxy from the proxy list and delete it
677 *
678 * Use this to remove a SOCKS proxy from the proxy list by checking
679 * the list against the parameters given. The proxy will then be deleted.
680 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
681 * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip
682 * @param username The username used for the proxy (OPTIONAL)
683 * @note This function matches in the same way as ecore_con_socks4_remote_exists().
684 * @warning Be aware that deleting a proxy which is being used WILL ruin your life.
685 * @since 1.2
686 */
687EAPI void
688ecore_con_socks4_remote_del(const char *ip, int port, const char *username)
689{
690 Ecore_Con_Socks_v4 *v4;
691
692 if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0]))) return;
693 if (!ecore_con_socks_proxies) return;
694
695 v4 = (Ecore_Con_Socks_v4*)_ecore_con_socks_find(4, ip, port, username, username ? strlen(username) : 0, NULL, 0);
696 if (!v4) return;
697 ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, v4);
698 _ecore_con_socks_free((Ecore_Con_Socks*)v4);
699}
700/**
701 * Add a SOCKS v5 proxy to the proxy list
702 *
703 * Use this to create (or return, if previously added) a SOCKS proxy
704 * object which can be used by any ecore_con servers.
705 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
706 * @param port The port to connect to on the proxy
707 * @param username The username to use for the proxy (OPTIONAL)
708 * @param password The password to use for the proxy (OPTIONAL)
709 * @return An allocated proxy object, or NULL on failure
710 * @note This object NEVER needs to be explicitly freed.
711 * @since 1.2
712 */
713EAPI Ecore_Con_Socks *
714ecore_con_socks5_remote_add(const char *ip, int port, const char *username, const char *password)
715{
716 Ecore_Con_Socks_v5 *ecs5;
717 size_t ulen = 0, plen = 0;
718
719 if ((!ip) || (!ip[0]) || (port < 0) || (port > 65535)) return NULL;
720
721 if (username)
722 {
723 ulen = strlen(username);
724 /* max length for protocol */
725 if ((!ulen) || (ulen > 255)) return NULL;
726 }
727 if (password)
728 {
729 plen = strlen(password);
730 /* max length for protocol */
731 if ((!plen) || (plen > 255)) return NULL;
732 }
733 ecs5 = (Ecore_Con_Socks_v5*)_ecore_con_socks_find(5, ip, port, username, ulen, password, plen);
734 if (ecs5) return (Ecore_Con_Socks*)ecs5;
735
736 ecs5 = calloc(1, sizeof(Ecore_Con_Socks_v5));
737 if (!ecs5) return NULL;
738
739 ecs5->version = 5;
740 ecs5->ip = eina_stringshare_add(ip);
741 ecs5->port = port;
742 ecs5->username = eina_stringshare_add(username);
743 ecs5->ulen = ulen;
744 ecs5->password = eina_stringshare_add(password);
745 ecs5->plen = plen;
746 ecore_con_socks_proxies = eina_list_append(ecore_con_socks_proxies, ecs5);
747 return (Ecore_Con_Socks*)ecs5;
748}
749
750/**
751 * Find a SOCKS v5 proxy in the proxy list
752 *
753 * Use this to determine if a SOCKS proxy was previously added by checking
754 * the proxy list against the parameters given.
755 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
756 * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip
757 * @param username The username used for the proxy (OPTIONAL)
758 * @param password The password used for the proxy (OPTIONAL)
759 * @return true only if a proxy exists matching the given params
760 * @note This function matches slightly more loosely than ecore_con_socks5_remote_add(), and
761 * ecore_con_socks5_remote_add() should be used to return the actual object.
762 * @since 1.2
763 */
764EAPI Eina_Bool
765ecore_con_socks5_remote_exists(const char *ip, int port, const char *username, const char *password)
766{
767 if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])) || (password && (!password[0])))
768 return EINA_FALSE;
769 return !!_ecore_con_socks_find(5, ip, port, username, username ? strlen(username) : 0, password, password ? strlen(password) : 0);
770}
771
772/**
773 * Remove a SOCKS v5 proxy from the proxy list and delete it
774 *
775 * Use this to remove a SOCKS proxy from the proxy list by checking
776 * the list against the parameters given. The proxy will then be deleted.
777 * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.)
778 * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip
779 * @param username The username used for the proxy (OPTIONAL)
780 * @param password The password used for the proxy (OPTIONAL)
781 * @note This function matches in the same way as ecore_con_socks4_remote_exists().
782 * @warning Be aware that deleting a proxy which is being used WILL ruin your life.
783 * @since 1.2
784 */
785EAPI void
786ecore_con_socks5_remote_del(const char *ip, int port, const char *username, const char *password)
787{
788 Ecore_Con_Socks_v5 *v5;
789
790 if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])) || (password && (!password[0])))
791 return;
792 if (!ecore_con_socks_proxies) return;
793
794 v5 = (Ecore_Con_Socks_v5*)_ecore_con_socks_find(5, ip, port, username, username ? strlen(username) : 0, password, password ? strlen(password) : 0);
795 if (!v5) return;
796 ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, v5);
797 _ecore_con_socks_free((Ecore_Con_Socks*)v5);
798}
799
800/**
801 * Set DNS lookup mode on an existing SOCKS proxy
802 *
803 * According to RFC, SOCKS v4 does not require that a proxy perform
804 * its own DNS lookups for addresses. SOCKS v4a specifies the protocol
805 * for this. SOCKS v5 allows DNS lookups.
806 * If you want to enable remote DNS lookup and are sure that your
807 * proxy supports it, use this function.
808 * @param ecs The proxy object
809 * @param enable If true, the proxy will perform the dns lookup
810 * @note By default, this setting is DISABLED.
811 * @since 1.2
812 */
813EAPI void
814ecore_con_socks_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable)
815{
816 ECORE_CON_SOCKS_CAST_ELSE(ecs) return;
817 ecs->lookup = !!enable;
818}
819
820/**
821 * Get DNS lookup mode on an existing SOCKS proxy
822 *
823 * According to RFC, SOCKS v4 does not require that a proxy perform
824 * its own DNS lookups for addresses. SOCKS v4a specifies the protocol
825 * for this. SOCKS v5 allows DNS lookups.
826 * This function returns whether lookups are enabled on a proxy object.
827 * @param ecs The proxy object
828 * @return If true, the proxy will perform the dns lookup
829 * @note By default, this setting is DISABLED.
830 * @since 1.2
831 */
832EAPI Eina_Bool
833ecore_con_socks_lookup_get(Ecore_Con_Socks *ecs)
834{
835 ECORE_CON_SOCKS_CAST_ELSE(ecs) return EINA_FALSE;
836 return ecs->lookup;
837}
838
839/**
840 * Enable bind mode on a SOCKS proxy
841 *
842 * Use this function to enable binding a remote port for use with a remote server.
843 * For more information, see http://ufasoft.com/doc/socks4_protocol.htm
844 * @param ecs The proxy object
845 * @param is_bind If true, the connection established will be a port binding
846 * @warning Be aware that changing the operation mode of an active proxy may result in undefined behavior
847 * @since 1.2
848 */
849EAPI void
850ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind)
851{
852 EINA_SAFETY_ON_NULL_RETURN(ecs);
853 ecs->bind = !!is_bind;
854}
855
856/**
857 * Return bind mode of a SOCKS proxy
858 *
859 * Use this function to return bind mode of a proxy (binding a remote port for use with a remote server).
860 * For more information, see http://ufasoft.com/doc/socks4_protocol.htm
861 * @param ecs The proxy object
862 * @return If true, the connection established will be a port binding
863 * @since 1.2
864 */
865EAPI Eina_Bool
866ecore_con_socks_bind_get(Ecore_Con_Socks *ecs)
867{
868 EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, EINA_FALSE);
869 return ecs->bind;
870}
871
872/**
873 * Return SOCKS version of a SOCKS proxy
874 *
875 * Use this function to return the SOCKS protocol version of a proxy
876 * @param ecs The proxy object
877 * @return 0 on error, else 4/5
878 * @since 1.2
879 */
880EAPI unsigned int
881ecore_con_socks_version_get(Ecore_Con_Socks *ecs)
882{
883 EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, 0);
884 return ecs->version;
885}
886
887/**
888 * Remove a SOCKS v4 proxy from the proxy list and delete it
889 *
890 * Use this to remove a SOCKS proxy from the proxy list by directly deleting the object given.
891 * @param ecs The proxy object to delete
892 * @warning Be aware that deleting a proxy which is being used WILL ruin your life.
893 * @since 1.2
894 */
895EAPI void
896ecore_con_socks_remote_del(Ecore_Con_Socks *ecs)
897{
898 EINA_SAFETY_ON_NULL_RETURN(ecs);
899 if (!ecore_con_socks_proxies) return;
900
901 ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, ecs);
902 _ecore_con_socks_free(ecs);
903}
904
905/**
906 * Set a proxy object to be used with the next server created with ecore_con_server_connect()
907 *
908 * This function sets a proxy for the next ecore_con connection. After the next server is created,
909 * the proxy will NEVER be applied again unless explicitly enabled.
910 * @param ecs The proxy object
911 * @see ecore_con_socks_apply_always()
912 * @since 1.2
913 */
914EAPI void
915ecore_con_socks_apply_once(Ecore_Con_Socks *ecs)
916{
917 _ecore_con_proxy_once = ecs;
918}
919
920/**
921 * Set a proxy object to be used with all servers created with ecore_con_server_connect()
922 *
923 * This function sets a proxy for all ecore_con connections. It will always be used.
924 * @param ecs The proxy object
925 * @see ecore_con_socks_apply_once()
926 * @since 1.2
927 * @note ecore-con supports setting this through environment variables like so:
928 * ECORE_CON_SOCKS_V4=[user@]server-port:lookup
929 * ECORE_CON_SOCKS_V5=[user@]server-port:lookup
930 * user is the OPTIONAL string that would be passed to the proxy as the username
931 * server is the IP_ADDRESS of the proxy server
932 * port is the port to connect to on the proxy server
933 * lookup is 1 if the proxy should perform all DNS lookups, otherwise 0 or omitted
934 */
935EAPI void
936ecore_con_socks_apply_always(Ecore_Con_Socks *ecs)
937{
938 _ecore_con_proxy_global = ecs;
939}
940/** @} */
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c b/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c
deleted file mode 100644
index cd8b9c6..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c
+++ /dev/null
@@ -1,2113 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#if USE_GNUTLS
6# include <gnutls/gnutls.h>
7# include <gnutls/x509.h>
8# include <gcrypt.h>
9#elif USE_OPENSSL
10# include <openssl/ssl.h>
11# include <openssl/err.h>
12# include <openssl/dh.h>
13#endif
14
15#ifdef HAVE_WS2TCPIP_H
16# include <ws2tcpip.h>
17#endif
18
19#include <sys/stat.h>
20#include "Ecore.h"
21#include "ecore_con_private.h"
22
23EAPI int ECORE_CON_EVENT_CLIENT_UPGRADE = 0;
24EAPI int ECORE_CON_EVENT_SERVER_UPGRADE = 0;
25
26static int _init_con_ssl_init_count = 0;
27
28#ifdef USE_GNUTLS
29# ifdef EINA_HAVE_THREADS
30GCRY_THREAD_OPTION_PTHREAD_IMPL;
31# endif
32
33static int _client_connected = 0;
34
35# define SSL_SUFFIX(ssl_func) ssl_func ## _gnutls
36# define _ECORE_CON_SSL_AVAILABLE 1
37
38#elif USE_OPENSSL
39
40# define SSL_SUFFIX(ssl_func) ssl_func ## _openssl
41# define _ECORE_CON_SSL_AVAILABLE 2
42
43#else
44# define SSL_SUFFIX(ssl_func) ssl_func ## _none
45# define _ECORE_CON_SSL_AVAILABLE 0
46
47#endif
48
49#if USE_GNUTLS
50static void
51_gnutls_print_errors(void *conn, int type, int ret)
52{
53 char buf[1024];
54
55 if (!ret) return;
56
57 snprintf(buf, sizeof(buf), "GNUTLS error: %s - %s", gnutls_strerror_name(ret), gnutls_strerror(ret));
58 if (type == ECORE_CON_EVENT_CLIENT_ERROR)
59 ecore_con_event_client_error(conn, buf);
60 else
61 ecore_con_event_server_error(conn, buf);
62}
63
64static void
65_gnutls_print_session(const gnutls_datum_t *cert_list, unsigned int cert_list_size)
66{
67 char *c = NULL;
68 gnutls_x509_crt_t crt;
69 unsigned int x;
70
71 if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return;
72 for (x = 0; x < cert_list_size; x++)
73 {
74 gnutls_x509_crt_init(&crt);
75 gnutls_x509_crt_import(crt, &cert_list[x], GNUTLS_X509_FMT_DER);
76 gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, (gnutls_datum_t*)&c);
77 INF("CERTIFICATE:\n%s", c);
78 gnutls_free(c);
79 gnutls_x509_crt_deinit(crt);
80 crt = NULL;
81 }
82}
83
84#ifdef ISCOMFITOR
85static void
86_gnutls_log_func(int level,
87 const char *str)
88{
89 char buf[128];
90 strncat(buf, str, strlen(str) - 1);
91 DBG("|<%d>| %s", level, buf);
92}
93#endif
94
95static const char *
96SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status)
97{
98 switch (status)
99 {
100 case GNUTLS_HANDSHAKE_HELLO_REQUEST:
101 return "Hello request";
102
103 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
104 return "Client hello";
105
106 case GNUTLS_HANDSHAKE_SERVER_HELLO:
107 return "Server hello";
108
109 case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
110 return "New session ticket";
111
112 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
113 return "Certificate packet";
114
115 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
116 return "Server key exchange";
117
118 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
119 return "Certificate request";
120
121 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
122 return "Server hello done";
123
124 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
125 return "Certificate verify";
126
127 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
128 return "Client key exchange";
129
130 case GNUTLS_HANDSHAKE_FINISHED:
131 return "Finished";
132
133 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
134 return "Supplemental";
135 }
136 return NULL;
137}
138
139#elif USE_OPENSSL
140
141static void
142_openssl_print_verify_error(int error)
143{
144 switch (error)
145 {
146#define ERROR(X) \
147 case (X): \
148 ERR("%s", #X); \
149 break
150#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
151 ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT);
152#endif
153#ifdef X509_V_ERR_UNABLE_TO_GET_CRL
154 ERROR(X509_V_ERR_UNABLE_TO_GET_CRL);
155#endif
156#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE
157 ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);
158#endif
159#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE
160 ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE);
161#endif
162#ifdef X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
163 ERROR(X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY);
164#endif
165#ifdef X509_V_ERR_CERT_SIGNATURE_FAILURE
166 ERROR(X509_V_ERR_CERT_SIGNATURE_FAILURE);
167#endif
168#ifdef X509_V_ERR_CRL_SIGNATURE_FAILURE
169 ERROR(X509_V_ERR_CRL_SIGNATURE_FAILURE);
170#endif
171#ifdef X509_V_ERR_CERT_NOT_YET_VALID
172 ERROR(X509_V_ERR_CERT_NOT_YET_VALID);
173#endif
174#ifdef X509_V_ERR_CERT_HAS_EXPIRED
175 ERROR(X509_V_ERR_CERT_HAS_EXPIRED);
176#endif
177#ifdef X509_V_ERR_CRL_NOT_YET_VALID
178 ERROR(X509_V_ERR_CRL_NOT_YET_VALID);
179#endif
180#ifdef X509_V_ERR_CRL_HAS_EXPIRED
181 ERROR(X509_V_ERR_CRL_HAS_EXPIRED);
182#endif
183#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
184 ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD);
185#endif
186#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
187 ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD);
188#endif
189#ifdef X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
190 ERROR(X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD);
191#endif
192#ifdef X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
193 ERROR(X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
194#endif
195#ifdef X509_V_ERR_OUT_OF_MEM
196 ERROR(X509_V_ERR_OUT_OF_MEM);
197#endif
198#ifdef X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
199 ERROR(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT);
200#endif
201#ifdef X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
202 ERROR(X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN);
203#endif
204#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
205 ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY);
206#endif
207#ifdef X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
208 ERROR(X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
209#endif
210#ifdef X509_V_ERR_CERT_CHAIN_TOO_LONG
211 ERROR(X509_V_ERR_CERT_CHAIN_TOO_LONG);
212#endif
213#ifdef X509_V_ERR_CERT_REVOKED
214 ERROR(X509_V_ERR_CERT_REVOKED);
215#endif
216#ifdef X509_V_ERR_INVALID_CA
217 ERROR(X509_V_ERR_INVALID_CA);
218#endif
219#ifdef X509_V_ERR_PATH_LENGTH_EXCEEDED
220 ERROR(X509_V_ERR_PATH_LENGTH_EXCEEDED);
221#endif
222#ifdef X509_V_ERR_INVALID_PURPOSE
223 ERROR(X509_V_ERR_INVALID_PURPOSE);
224#endif
225#ifdef X509_V_ERR_CERT_UNTRUSTED
226 ERROR(X509_V_ERR_CERT_UNTRUSTED);
227#endif
228#ifdef X509_V_ERR_CERT_REJECTED
229 ERROR(X509_V_ERR_CERT_REJECTED);
230#endif
231 /* These are 'informational' when looking for issuer cert */
232#ifdef X509_V_ERR_SUBJECT_ISSUER_MISMATCH
233 ERROR(X509_V_ERR_SUBJECT_ISSUER_MISMATCH);
234#endif
235#ifdef X509_V_ERR_AKID_SKID_MISMATCH
236 ERROR(X509_V_ERR_AKID_SKID_MISMATCH);
237#endif
238#ifdef X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH
239 ERROR(X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH);
240#endif
241#ifdef X509_V_ERR_KEYUSAGE_NO_CERTSIGN
242 ERROR(X509_V_ERR_KEYUSAGE_NO_CERTSIGN);
243#endif
244
245#ifdef X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER
246 ERROR(X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER);
247#endif
248#ifdef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION
249 ERROR(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION);
250#endif
251#ifdef X509_V_ERR_KEYUSAGE_NO_CRL_SIGN
252 ERROR(X509_V_ERR_KEYUSAGE_NO_CRL_SIGN);
253#endif
254#ifdef X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION
255 ERROR(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
256#endif
257#ifdef X509_V_ERR_INVALID_NON_CA
258 ERROR(X509_V_ERR_INVALID_NON_CA);
259#endif
260#ifdef X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED
261 ERROR(X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED);
262#endif
263#ifdef X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE
264 ERROR(X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE);
265#endif
266#ifdef X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED
267 ERROR(X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED);
268#endif
269
270#ifdef X509_V_ERR_INVALID_EXTENSION
271 ERROR(X509_V_ERR_INVALID_EXTENSION);
272#endif
273#ifdef X509_V_ERR_INVALID_POLICY_EXTENSION
274 ERROR(X509_V_ERR_INVALID_POLICY_EXTENSION);
275#endif
276#ifdef X509_V_ERR_NO_EXPLICIT_POLICY
277 ERROR(X509_V_ERR_NO_EXPLICIT_POLICY);
278#endif
279#ifdef X509_V_ERR_DIFFERENT_CRL_SCOPE
280 ERROR(X509_V_ERR_DIFFERENT_CRL_SCOPE);
281#endif
282#ifdef X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE
283 ERROR(X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
284#endif
285
286#ifdef X509_V_ERR_UNNESTED_RESOURCE
287 ERROR(X509_V_ERR_UNNESTED_RESOURCE);
288#endif
289
290#ifdef X509_V_ERR_PERMITTED_VIOLATION
291 ERROR(X509_V_ERR_PERMITTED_VIOLATION);
292#endif
293#ifdef X509_V_ERR_EXCLUDED_VIOLATION
294 ERROR(X509_V_ERR_EXCLUDED_VIOLATION);
295#endif
296#ifdef X509_V_ERR_SUBTREE_MINMAX
297 ERROR(X509_V_ERR_SUBTREE_MINMAX);
298#endif
299#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE
300 ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
301#endif
302#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX
303 ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
304#endif
305#ifdef X509_V_ERR_UNSUPPORTED_NAME_SYNTAX
306 ERROR(X509_V_ERR_UNSUPPORTED_NAME_SYNTAX);
307#endif
308#ifdef X509_V_ERR_CRL_PATH_VALIDATION_ERROR
309 ERROR(X509_V_ERR_CRL_PATH_VALIDATION_ERROR);
310#endif
311
312 /* The application is not happy */
313#ifdef X509_V_ERR_APPLICATION_VERIFICATION
314 ERROR(X509_V_ERR_APPLICATION_VERIFICATION);
315#endif
316 }
317#undef ERROR
318}
319
320static void
321_openssl_print_errors(void *conn, int type)
322{
323 char buf[1024];
324 do
325 {
326 unsigned long err;
327
328 err = ERR_get_error();
329 if (!err) break;
330 snprintf(buf, sizeof(buf), "OpenSSL error: %s", ERR_reason_error_string(err));
331 if (type == ECORE_CON_EVENT_CLIENT_ERROR)
332 ecore_con_event_client_error(conn, buf);
333 else
334 ecore_con_event_server_error(conn, buf);
335
336 } while (1);
337}
338
339static Eina_Bool
340_openssl_name_verify(const char *name, const char *svrname)
341{
342 if (name[0] == '*')
343 {
344 /* we allow *.domain.TLD with a wildcard, but nothing else */
345 const char *p, *s;
346
347 EINA_SAFETY_ON_TRUE_RETURN_VAL((name[1] != '.') || (!name[2]), EINA_FALSE);
348 p = strchr(name + 1, '*');
349 EINA_SAFETY_ON_TRUE_RETURN_VAL(!!p, EINA_FALSE);
350 /* verify that we have a domain of at least *.X.TLD and not *.TLD */
351 p = strchr(name + 2, '.');
352 EINA_SAFETY_ON_TRUE_RETURN_VAL(!p, EINA_FALSE);
353 s = strchr(svrname, '.');
354 EINA_SAFETY_ON_TRUE_RETURN_VAL(!s, EINA_FALSE);
355 /* same as above for the stored name */
356 EINA_SAFETY_ON_TRUE_RETURN_VAL(!strchr(s + 1, '.'), EINA_FALSE);
357 if (strcasecmp(s, name + 1))
358 {
359 ERR("%s != %s", s, name + 1);
360 return EINA_FALSE;
361 }
362 }
363 else
364 if (strcasecmp(name, svrname))
365 {
366 ERR("%s != %s", name, svrname);
367 return EINA_FALSE;
368 }
369 return EINA_TRUE;
370}
371
372static void
373_openssl_print_session(SSL *ssl)
374{
375 /* print session info into DBG */
376 SSL_SESSION *s;
377 STACK_OF(X509) *sk;
378 BIO *b;
379 char log[4096], *p;
380 int x;
381
382 if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return;
383
384 memset(log, 0, sizeof(log));
385 b = BIO_new(BIO_s_mem());
386 sk = SSL_get_peer_cert_chain(ssl);
387 if (sk)
388 {
389 DBG("CERTIFICATES:");
390 for (x = 0; x < sk_X509_num(sk); x++)
391 {
392 p = X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, x)), log, sizeof(log));
393 DBG("%2d s:%s", x, p);
394 p = X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, x)), log, sizeof(log));
395 DBG(" i:%s", p);
396 PEM_write_X509(stderr, sk_X509_value(sk, x));
397 }
398 }
399 s = SSL_get_session(ssl);
400 SSL_SESSION_print(b, s);
401 fprintf(stderr, "\n");
402 while (BIO_read(b, log, sizeof(log)) > 0)
403 fprintf(stderr, "%s", log);
404
405 BIO_free(b);
406}
407
408#endif
409
410#define SSL_ERROR_CHECK_GOTO_ERROR(X) \
411 do \
412 { \
413 if ((X)) \
414 { \
415 ERR("Error at %s:%s:%d!", __FILE__, __PRETTY_FUNCTION__, __LINE__); \
416 goto error; \
417 } \
418 } \
419 while (0)
420
421static Ecore_Con_Ssl_Error
422 SSL_SUFFIX(_ecore_con_ssl_init) (void);
423static Ecore_Con_Ssl_Error
424 SSL_SUFFIX(_ecore_con_ssl_shutdown) (void);
425
426static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (Ecore_Con_Server * svr, const char *ca_file);
427static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (Ecore_Con_Server * svr, const char *crl_file);
428static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (Ecore_Con_Server * svr, const char *cert);
429static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (Ecore_Con_Server * svr, const char *key_file);
430
431static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_prepare) (Ecore_Con_Server * svr, int ssl_type);
432static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_init) (Ecore_Con_Server * svr);
433static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (Ecore_Con_Server *svr);
434static int SSL_SUFFIX(_ecore_con_ssl_server_read) (Ecore_Con_Server *svr, unsigned char *buf, int size);
435static int SSL_SUFFIX(_ecore_con_ssl_server_write) (Ecore_Con_Server *svr, const unsigned char *buf, int size);
436
437static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_client_init) (Ecore_Con_Client * cl);
438static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (Ecore_Con_Client *cl);
439static int SSL_SUFFIX(_ecore_con_ssl_client_read) (Ecore_Con_Client * cl,
440 unsigned char *buf, int size);
441static int SSL_SUFFIX(_ecore_con_ssl_client_write) (Ecore_Con_Client * cl,
442 const unsigned char *buf, int size);
443
444/*
445 * General SSL API
446 */
447
448Ecore_Con_Ssl_Error
449ecore_con_ssl_init(void)
450{
451 if (!_init_con_ssl_init_count++)
452 {
453 SSL_SUFFIX(_ecore_con_ssl_init) ();
454#if _ECORE_CON_SSL_AVAILABLE != 0
455 ECORE_CON_EVENT_CLIENT_UPGRADE = ecore_event_type_new();
456 ECORE_CON_EVENT_SERVER_UPGRADE = ecore_event_type_new();
457#endif
458 }
459
460 return _init_con_ssl_init_count;
461}
462
463Ecore_Con_Ssl_Error
464ecore_con_ssl_shutdown(void)
465{
466 if (!--_init_con_ssl_init_count)
467 SSL_SUFFIX(_ecore_con_ssl_shutdown) ();
468
469 return _init_con_ssl_init_count;
470}
471
472Ecore_Con_Ssl_Error
473ecore_con_ssl_server_prepare(Ecore_Con_Server *svr,
474 int ssl_type)
475{
476 if (!ssl_type)
477 return ECORE_CON_SSL_ERROR_NONE;
478 return SSL_SUFFIX(_ecore_con_ssl_server_prepare) (svr, ssl_type);
479}
480
481Ecore_Con_Ssl_Error
482ecore_con_ssl_server_init(Ecore_Con_Server *svr)
483{
484 if (!(svr->type & ECORE_CON_SSL))
485 return ECORE_CON_SSL_ERROR_NONE;
486 return SSL_SUFFIX(_ecore_con_ssl_server_init) (svr);
487}
488
489Ecore_Con_Ssl_Error
490ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr)
491{
492 if (!(svr->type & ECORE_CON_SSL))
493 return ECORE_CON_SSL_ERROR_NONE;
494 return SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (svr);
495}
496
497int
498ecore_con_ssl_server_read(Ecore_Con_Server *svr,
499 unsigned char *buf,
500 int size)
501{
502 return SSL_SUFFIX(_ecore_con_ssl_server_read) (svr, buf, size);
503}
504
505int
506ecore_con_ssl_server_write(Ecore_Con_Server *svr,
507 const unsigned char *buf,
508 int size)
509{
510 return SSL_SUFFIX(_ecore_con_ssl_server_write) (svr, buf, size);
511}
512
513Ecore_Con_Ssl_Error
514ecore_con_ssl_client_init(Ecore_Con_Client *cl)
515{
516 if (!(cl->host_server->type & ECORE_CON_SSL))
517 return ECORE_CON_SSL_ERROR_NONE;
518 return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl);
519}
520
521Ecore_Con_Ssl_Error
522ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl)
523{
524 if (!(cl->host_server->type & ECORE_CON_SSL))
525 return ECORE_CON_SSL_ERROR_NONE;
526 return SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (cl);
527}
528
529int
530ecore_con_ssl_client_read(Ecore_Con_Client *cl,
531 unsigned char *buf,
532 int size)
533{
534 return SSL_SUFFIX(_ecore_con_ssl_client_read) (cl, buf, size);
535}
536
537int
538ecore_con_ssl_client_write(Ecore_Con_Client *cl,
539 const unsigned char *buf,
540 int size)
541{
542 return SSL_SUFFIX(_ecore_con_ssl_client_write) (cl, buf, size);
543}
544
545/**
546 * Returns if SSL support is available
547 * @return 1 if SSL is available and provided by gnutls, 2 if provided by openssl,
548 * 0 if it is not available.
549 * @ingroup Ecore_Con_Client_Group
550 */
551EAPI int
552ecore_con_ssl_available_get(void)
553{
554 return _ECORE_CON_SSL_AVAILABLE;
555}
556
557/**
558 * @addtogroup Ecore_Con_SSL_Group Ecore Connection SSL Functions
559 *
560 * Functions that operate on Ecore connection objects pertaining to SSL.
561 *
562 * @{
563 */
564
565/**
566 * @brief Enable certificate verification on a server object
567 *
568 * Call this function on a server object before main loop has started
569 * to enable verification of certificates against loaded certificates.
570 * @param svr The server object
571 */
572EAPI void
573ecore_con_ssl_server_verify(Ecore_Con_Server *svr)
574{
575 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
576 {
577 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_verify");
578 return;
579 }
580 svr->verify = EINA_TRUE;
581}
582
583/**
584 * @brief Enable hostname-based certificate verification on a server object
585 *
586 * Call this function on a server object before main loop has started
587 * to enable verification of certificates using ONLY their hostnames.
588 * @param svr The server object
589 * @note This function has no effect when used on a listening server created by
590 * ecore_con_server_add
591 * @since 1.1
592 */
593EAPI void
594ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr)
595{
596 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
597 {
598 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
599 return;
600 }
601 svr->verify_basic = EINA_TRUE;
602}
603
604/**
605 * @brief Set the hostname to verify against in certificate verification
606 *
607 * Sometimes the certificate hostname will not match the hostname that you are
608 * connecting to, and will instead match a different name. An example of this is
609 * that if you connect to talk.google.com to use Google Talk, you receive Google's
610 * certificate for gmail.com. This certificate should be trusted, and so you must call
611 * this function with "gmail.com" as @p name.
612 * See RFC2818 for more details.
613 * @param svr The server object
614 * @param name The hostname to verify against
615 * @since 1.2
616 */
617EAPI void
618ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name)
619{
620 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
621 {
622 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
623 return;
624 }
625 eina_stringshare_replace(&svr->verify_name, name);
626}
627
628/**
629 * @brief Get the hostname to verify against in certificate verification
630 *
631 * This function returns the name which will be used to validate the SSL certificate
632 * common name (CN) or alt name (subjectAltName). It will default to the @p name
633 * param in ecore_con_server_connect(), but can be changed with ecore_con_ssl_server_verify_name_set().
634 * @param svr The server object
635 * @return The hostname which will be used
636 * @since 1.2
637 */
638EAPI const char *
639ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr)
640{
641 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
642 {
643 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
644 return NULL;
645 }
646 return svr->verify_name ?: svr->name;
647}
648
649/**
650 * @brief Add an ssl certificate for use in ecore_con functions.
651 *
652 * Use this function to add a SSL PEM certificate.
653 * Simply specify the cert here to use it in the server object for connecting or listening.
654 * If there is an error loading the certificate, an error will automatically be logged.
655 * @param svr The server object
656 * @param cert The path to the certificate.
657 * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE.
658 */
659
660EAPI Eina_Bool
661ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr,
662 const char *cert)
663{
664 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
665 {
666 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cert_add");
667 return EINA_FALSE;
668 }
669
670 if (!svr->ssl_prepared)
671 {
672 svr->use_cert = EINA_TRUE;
673 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
674 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
675 return EINA_FALSE;
676 }
677
678 return SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (svr, cert);
679}
680
681/**
682 * @brief Add an ssl CA file for use in ecore_con functions.
683 *
684 * Use this function to add a SSL PEM CA file.
685 * Simply specify the file here to use it in the server object for connecting or listening.
686 * If there is an error loading the CAs, an error will automatically be logged.
687 * @param svr The server object
688 * @param ca_file The path to the CA file.
689 * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE.
690 * @note since 1.2, this function can load directores
691 */
692
693EAPI Eina_Bool
694ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr,
695 const char *ca_file)
696{
697 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
698 {
699 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cafile_add");
700 return EINA_FALSE;
701 }
702
703 if (!svr->ssl_prepared)
704 {
705 svr->use_cert = EINA_TRUE;
706 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
707 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
708 return EINA_FALSE;
709 }
710
711 return SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (svr, ca_file);
712}
713
714/**
715 * @brief Add an ssl private key for use in ecore_con functions.
716 *
717 * Use this function to add a SSL PEM private key
718 * Simply specify the key file here to use it in the server object for connecting or listening.
719 * If there is an error loading the key, an error will automatically be logged.
720 * @param key_file The path to the key file.
721 * @return EINA_FALSE if the file cannot be loaded,
722 * otherwise EINA_TRUE.
723 */
724
725EAPI Eina_Bool
726ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr,
727 const char *key_file)
728{
729 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
730 {
731 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_privkey_add");
732 return EINA_FALSE;
733 }
734
735 if (!svr->ssl_prepared)
736 {
737 svr->use_cert = EINA_TRUE;
738 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
739 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
740 return EINA_FALSE;
741 }
742
743 return SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (svr, key_file);
744}
745
746/**
747 * @brief Add an ssl CRL for use in ecore_con functions.
748 *
749 * Use this function to add a SSL PEM CRL file
750 * Simply specify the CRL file here to use it in the server object for connecting or listening.
751 * If there is an error loading the CRL, an error will automatically be logged.
752 * @param svr The server object
753 * @param crl_file The path to the CRL file.
754 * @return EINA_FALSE if the file cannot be loaded,
755 * otherwise EINA_TRUE.
756 */
757
758EAPI Eina_Bool
759ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr,
760 const char *crl_file)
761{
762 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
763 {
764 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_crl_add");
765 return EINA_FALSE;
766 }
767
768 if (!svr->ssl_prepared)
769 {
770 svr->use_cert = EINA_TRUE;
771 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
772 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
773 return EINA_FALSE;
774 }
775
776 return SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (svr, crl_file);
777}
778
779/**
780 * @brief Upgrade a connection to a specified level of encryption
781 *
782 * Use this function to begin an SSL handshake on a connection (STARTTLS or similar).
783 * Once the upgrade has been completed, an ECORE_CON_EVENT_SERVER_UPGRADE event will be emitted.
784 * The connection should be treated as disconnected until the next event.
785 * @param svr The server object
786 * @param ssl_type The SSL connection type (ONLY).
787 * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE.
788 * @note This function is NEVER to be used on a server object created with ecore_con_server_add
789 * @warning Setting a wrong value for @p compl_type WILL mess up your program.
790 * @since 1.1
791 */
792
793EAPI Eina_Bool
794ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type ssl_type)
795{
796 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
797 {
798 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
799 return EINA_FALSE;
800 }
801#if _ECORE_CON_SSL_AVAILABLE == 0
802 return EINA_FALSE;
803#endif
804
805 if (!svr->ssl_prepared)
806 {
807 if (ecore_con_ssl_server_prepare(svr, ssl_type))
808 return EINA_FALSE;
809 }
810 if (!svr->use_cert)
811 svr->type |= ssl_type;
812 svr->upgrade = EINA_TRUE;
813 svr->handshaking = EINA_TRUE;
814 svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
815 return !SSL_SUFFIX(_ecore_con_ssl_server_init) (svr);
816}
817
818/**
819 * @brief Upgrade a connection to a specified level of encryption
820 *
821 * Use this function to begin an SSL handshake on a connection (STARTTLS or similar).
822 * Once the upgrade has been completed, an ECORE_CON_EVENT_CLIENT_UPGRADE event will be emitted.
823 * The connection should be treated as disconnected until the next event.
824 * @param cl The client object
825 * @param ssl_type The SSL connection type (ONLY).
826 * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE.
827 * @warning Setting a wrong value for @p compl_type WILL mess up your program.
828 * @since 1.1
829 */
830
831EAPI Eina_Bool
832ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type ssl_type)
833{
834 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
835 {
836 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__);
837 return EINA_FALSE;
838 }
839#if _ECORE_CON_SSL_AVAILABLE == 0
840 return EINA_FALSE;
841#endif
842
843 if (!cl->host_server->ssl_prepared)
844 {
845 if (ecore_con_ssl_server_prepare(cl->host_server, ssl_type))
846 return EINA_FALSE;
847 }
848 if (!cl->host_server->use_cert)
849 cl->host_server->type |= ssl_type;
850 cl->upgrade = EINA_TRUE;
851 cl->host_server->upgrade = EINA_TRUE;
852 cl->handshaking = EINA_TRUE;
853 cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
854 return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl);
855}
856
857/**
858 * @}
859 */
860
861#if USE_GNUTLS
862
863/*
864 * GnuTLS
865 */
866
867static Ecore_Con_Ssl_Error
868_ecore_con_ssl_init_gnutls(void)
869{
870#ifdef EINA_HAVE_THREADS
871 if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
872 WRN("YOU ARE USING PTHREADS, BUT I CANNOT INITIALIZE THREADSAFE GCRYPT OPERATIONS!");
873#endif
874 if (gnutls_global_init())
875 return ECORE_CON_SSL_ERROR_INIT_FAILED;
876
877#ifdef ISCOMFITOR
878 if (eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG))
879 {
880 gnutls_global_set_log_level(9);
881 gnutls_global_set_log_function(_gnutls_log_func);
882 }
883#endif
884 return ECORE_CON_SSL_ERROR_NONE;
885}
886
887static Ecore_Con_Ssl_Error
888_ecore_con_ssl_shutdown_gnutls(void)
889{
890 gnutls_global_deinit();
891
892 return ECORE_CON_SSL_ERROR_NONE;
893}
894
895static Ecore_Con_Ssl_Error
896_ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr,
897 int ssl_type)
898{
899 int ret;
900
901 if (ssl_type & ECORE_CON_USE_SSL2)
902 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
903
904 switch (ssl_type)
905 {
906 case ECORE_CON_USE_SSL3:
907 case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
908 case ECORE_CON_USE_TLS:
909 case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
910 case ECORE_CON_USE_MIXED:
911 case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
912 break;
913
914 default:
915 return ECORE_CON_SSL_ERROR_NONE;
916 }
917
918 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_allocate_credentials(&svr->cert));
919
920 if (svr->use_cert)
921 {
922 if (svr->created)
923 {
924 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_init(&svr->dh_params));
925 INF("Generating DH params");
926 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_generate2(svr->dh_params, 1024));
927
928 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_server_credentials(&svr->anoncred_s));
929 /* TODO: implement PSK */
930 // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_server_credentials(&svr->pskcred_s));
931
932 gnutls_anon_set_server_dh_params(svr->anoncred_s, svr->dh_params);
933 gnutls_certificate_set_dh_params(svr->cert, svr->dh_params);
934 //gnutls_psk_set_server_dh_params(svr->pskcred_s, svr->dh_params);
935 INF("DH params successfully generated and applied!");
936 }
937 else
938 {
939 //SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_client_credentials(&svr->pskcred_c));
940 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_client_credentials(&svr->anoncred_c));
941 }
942 }
943
944 svr->ssl_prepared = EINA_TRUE;
945 return ECORE_CON_SSL_ERROR_NONE;
946
947error:
948 _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret);
949 _ecore_con_ssl_server_shutdown_gnutls(svr);
950 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
951}
952
953
954static Ecore_Con_Ssl_Error
955_ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
956{
957 const gnutls_datum_t *cert_list;
958 unsigned int iter, cert_list_size;
959 gnutls_x509_crt_t cert = NULL;
960 const char *priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0";
961 int ret = 0;
962
963 switch (svr->ssl_state)
964 {
965 case ECORE_CON_SSL_STATE_DONE:
966 return ECORE_CON_SSL_ERROR_NONE;
967
968 case ECORE_CON_SSL_STATE_INIT:
969 if (svr->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
970 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
971
972 switch (svr->type & ECORE_CON_SSL)
973 {
974 case ECORE_CON_USE_SSL3:
975 case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
976 priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-TLS1.0:!VERS-TLS1.1";
977 break;
978
979 case ECORE_CON_USE_TLS:
980 case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
981 priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-SSL3.0";
982 break;
983
984 case ECORE_CON_USE_MIXED:
985 case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
986 break;
987
988 default:
989 return ECORE_CON_SSL_ERROR_NONE;
990 }
991
992 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&svr->session, GNUTLS_CLIENT));
993 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_client(svr->session));
994 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_server_name_set(svr->session, GNUTLS_NAME_DNS, svr->name, strlen(svr->name)));
995 INF("Applying priority string: %s", priority);
996 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(svr->session, priority, NULL));
997 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_CERTIFICATE, svr->cert));
998 // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_PSK, svr->pskcred_c));
999 if (!svr->use_cert)
1000 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c));
1001
1002 gnutls_dh_set_prime_bits(svr->session, 512);
1003 gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)((intptr_t)svr->fd));
1004 svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1005
1006 case ECORE_CON_SSL_STATE_HANDSHAKING:
1007 if (!svr->session)
1008 {
1009 DBG("Server was previously lost, going to error condition");
1010 goto error;
1011 }
1012 ret = gnutls_handshake(svr->session);
1013 DBG("calling gnutls_handshake(): returned with '%s'", gnutls_strerror_name(ret));
1014 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
1015 if (!ret)
1016 {
1017 svr->handshaking = EINA_FALSE;
1018 svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
1019 }
1020 else
1021 {
1022 if (gnutls_record_get_direction(svr->session))
1023 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1024 else
1025 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1026 return ECORE_CON_SSL_ERROR_NONE;
1027 }
1028
1029 default:
1030 break;
1031 }
1032
1033 if ((!svr->verify) && (!svr->verify_basic))
1034 /* not verifying certificates, so we're done! */
1035 return ECORE_CON_SSL_ERROR_NONE;
1036 if (svr->verify)
1037 {
1038 /* use CRL/CA lists to verify */
1039 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(svr->session, &iter));
1040 if (iter & GNUTLS_CERT_INVALID)
1041 ERR("The certificate is not trusted.");
1042 else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND)
1043 ERR("The certificate hasn't got a known issuer.");
1044 else if (iter & GNUTLS_CERT_REVOKED)
1045 ERR("The certificate has been revoked.");
1046 else if (iter & GNUTLS_CERT_EXPIRED)
1047 ERR("The certificate has expired");
1048 else if (iter & GNUTLS_CERT_NOT_ACTIVATED)
1049 ERR("The certificate is not yet activated");
1050
1051 if (iter)
1052 goto error;
1053 }
1054 if (gnutls_certificate_type_get(svr->session) != GNUTLS_CRT_X509)
1055 {
1056 ERR("Warning: PGP certificates are not yet supported!");
1057 goto error;
1058 }
1059
1060 SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(svr->session, &cert_list_size)));
1061 SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size);
1062
1063 _gnutls_print_session(cert_list, cert_list_size);
1064
1065 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert));
1066 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER));
1067
1068 SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->verify_name ?: svr->name));
1069 gnutls_x509_crt_deinit(cert);
1070 DBG("SSL certificate verification succeeded!");
1071 return ECORE_CON_SSL_ERROR_NONE;
1072
1073error:
1074 _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret);
1075 if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
1076 ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(svr->session)));
1077 if (svr->session && (svr->ssl_state != ECORE_CON_SSL_STATE_DONE))
1078 {
1079 ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(svr->session)));
1080 ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(svr->session)));
1081 }
1082 if (cert)
1083 gnutls_x509_crt_deinit(cert);
1084 _ecore_con_ssl_server_shutdown_gnutls(svr);
1085 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1086}
1087
1088static Eina_Bool
1089_ecore_con_ssl_server_cafile_add_gnutls(Ecore_Con_Server *svr,
1090 const char *ca_file)
1091{
1092 struct stat st;
1093 Eina_Iterator *it;
1094 const char *file;
1095 Eina_Bool error = EINA_FALSE;
1096
1097 if (stat(ca_file, &st)) return EINA_FALSE;
1098 if (S_ISDIR(st.st_mode))
1099 {
1100 it = eina_file_ls(ca_file);
1101 SSL_ERROR_CHECK_GOTO_ERROR(!it);
1102 EINA_ITERATOR_FOREACH(it, file)
1103 {
1104 if (!error)
1105 {
1106 if (gnutls_certificate_set_x509_trust_file(svr->cert, file, GNUTLS_X509_FMT_PEM) < 1)
1107 error++;
1108 }
1109 eina_stringshare_del(file);
1110 }
1111 eina_iterator_free(it);
1112 }
1113 else
1114 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_trust_file(svr->cert, ca_file,
1115 GNUTLS_X509_FMT_PEM) < 1);
1116
1117 return !error;
1118error:
1119 ERR("Could not load CA file!");
1120 return EINA_FALSE;
1121}
1122
1123static Eina_Bool
1124_ecore_con_ssl_server_crl_add_gnutls(Ecore_Con_Server *svr,
1125 const char *crl_file)
1126{
1127 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_crl_file(svr->cert, crl_file,
1128 GNUTLS_X509_FMT_PEM) < 1);
1129
1130 return EINA_TRUE;
1131error:
1132 ERR("Could not load CRL file!");
1133 return EINA_FALSE;
1134}
1135
1136static Eina_Bool
1137_ecore_con_ssl_server_privkey_add_gnutls(Ecore_Con_Server *svr,
1138 const char *key_file)
1139{
1140 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_key_file(svr->cert, svr->cert_file, key_file,
1141 GNUTLS_X509_FMT_PEM));
1142
1143 return EINA_TRUE;
1144error:
1145 ERR("Could not load certificate/key file!");
1146 return EINA_FALSE;
1147}
1148
1149static Eina_Bool
1150_ecore_con_ssl_server_cert_add_gnutls(Ecore_Con_Server *svr,
1151 const char *cert_file)
1152{
1153 if (!(svr->cert_file = strdup(cert_file)))
1154 return EINA_FALSE;
1155
1156 return EINA_TRUE;
1157}
1158
1159static Ecore_Con_Ssl_Error
1160_ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
1161{
1162 if (svr->session)
1163 {
1164 gnutls_bye(svr->session, GNUTLS_SHUT_RDWR);
1165 gnutls_deinit(svr->session);
1166 }
1167
1168 free(svr->cert_file);
1169 svr->cert_file = NULL;
1170 if (svr->cert)
1171 gnutls_certificate_free_credentials(svr->cert);
1172 svr->cert = NULL;
1173
1174 if ((svr->type & ECORE_CON_SSL) && svr->created)
1175 {
1176 if (svr->dh_params)
1177 {
1178 gnutls_dh_params_deinit(svr->dh_params);
1179 svr->dh_params = NULL;
1180 }
1181 if (svr->anoncred_s)
1182 gnutls_anon_free_server_credentials(svr->anoncred_s);
1183 // if (svr->pskcred_s)
1184 // gnutls_psk_free_server_credentials(svr->pskcred_s);
1185
1186 svr->anoncred_s = NULL;
1187 svr->pskcred_s = NULL;
1188 }
1189 else if (svr->type & ECORE_CON_SSL)
1190 {
1191 if (svr->anoncred_c)
1192 gnutls_anon_free_client_credentials(svr->anoncred_c);
1193 // if (svr->pskcred_c)
1194 // gnutls_psk_free_client_credentials(svr->pskcred_c);
1195
1196 svr->anoncred_c = NULL;
1197 svr->pskcred_c = NULL;
1198 }
1199
1200 svr->session = NULL;
1201
1202 return ECORE_CON_SSL_ERROR_NONE;
1203}
1204
1205static int
1206_ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr,
1207 unsigned char *buf,
1208 int size)
1209{
1210 int num;
1211
1212 if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1213 {
1214 DBG("Continuing gnutls handshake");
1215 if (!_ecore_con_ssl_server_init_gnutls(svr))
1216 return 0;
1217 return -1;
1218 }
1219
1220 num = gnutls_record_recv(svr->session, buf, size);
1221 if (num > 0)
1222 return num;
1223
1224 if (num == GNUTLS_E_REHANDSHAKE)
1225 {
1226 WRN("Rehandshake request ignored");
1227 return 0;
1228
1229 svr->handshaking = EINA_TRUE;
1230 svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1231 if (!_ecore_con_ssl_server_init_gnutls(svr))
1232 return 0;
1233 }
1234 else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS))
1235 return 0;
1236
1237 return -1;
1238}
1239
1240static int
1241_ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr,
1242 const unsigned char *buf,
1243 int size)
1244{
1245 int num;
1246
1247 if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1248 {
1249 DBG("Continuing gnutls handshake");
1250 if (!_ecore_con_ssl_server_init_gnutls(svr))
1251 return 0;
1252 return -1;
1253 }
1254
1255 num = gnutls_record_send(svr->session, buf, size);
1256 if (num > 0)
1257 return num;
1258
1259 if (num == GNUTLS_E_REHANDSHAKE)
1260 {
1261 WRN("Rehandshake request ignored");
1262 return 0;
1263/* this is only partly functional I think? */
1264 svr->handshaking = EINA_TRUE;
1265 svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1266 if (!_ecore_con_ssl_server_init_gnutls(svr))
1267 return 0;
1268 }
1269 else if (!gnutls_error_is_fatal(num))
1270 return 0;
1271
1272 return -1;
1273}
1274
1275static Ecore_Con_Ssl_Error
1276_ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
1277{
1278 const gnutls_datum_t *cert_list;
1279 unsigned int iter, cert_list_size;
1280 const char *priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0";
1281 int ret = 0;
1282
1283 switch (cl->ssl_state)
1284 {
1285 case ECORE_CON_SSL_STATE_DONE:
1286 return ECORE_CON_SSL_ERROR_NONE;
1287
1288 case ECORE_CON_SSL_STATE_INIT:
1289 if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
1290 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
1291
1292 switch (cl->host_server->type & ECORE_CON_SSL)
1293 {
1294 case ECORE_CON_USE_SSL3:
1295 case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
1296 priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-TLS1.0:!VERS-TLS1.1";
1297 break;
1298
1299 case ECORE_CON_USE_TLS:
1300 case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
1301 priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-SSL3.0";
1302 break;
1303
1304 case ECORE_CON_USE_MIXED:
1305 case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
1306 break;
1307
1308 default:
1309 return ECORE_CON_SSL_ERROR_NONE;
1310 }
1311
1312 _client_connected++;
1313
1314 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&cl->session, GNUTLS_SERVER));
1315 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_key_generate(&cl->session_ticket));
1316 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_server(cl->session, &cl->session_ticket));
1317 INF("Applying priority string: %s", priority);
1318 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(cl->session, priority, NULL));
1319 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_CERTIFICATE, cl->host_server->cert));
1320 // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_PSK, cl->host_server->pskcred_s));
1321 if (!cl->host_server->use_cert)
1322 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->host_server->anoncred_s));
1323
1324 gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST);
1325
1326 gnutls_dh_set_prime_bits(cl->session, 2048);
1327 gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)((intptr_t)cl->fd));
1328 cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1329
1330 case ECORE_CON_SSL_STATE_HANDSHAKING:
1331 if (!cl->session)
1332 {
1333 DBG("Client was previously lost, going to error condition");
1334 goto error;
1335 }
1336 DBG("calling gnutls_handshake()");
1337 ret = gnutls_handshake(cl->session);
1338 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
1339
1340 if (!ret)
1341 {
1342 cl->handshaking = EINA_FALSE;
1343 cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
1344 }
1345 else
1346 {
1347 if (gnutls_record_get_direction(cl->session))
1348 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1349 else
1350 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1351 return ECORE_CON_SSL_ERROR_NONE;
1352 }
1353
1354 default:
1355 break;
1356 }
1357
1358 if (!cl->host_server->verify)
1359 /* not verifying certificates, so we're done! */
1360 return ECORE_CON_SSL_ERROR_NONE;
1361 /* use CRL/CA lists to verify */
1362 SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(cl->session, &iter));
1363 if (iter & GNUTLS_CERT_INVALID)
1364 ERR("The certificate is not trusted.");
1365 else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND)
1366 ERR("The certificate hasn't got a known issuer.");
1367 else if (iter & GNUTLS_CERT_REVOKED)
1368 ERR("The certificate has been revoked.");
1369 else if (iter & GNUTLS_CERT_EXPIRED)
1370 ERR("The certificate has expired");
1371 else if (iter & GNUTLS_CERT_NOT_ACTIVATED)
1372 ERR("The certificate is not yet activated");
1373
1374 if (iter)
1375 goto error;
1376 if (gnutls_certificate_type_get(cl->session) != GNUTLS_CRT_X509)
1377 {
1378 ERR("Warning: PGP certificates are not yet supported!");
1379 goto error;
1380 }
1381
1382 SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(cl->session, &cert_list_size)));
1383 SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size);
1384
1385 _gnutls_print_session(cert_list, cert_list_size);
1386/*
1387 gnutls_x509_crt_t cert = NULL;
1388 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert));
1389 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER));
1390
1391 SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, cl->host_server->name));
1392 gnutls_x509_crt_deinit(cert);
1393*/
1394 DBG("SSL certificate verification succeeded!");
1395 return ECORE_CON_SSL_ERROR_NONE;
1396
1397error:
1398 _gnutls_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR, ret);
1399 if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED))
1400 ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(cl->session)));
1401 if (cl->session && (cl->ssl_state != ECORE_CON_SSL_STATE_DONE))
1402 {
1403 ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(cl->session)));
1404 ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(cl->session)));
1405 }
1406/*
1407 if (cert)
1408 gnutls_x509_crt_deinit(cert);
1409*/
1410 _ecore_con_ssl_client_shutdown_gnutls(cl);
1411 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1412}
1413
1414static Ecore_Con_Ssl_Error
1415_ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
1416{
1417 if (cl->session)
1418 {
1419 gnutls_bye(cl->session, GNUTLS_SHUT_RDWR);
1420 gnutls_deinit(cl->session);
1421 gnutls_free(cl->session_ticket.data);
1422 cl->session_ticket.data = NULL;
1423 }
1424
1425 cl->session = NULL;
1426
1427 return ECORE_CON_SSL_ERROR_NONE;
1428}
1429
1430static int
1431_ecore_con_ssl_client_read_gnutls(Ecore_Con_Client *cl,
1432 unsigned char *buf,
1433 int size)
1434{
1435 int num;
1436
1437 if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1438 {
1439 if (!_ecore_con_ssl_client_init_gnutls(cl))
1440 return 0;
1441 return -1;
1442 }
1443
1444 num = gnutls_record_recv(cl->session, buf, size);
1445 if (num > 0)
1446 return num;
1447
1448 if (num == GNUTLS_E_REHANDSHAKE)
1449 {
1450 WRN("Rehandshake request ignored");
1451 return 0;
1452 cl->handshaking = EINA_TRUE;
1453 cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1454 if (!_ecore_con_ssl_client_init_gnutls(cl))
1455 return 0;
1456 WRN("Rehandshake request ignored");
1457 return 0;
1458 }
1459 else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS))
1460 return 0;
1461
1462 return -1;
1463}
1464
1465static int
1466_ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl,
1467 const unsigned char *buf,
1468 int size)
1469{
1470 int num;
1471
1472 if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING)
1473 {
1474 if (!_ecore_con_ssl_client_init_gnutls(cl))
1475 return 0;
1476 return -1;
1477 }
1478
1479 num = gnutls_record_send(cl->session, buf, size);
1480 if (num > 0)
1481 return num;
1482
1483 if (num == GNUTLS_E_REHANDSHAKE)
1484 {
1485 WRN("Rehandshake request ignored");
1486 return 0;
1487 cl->handshaking = EINA_TRUE;
1488 cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1489 if (!_ecore_con_ssl_client_init_gnutls(cl))
1490 return 0;
1491 }
1492 else if (!gnutls_error_is_fatal(num))
1493 return 0;
1494
1495 return -1;
1496}
1497
1498#elif USE_OPENSSL && !USE_GNUTLS
1499
1500/*
1501 * OpenSSL
1502 */
1503
1504static Ecore_Con_Ssl_Error
1505_ecore_con_ssl_init_openssl(void)
1506{
1507 SSL_library_init();
1508 SSL_load_error_strings();
1509 OpenSSL_add_all_algorithms();
1510
1511 return ECORE_CON_SSL_ERROR_NONE;
1512}
1513
1514static Ecore_Con_Ssl_Error
1515_ecore_con_ssl_shutdown_openssl(void)
1516{
1517 ERR_free_strings();
1518 EVP_cleanup();
1519 return ECORE_CON_SSL_ERROR_NONE;
1520}
1521
1522static Ecore_Con_Ssl_Error
1523_ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr,
1524 int ssl_type)
1525{
1526 long options;
1527 int dh = 0;
1528
1529 if (ssl_type & ECORE_CON_USE_SSL2)
1530 return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
1531
1532 switch (ssl_type)
1533 {
1534 case ECORE_CON_USE_SSL3:
1535 case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
1536 if (!svr->created)
1537 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())));
1538 else
1539 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_server_method())));
1540 break;
1541
1542 case ECORE_CON_USE_TLS:
1543 case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
1544 if (!svr->created)
1545 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())));
1546 else
1547 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_server_method())));
1548 break;
1549
1550 case ECORE_CON_USE_MIXED:
1551 case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
1552 if (!svr->created)
1553 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_client_method())));
1554 else
1555 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_server_method())));
1556 options = SSL_CTX_get_options(svr->ssl_ctx);
1557 SSL_CTX_set_options(svr->ssl_ctx, options | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE);
1558 break;
1559
1560 default:
1561 return ECORE_CON_SSL_ERROR_NONE;
1562 }
1563
1564 if ((!svr->use_cert) && svr->created)
1565 {
1566 DH *dh_params;
1567 INF("Generating DH params");
1568 SSL_ERROR_CHECK_GOTO_ERROR(!(dh_params = DH_new()));
1569 SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_parameters_ex(dh_params, 1024, DH_GENERATOR_5, NULL));
1570 SSL_ERROR_CHECK_GOTO_ERROR(!DH_check(dh_params, &dh));
1571 SSL_ERROR_CHECK_GOTO_ERROR((dh & DH_CHECK_P_NOT_PRIME) || (dh & DH_CHECK_P_NOT_SAFE_PRIME));
1572 SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_key(dh_params));
1573 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_tmp_dh(svr->ssl_ctx, dh_params));
1574 DH_free(dh_params);
1575 INF("DH params successfully generated and applied!");
1576 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:@STRENGTH"));
1577 }
1578 else if (!svr->use_cert)
1579 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:!ECDH:RSA:AES:!PSK:@STRENGTH"));
1580
1581 return ECORE_CON_SSL_ERROR_NONE;
1582
1583error:
1584 if (dh)
1585 {
1586 if (dh & DH_CHECK_P_NOT_PRIME)
1587 ERR("openssl error: dh_params could not generate a prime!");
1588 else
1589 ERR("openssl error: dh_params could not generate a safe prime!");
1590 }
1591 else
1592 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1593 _ecore_con_ssl_server_shutdown_openssl(svr);
1594 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1595}
1596
1597static Ecore_Con_Ssl_Error
1598_ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
1599{
1600 int ret = -1;
1601
1602 switch (svr->ssl_state)
1603 {
1604 case ECORE_CON_SSL_STATE_DONE:
1605 return ECORE_CON_SSL_ERROR_NONE;
1606
1607 case ECORE_CON_SSL_STATE_INIT:
1608 SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx)));
1609
1610 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd));
1611 SSL_set_connect_state(svr->ssl);
1612 svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1613
1614 case ECORE_CON_SSL_STATE_HANDSHAKING:
1615 if (!svr->ssl)
1616 {
1617 DBG("Server was previously lost, going to error condition");
1618 goto error;
1619 }
1620 ret = SSL_do_handshake(svr->ssl);
1621 svr->ssl_err = SSL_get_error(svr->ssl, ret);
1622 SSL_ERROR_CHECK_GOTO_ERROR((svr->ssl_err == SSL_ERROR_SYSCALL) || (svr->ssl_err == SSL_ERROR_SSL));
1623
1624 if (ret == 1)
1625 {
1626 svr->handshaking = EINA_FALSE;
1627 svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
1628 }
1629 else
1630 {
1631 if (svr->ssl_err == SSL_ERROR_WANT_READ)
1632 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1633 else if (svr->ssl_err == SSL_ERROR_WANT_WRITE)
1634 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1635 return ECORE_CON_SSL_ERROR_NONE;
1636 }
1637
1638 default:
1639 break;
1640 }
1641
1642 _openssl_print_session(svr->ssl);
1643 if ((!svr->verify) && (!svr->verify_basic))
1644 /* not verifying certificates, so we're done! */
1645 return ECORE_CON_SSL_ERROR_NONE;
1646
1647 {
1648 X509 *cert;
1649 SSL_set_verify(svr->ssl, SSL_VERIFY_PEER, NULL);
1650 /* use CRL/CA lists to verify */
1651 cert = SSL_get_peer_certificate(svr->ssl);
1652 if (cert)
1653 {
1654 char *c;
1655 int clen;
1656 int name = 0;
1657
1658 if (svr->verify)
1659 {
1660 int err;
1661
1662 err = SSL_get_verify_result(svr->ssl);
1663 _openssl_print_verify_error(err);
1664 SSL_ERROR_CHECK_GOTO_ERROR(err);
1665 }
1666 clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, NULL, 0);
1667 if (clen > 0)
1668 name = NID_subject_alt_name;
1669 else
1670 clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, NULL, 0);
1671 SSL_ERROR_CHECK_GOTO_ERROR(clen < 1);
1672 if (!name) name = NID_commonName;
1673 c = alloca(++clen);
1674 X509_NAME_get_text_by_NID(X509_get_subject_name(cert), name, c, clen);
1675 INF("CERT NAME: %s\n", c);
1676 SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(c, svr->verify_name ?: svr->name));
1677 }
1678 }
1679
1680 DBG("SSL certificate verification succeeded!");
1681
1682 return ECORE_CON_SSL_ERROR_NONE;
1683
1684error:
1685 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1686 _ecore_con_ssl_server_shutdown_openssl(svr);
1687 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1688}
1689
1690static Eina_Bool
1691_ecore_con_ssl_server_cafile_add_openssl(Ecore_Con_Server *svr,
1692 const char *ca_file)
1693{
1694 struct stat st;
1695
1696 if (stat(ca_file, &st)) return EINA_FALSE;
1697 if (S_ISDIR(st.st_mode))
1698 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, NULL, ca_file));
1699 else
1700 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, ca_file, NULL));
1701 return EINA_TRUE;
1702
1703error:
1704 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1705 return EINA_FALSE;
1706}
1707
1708static Eina_Bool
1709_ecore_con_ssl_server_crl_add_openssl(Ecore_Con_Server *svr,
1710 const char *crl_file)
1711{
1712 X509_STORE *st;
1713 X509_LOOKUP *lu;
1714 static Eina_Bool flag = EINA_FALSE;
1715
1716 SSL_ERROR_CHECK_GOTO_ERROR(!(st = SSL_CTX_get_cert_store(svr->ssl_ctx)));
1717 SSL_ERROR_CHECK_GOTO_ERROR(!(lu = X509_STORE_add_lookup(st, X509_LOOKUP_file())));
1718 SSL_ERROR_CHECK_GOTO_ERROR(X509_load_crl_file(lu, crl_file, X509_FILETYPE_PEM) < 1);
1719 if (!flag)
1720 {
1721 X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1722 flag = EINA_TRUE;
1723 }
1724
1725 return EINA_TRUE;
1726
1727error:
1728 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1729 return EINA_FALSE;
1730}
1731
1732static Eina_Bool
1733_ecore_con_ssl_server_privkey_add_openssl(Ecore_Con_Server *svr,
1734 const char *key_file)
1735{
1736 FILE *fp = NULL;
1737 EVP_PKEY *privkey = NULL;
1738
1739 if (!(fp = fopen(key_file, "r")))
1740 goto error;
1741
1742 SSL_ERROR_CHECK_GOTO_ERROR(!(privkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)));
1743
1744 fclose(fp);
1745 SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_PrivateKey(svr->ssl_ctx, privkey) < 1);
1746 SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_check_private_key(svr->ssl_ctx) < 1);
1747
1748 return EINA_TRUE;
1749
1750error:
1751 if (fp)
1752 fclose(fp);
1753 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1754 return EINA_FALSE;
1755}
1756
1757static Eina_Bool
1758_ecore_con_ssl_server_cert_add_openssl(Ecore_Con_Server *svr,
1759 const char *cert_file)
1760{
1761 FILE *fp = NULL;
1762 X509 *cert = NULL;
1763
1764 if (!(fp = fopen(cert_file, "r")))
1765 goto error;
1766
1767 SSL_ERROR_CHECK_GOTO_ERROR(!(cert = PEM_read_X509(fp, NULL, NULL, NULL)));
1768
1769 fclose(fp);
1770
1771 SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(svr->ssl_ctx, cert) < 1);
1772
1773 return EINA_TRUE;
1774
1775error:
1776 if (fp)
1777 fclose(fp);
1778 _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR);
1779 return EINA_FALSE;
1780}
1781
1782static Ecore_Con_Ssl_Error
1783_ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
1784{
1785 if (svr->ssl)
1786 {
1787 if (!SSL_shutdown(svr->ssl))
1788 SSL_shutdown(svr->ssl);
1789
1790 SSL_free(svr->ssl);
1791 }
1792
1793 if (svr->ssl_ctx)
1794 SSL_CTX_free(svr->ssl_ctx);
1795
1796 svr->ssl = NULL;
1797 svr->ssl_ctx = NULL;
1798 svr->ssl_err = SSL_ERROR_NONE;
1799
1800 return ECORE_CON_SSL_ERROR_NONE;
1801}
1802
1803static int
1804_ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr,
1805 unsigned char *buf,
1806 int size)
1807{
1808 int num;
1809
1810 if (!svr->ssl) return -1;
1811 num = SSL_read(svr->ssl, buf, size);
1812 svr->ssl_err = SSL_get_error(svr->ssl, num);
1813
1814 if (svr->fd_handler)
1815 {
1816 if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
1817 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1818 else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
1819 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1820 }
1821
1822 if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1823 (svr->ssl_err == SSL_ERROR_SYSCALL) ||
1824 (svr->ssl_err == SSL_ERROR_SSL))
1825 return -1;
1826
1827 if (num < 0)
1828 return 0;
1829
1830 return num;
1831}
1832
1833static int
1834_ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr,
1835 const unsigned char *buf,
1836 int size)
1837{
1838 int num;
1839
1840 num = SSL_write(svr->ssl, buf, size);
1841 svr->ssl_err = SSL_get_error(svr->ssl, num);
1842
1843 if (svr->fd_handler)
1844 {
1845 if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
1846 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1847 else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
1848 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1849 }
1850
1851 if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1852 (svr->ssl_err == SSL_ERROR_SYSCALL) ||
1853 (svr->ssl_err == SSL_ERROR_SSL))
1854 return -1;
1855
1856 if (num < 0)
1857 return 0;
1858
1859 return num;
1860}
1861
1862static Ecore_Con_Ssl_Error
1863_ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
1864{
1865 int ret = -1;
1866 switch (cl->ssl_state)
1867 {
1868 case ECORE_CON_SSL_STATE_DONE:
1869 return ECORE_CON_SSL_ERROR_NONE;
1870
1871 case ECORE_CON_SSL_STATE_INIT:
1872 SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx)));
1873
1874 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd));
1875 SSL_set_accept_state(cl->ssl);
1876 cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
1877
1878 case ECORE_CON_SSL_STATE_HANDSHAKING:
1879 if (!cl->ssl)
1880 {
1881 DBG("Client was previously lost, going to error condition");
1882 goto error;
1883 }
1884 ret = SSL_do_handshake(cl->ssl);
1885 cl->ssl_err = SSL_get_error(cl->ssl, ret);
1886 SSL_ERROR_CHECK_GOTO_ERROR((cl->ssl_err == SSL_ERROR_SYSCALL) || (cl->ssl_err == SSL_ERROR_SSL));
1887 if (ret == 1)
1888 {
1889 cl->handshaking = EINA_FALSE;
1890 cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
1891 }
1892 else
1893 {
1894 if (cl->ssl_err == SSL_ERROR_WANT_READ)
1895 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1896 else if (cl->ssl_err == SSL_ERROR_WANT_WRITE)
1897 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1898 return ECORE_CON_SSL_ERROR_NONE;
1899 }
1900
1901 default:
1902 break;
1903 }
1904
1905 _openssl_print_session(cl->ssl);
1906 if (!cl->host_server->verify)
1907 /* not verifying certificates, so we're done! */
1908 return ECORE_CON_SSL_ERROR_NONE;
1909 SSL_set_verify(cl->ssl, SSL_VERIFY_PEER, NULL);
1910 /* use CRL/CA lists to verify */
1911 if (SSL_get_peer_certificate(cl->ssl))
1912 {
1913 int err;
1914
1915 err = SSL_get_verify_result(cl->ssl);
1916 _openssl_print_verify_error(err);
1917 SSL_ERROR_CHECK_GOTO_ERROR(err);
1918 }
1919
1920 return ECORE_CON_SSL_ERROR_NONE;
1921
1922error:
1923 _openssl_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR);
1924 _ecore_con_ssl_client_shutdown_openssl(cl);
1925 return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
1926}
1927
1928static Ecore_Con_Ssl_Error
1929_ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
1930{
1931 if (cl->ssl)
1932 {
1933 if (!SSL_shutdown(cl->ssl))
1934 SSL_shutdown(cl->ssl);
1935
1936 SSL_free(cl->ssl);
1937 }
1938
1939 cl->ssl = NULL;
1940 cl->ssl_err = SSL_ERROR_NONE;
1941
1942 return ECORE_CON_SSL_ERROR_NONE;
1943}
1944
1945static int
1946_ecore_con_ssl_client_read_openssl(Ecore_Con_Client *cl,
1947 unsigned char *buf,
1948 int size)
1949{
1950 int num;
1951
1952 if (!cl->ssl) return -1;
1953 num = SSL_read(cl->ssl, buf, size);
1954 cl->ssl_err = SSL_get_error(cl->ssl, num);
1955
1956 if (cl->fd_handler)
1957 {
1958 if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
1959 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1960 else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
1961 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1962 }
1963
1964 if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1965 (cl->ssl_err == SSL_ERROR_SYSCALL) ||
1966 (cl->ssl_err == SSL_ERROR_SSL))
1967 return -1;
1968
1969 if (num < 0)
1970 return 0;
1971
1972 return num;
1973}
1974
1975static int
1976_ecore_con_ssl_client_write_openssl(Ecore_Con_Client *cl,
1977 const unsigned char *buf,
1978 int size)
1979{
1980 int num;
1981
1982 num = SSL_write(cl->ssl, buf, size);
1983 cl->ssl_err = SSL_get_error(cl->ssl, num);
1984
1985 if (cl->fd_handler)
1986 {
1987 if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
1988 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1989 else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
1990 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
1991 }
1992
1993 if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
1994 (cl->ssl_err == SSL_ERROR_SYSCALL) ||
1995 (cl->ssl_err == SSL_ERROR_SSL))
1996 return -1;
1997
1998 if (num < 0)
1999 return 0;
2000
2001 return num;
2002}
2003
2004#else
2005
2006/*
2007 * No Ssl
2008 */
2009
2010static Ecore_Con_Ssl_Error
2011_ecore_con_ssl_init_none(void)
2012{
2013 return ECORE_CON_SSL_ERROR_NONE;
2014}
2015
2016static Ecore_Con_Ssl_Error
2017_ecore_con_ssl_shutdown_none(void)
2018{
2019 return ECORE_CON_SSL_ERROR_NONE;
2020}
2021
2022static Ecore_Con_Ssl_Error
2023_ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr __UNUSED__,
2024 int ssl_type __UNUSED__)
2025{
2026 return ECORE_CON_SSL_ERROR_NONE;
2027}
2028
2029static Ecore_Con_Ssl_Error
2030_ecore_con_ssl_server_init_none(Ecore_Con_Server *svr __UNUSED__)
2031{
2032 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
2033}
2034
2035static Eina_Bool
2036_ecore_con_ssl_server_cafile_add_none(Ecore_Con_Server *svr __UNUSED__,
2037 const char *ca_file __UNUSED__)
2038{
2039 return EINA_FALSE;
2040}
2041
2042static Eina_Bool
2043_ecore_con_ssl_server_cert_add_none(Ecore_Con_Server *svr __UNUSED__,
2044 const char *cert_file __UNUSED__)
2045{
2046 return EINA_FALSE;
2047}
2048
2049static Eina_Bool
2050_ecore_con_ssl_server_privkey_add_none(Ecore_Con_Server *svr __UNUSED__,
2051 const char *key_file __UNUSED__)
2052{
2053 return EINA_FALSE;
2054}
2055
2056static Eina_Bool
2057_ecore_con_ssl_server_crl_add_none(Ecore_Con_Server *svr __UNUSED__,
2058 const char *crl_file __UNUSED__)
2059{
2060 return EINA_FALSE;
2061}
2062
2063static Ecore_Con_Ssl_Error
2064_ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr __UNUSED__)
2065{
2066 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
2067}
2068
2069static int
2070_ecore_con_ssl_server_read_none(Ecore_Con_Server *svr __UNUSED__,
2071 unsigned char *buf __UNUSED__,
2072 int size __UNUSED__)
2073{
2074 return -1;
2075}
2076
2077static int
2078_ecore_con_ssl_server_write_none(Ecore_Con_Server *svr __UNUSED__,
2079 const unsigned char *buf __UNUSED__,
2080 int size __UNUSED__)
2081{
2082 return -1;
2083}
2084
2085static Ecore_Con_Ssl_Error
2086_ecore_con_ssl_client_init_none(Ecore_Con_Client *cl __UNUSED__)
2087{
2088 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
2089}
2090
2091static Ecore_Con_Ssl_Error
2092_ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl __UNUSED__)
2093{
2094 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
2095}
2096
2097static int
2098_ecore_con_ssl_client_read_none(Ecore_Con_Client *cl __UNUSED__,
2099 unsigned char *buf __UNUSED__,
2100 int size __UNUSED__)
2101{
2102 return -1;
2103}
2104
2105static int
2106_ecore_con_ssl_client_write_none(Ecore_Con_Client *cl __UNUSED__,
2107 const unsigned char *buf __UNUSED__,
2108 int size __UNUSED__)
2109{
2110 return -1;
2111}
2112
2113#endif
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_url.c b/libraries/ecore/src/lib/ecore_con/ecore_con_url.c
deleted file mode 100644
index 05f0678..0000000
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_url.c
+++ /dev/null
@@ -1,1635 +0,0 @@
1/*
2 * For info on how to use libcurl, see:
3 * http://curl.haxx.se/libcurl/c/libcurl-tutorial.html
4 */
5
6/*
7 * FIXME: Support more CURL features...
8 */
9
10#ifdef HAVE_CONFIG_H
11# include <config.h>
12#endif
13
14#include <string.h>
15#include <errno.h>
16#include <sys/stat.h>
17#include <sys/types.h>
18#include <unistd.h>
19
20#ifdef HAVE_WS2TCPIP_H
21# include <ws2tcpip.h>
22#endif
23
24#ifdef HAVE_ESCAPE
25# include <Escape.h>
26#endif
27
28#include "Ecore.h"
29#include "ecore_private.h"
30#include "Ecore_Con.h"
31#include "ecore_con_private.h"
32
33#define CURL_MIN_TIMEOUT 100
34
35int ECORE_CON_EVENT_URL_DATA = 0;
36int ECORE_CON_EVENT_URL_COMPLETE = 0;
37int ECORE_CON_EVENT_URL_PROGRESS = 0;
38
39#ifdef HAVE_CURL
40static void _ecore_con_url_event_url_complete(Ecore_Con_Url *url_con, CURLMsg *curlmsg);
41static void _ecore_con_url_multi_remove(Ecore_Con_Url *url_con);
42static Eina_Bool _ecore_con_url_perform(Ecore_Con_Url *url_con);
43static size_t _ecore_con_url_header_cb(void *ptr, size_t size, size_t nitems, void *stream);
44static size_t _ecore_con_url_data_cb(void *buffer, size_t size, size_t nitems, void *userp);
45static int _ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
46static size_t _ecore_con_url_read_cb(void *ptr, size_t size, size_t nitems, void *stream);
47static void _ecore_con_event_url_free(Ecore_Con_Url *url_con, void *ev);
48static Eina_Bool _ecore_con_url_timer(void *data);
49static Eina_Bool _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
50static Eina_Bool _ecore_con_url_timeout_cb(void *data);
51static void _ecore_con_url_status_get(Ecore_Con_Url *url_con);
52
53static Eina_List *_url_con_list = NULL;
54static Eina_List *_fd_hd_list = NULL;
55static CURLM *_curlm = NULL;
56static int _init_count = 0;
57static Ecore_Timer *_curl_timer = NULL;
58static Eina_Bool pipelining = EINA_FALSE;
59
60#endif
61
62/**
63 * @addtogroup Ecore_Con_Url_Group Ecore URL Connection Functions
64 *
65 * @{
66 */
67
68EAPI int
69ecore_con_url_init(void)
70{
71#ifdef HAVE_CURL
72 long ms;
73 if (++_init_count > 1) return _init_count;
74
75 ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
76 ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
77 ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new();
78
79 // curl_global_init() is not thread safe!
80 if (curl_global_init(CURL_GLOBAL_ALL)) return --_init_count;
81
82 _curlm = curl_multi_init();
83 if (!_curlm)
84 {
85 curl_global_cleanup();
86 return --_init_count;
87 }
88
89 curl_multi_timeout(_curlm, &ms);
90 if (ms >= CURL_MIN_TIMEOUT || ms <= 0) ms = CURL_MIN_TIMEOUT;
91
92 _curl_timer = ecore_timer_add((double)ms / 1000, _ecore_con_url_timer, NULL);
93 ecore_timer_freeze(_curl_timer);
94
95 return _init_count;
96#else
97 return 0;
98#endif
99}
100
101EAPI int
102ecore_con_url_shutdown(void)
103{
104#ifdef HAVE_CURL
105 Ecore_Con_Url *url_con;
106 Ecore_Fd_Handler *fd_handler;
107 if (_init_count == 0) return 0;
108 --_init_count;
109 if (_init_count) return _init_count;
110
111 if (_curl_timer)
112 {
113 ecore_timer_del(_curl_timer);
114 _curl_timer = NULL;
115 }
116
117 EINA_LIST_FREE(_url_con_list, url_con)
118 ecore_con_url_free(url_con);
119 EINA_LIST_FREE(_fd_hd_list, fd_handler)
120 ecore_main_fd_handler_del(fd_handler);
121
122 if (_curlm)
123 {
124 curl_multi_cleanup(_curlm);
125 _curlm = NULL;
126 }
127 curl_global_cleanup();
128 return 0;
129#endif
130 return 1;
131}
132
133EAPI void
134ecore_con_url_pipeline_set(Eina_Bool enable)
135{
136#ifdef HAVE_CURL
137 if (enable == pipelining) return;
138 curl_multi_setopt(_curlm, CURLMOPT_PIPELINING, !!enable);
139 pipelining = enable;
140#else
141 return;
142 (void)enable;
143#endif
144}
145
146EAPI Eina_Bool
147ecore_con_url_pipeline_get(void)
148{
149#ifdef HAVE_CURL
150 return pipelining;
151#endif
152 return EINA_FALSE;
153}
154
155extern Ecore_Con_Socks *_ecore_con_proxy_global;
156
157EAPI Ecore_Con_Url *
158ecore_con_url_new(const char *url)
159{
160#ifdef HAVE_CURL
161 Ecore_Con_Url *url_con;
162 CURLcode ret;
163
164 if (!_init_count)
165 return NULL;
166
167 url_con = calloc(1, sizeof(Ecore_Con_Url));
168 if (!url_con)
169 return NULL;
170
171 url_con->write_fd = -1;
172
173 url_con->curl_easy = curl_easy_init();
174 if (!url_con->curl_easy)
175 {
176 free(url_con);
177 return NULL;
178 }
179
180 ECORE_MAGIC_SET(url_con, ECORE_MAGIC_CON_URL);
181
182 if (!ecore_con_url_url_set(url_con, url))
183 {
184 ecore_con_url_free(url_con);
185 return NULL;
186 }
187
188 // Read socks proxy
189 url_con->proxy_type = -1;
190 if (_ecore_con_proxy_global && _ecore_con_proxy_global->ip &&
191 (_ecore_con_proxy_global->version == 4 ||
192 _ecore_con_proxy_global->version == 5))
193 {
194 char proxy[256];
195 char host[256];
196
197 if (_ecore_con_proxy_global->version == 5)
198 {
199 if (_ecore_con_proxy_global->lookup)
200 snprintf(host, sizeof(host), "socks5h://%s",
201 _ecore_con_proxy_global->ip);
202 else snprintf(host, sizeof(host), "socks5://%s",
203 _ecore_con_proxy_global->ip);
204 }
205 else if (_ecore_con_proxy_global->version == 4)
206 {
207 if (_ecore_con_proxy_global->lookup)
208 snprintf(host, sizeof(host), "socks4a://%s",
209 _ecore_con_proxy_global->ip);
210 else snprintf(host, sizeof(host), "socks4://%s",
211 _ecore_con_proxy_global->ip);
212 }
213
214 if (_ecore_con_proxy_global->port > 0 &&
215 _ecore_con_proxy_global->port <= 65535)
216 snprintf(proxy, sizeof(proxy), "%s:%d", host,
217 _ecore_con_proxy_global->port);
218 else snprintf(proxy, sizeof(proxy), "%s", host);
219
220 ecore_con_url_proxy_set(url_con, proxy);
221 ecore_con_url_proxy_username_set(url_con,
222 _ecore_con_proxy_global->username);
223 }
224
225 ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate");
226 if (ret != CURLE_OK)
227 {
228 ERR("Could not set CURLOPT_ENCODING to \"gzip,deflate\": %s",
229 curl_easy_strerror(ret));
230 ecore_con_url_free(url_con);
231 return NULL;
232 }
233
234 curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEFUNCTION,
235 _ecore_con_url_data_cb);
236 curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEDATA, url_con);
237
238 curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION,
239 _ecore_con_url_progress_cb);
240 curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSDATA, url_con);
241 curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_FALSE);
242
243 curl_easy_setopt(url_con->curl_easy, CURLOPT_HEADERFUNCTION,
244 _ecore_con_url_header_cb);
245 curl_easy_setopt(url_con->curl_easy, CURLOPT_HEADERDATA, url_con);
246
247 /*
248 * FIXME: Check that these timeouts are sensible defaults
249 * FIXME: Provide a means to change these timeouts
250 */
251 curl_easy_setopt(url_con->curl_easy, CURLOPT_CONNECTTIMEOUT, 30);
252 curl_easy_setopt(url_con->curl_easy, CURLOPT_FOLLOWLOCATION, 1);
253
254 return url_con;
255#else
256 return NULL;
257 url = NULL;
258#endif
259}
260
261EAPI Ecore_Con_Url *
262ecore_con_url_custom_new(const char *url,
263 const char *custom_request)
264{
265#ifdef HAVE_CURL
266 Ecore_Con_Url *url_con;
267 CURLcode ret;
268
269 if (!url)
270 return NULL;
271
272 if (!custom_request)
273 return NULL;
274
275 url_con = ecore_con_url_new(url);
276
277 if (!url_con)
278 return NULL;
279
280 ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_CUSTOMREQUEST, custom_request);
281 if (ret != CURLE_OK)
282 {
283 ERR("Could not set a custom request string: %s",
284 curl_easy_strerror(ret));
285 ecore_con_url_free(url_con);
286 return NULL;
287 }
288
289 return url_con;
290#else
291 return NULL;
292 url = NULL;
293 custom_request = NULL;
294#endif
295}
296
297EAPI void
298ecore_con_url_free(Ecore_Con_Url *url_con)
299{
300#ifdef HAVE_CURL
301 char *s;
302
303 if (!url_con) return;
304
305 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
306 {
307 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_free");
308 return;
309 }
310
311 if (url_con->curl_easy)
312 {
313 // FIXME : How can we delete curl_easy's fds ?? (Curl do not give this info.)
314 // This cause "Failed to delete epoll fd xx!" error messages
315 curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL);
316 curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_TRUE);
317
318 if (url_con->multi)
319 {
320 _ecore_con_url_multi_remove(url_con);
321 _url_con_list = eina_list_remove(_url_con_list, url_con);
322 }
323
324 curl_easy_cleanup(url_con->curl_easy);
325 }
326 if (url_con->timer) ecore_timer_del(url_con->timer);
327
328 url_con->curl_easy = NULL;
329 url_con->timer = NULL;
330 url_con->dead = EINA_TRUE;
331 if (url_con->event_count) return;
332 ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
333
334 curl_slist_free_all(url_con->headers);
335 EINA_LIST_FREE(url_con->additional_headers, s)
336 free(s);
337 EINA_LIST_FREE(url_con->response_headers, s)
338 free(s);
339 eina_stringshare_del(url_con->url);
340 if (url_con->post_data) free(url_con->post_data);
341 free(url_con);
342#else
343 return;
344 (void)url_con;
345#endif
346}
347
348EAPI const char *
349ecore_con_url_url_get(Ecore_Con_Url *url_con)
350{
351#ifdef HAVE_CURL
352 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
353 {
354 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, __func__);
355 return NULL;
356 }
357 return url_con->url;
358#else
359 return NULL;
360 (void)url_con;
361#endif
362}
363
364EAPI int
365ecore_con_url_status_code_get(Ecore_Con_Url *url_con)
366{
367#ifdef HAVE_CURL
368 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
369 {
370 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, __func__);
371 return 0;
372 }
373
374 if (url_con->status) return url_con->status;
375 _ecore_con_url_status_get(url_con);
376 return url_con->status;
377#else
378 return -1;
379 (void)url_con;
380#endif
381}
382
383EAPI Eina_Bool
384ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url)
385{
386#ifdef HAVE_CURL
387 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
388 {
389 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_url_set");
390 return EINA_FALSE;
391 }
392
393 if (url_con->dead) return EINA_FALSE;
394 eina_stringshare_replace(&url_con->url, url);
395
396 if (url_con->url)
397 curl_easy_setopt(url_con->curl_easy, CURLOPT_URL,
398 url_con->url);
399 else
400 curl_easy_setopt(url_con->curl_easy, CURLOPT_URL, "");
401
402 return EINA_TRUE;
403#else
404 return EINA_FALSE;
405 (void)url;
406 (void)url_con;
407#endif
408}
409
410EAPI void
411ecore_con_url_data_set(Ecore_Con_Url *url_con, void *data)
412{
413#ifdef HAVE_CURL
414 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
415 {
416 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_set");
417 return;
418 }
419
420 url_con->data = data;
421#else
422 return;
423 url_con = NULL;
424 data = NULL;
425#endif
426}
427
428EAPI void
429ecore_con_url_additional_header_add(Ecore_Con_Url *url_con, const char *key, const char *value)
430{
431#ifdef HAVE_CURL
432 char *tmp;
433
434 if (url_con->dead) return;
435 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
436 {
437 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
438 "ecore_con_url_additional_header_add");
439 return;
440 }
441
442 if (url_con->dead) return;
443 tmp = malloc(strlen(key) + strlen(value) + 3);
444 if (!tmp)
445 return;
446
447 sprintf(tmp, "%s: %s", key, value);
448 url_con->additional_headers = eina_list_append(url_con->additional_headers,
449 tmp);
450#else
451 return;
452 url_con = NULL;
453 key = NULL;
454 value = NULL;
455#endif
456}
457
458EAPI void
459ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con)
460{
461#ifdef HAVE_CURL
462 char *s;
463
464 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
465 {
466 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
467 "ecore_con_url_additional_headers_clear");
468 return;
469 }
470
471 EINA_LIST_FREE(url_con->additional_headers, s)
472 free(s);
473#else
474 return;
475 url_con = NULL;
476#endif
477}
478
479EAPI void *
480ecore_con_url_data_get(Ecore_Con_Url *url_con)
481{
482#ifdef HAVE_CURL
483 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
484 {
485 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_get");
486 return NULL;
487 }
488
489 return url_con->data;
490#else
491 return NULL;
492 url_con = NULL;
493#endif
494}
495
496EAPI void
497ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, double timestamp)
498{
499#ifdef HAVE_CURL
500 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
501 {
502 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_time");
503 return;
504 }
505
506 if (url_con->dead) return;
507 url_con->time_condition = condition;
508 url_con->timestamp = timestamp;
509#else
510 return;
511 (void)url_con;
512 (void)condition;
513 (void)timestamp;
514#endif
515}
516
517EAPI void
518ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd)
519{
520#ifdef HAVE_CURL
521 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
522 {
523 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_set");
524 return;
525 }
526
527 if (url_con->dead) return;
528 url_con->write_fd = fd;
529#else
530 return;
531 (void)url_con;
532 (void)fd;
533#endif
534}
535
536EAPI int
537ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con)
538{
539#ifdef HAVE_CURL
540 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
541 {
542 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
543 "ecore_con_url_received_bytes_get");
544 return -1;
545 }
546
547 return url_con->received;
548#else
549 return 0;
550 (void)url_con;
551#endif
552}
553
554EAPI const Eina_List *
555ecore_con_url_response_headers_get(Ecore_Con_Url *url_con)
556{
557#ifdef HAVE_CURL
558 return url_con->response_headers;
559#else
560 return NULL;
561 (void)url_con;
562#endif
563}
564
565EAPI Eina_Bool
566ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, const char *username, const char *password, Eina_Bool safe)
567{
568#ifdef HAVE_CURL
569 CURLcode ret;
570
571 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
572 {
573 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
574 "ecore_con_url_httpauth_set");
575 return EINA_FALSE;
576 }
577
578 if (url_con->dead) return EINA_FALSE;
579# if LIBCURL_VERSION_NUM >= 0x071301
580 if ((username) && (password))
581 {
582 if (safe)
583 curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPAUTH,
584 CURLAUTH_ANYSAFE);
585 else
586 curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
587
588 ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERNAME, username);
589 if (ret != CURLE_OK)
590 {
591 ERR("Could not set username for HTTP authentication: %s",
592 curl_easy_strerror(ret));
593 return EINA_FALSE;
594 }
595
596 ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_PASSWORD, password);
597 if (ret != CURLE_OK)
598 {
599 ERR("Could not set password for HTTP authentication: %s",
600 curl_easy_strerror(ret));
601 return EINA_FALSE;
602 }
603
604 return EINA_TRUE;
605 }
606# endif
607#else
608 return EINA_FALSE;
609 (void)url_con;
610 (void)username;
611 (void)password;
612 (void)safe;
613#endif
614
615 return EINA_FALSE;
616}
617
618#define MODE_AUTO 0
619#define MODE_GET 1
620#define MODE_POST 2
621
622static Eina_Bool
623_ecore_con_url_send(Ecore_Con_Url *url_con, int mode, const void *data, long length, const char *content_type)
624{
625#ifdef HAVE_CURL
626 Eina_List *l;
627 const char *s;
628 char tmp[512];
629
630 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
631 {
632 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_send");
633 return EINA_FALSE;
634 }
635
636 if (!url_con->url) return EINA_FALSE;
637 if (url_con->dead) return EINA_FALSE;
638
639 /* Free response headers from previous send() calls */
640 EINA_LIST_FREE(url_con->response_headers, s)
641 free((char *)s);
642 url_con->response_headers = NULL;
643 url_con->status = 0;
644
645 curl_slist_free_all(url_con->headers);
646 url_con->headers = NULL;
647
648 if ((mode == MODE_POST) || (mode == MODE_AUTO))
649 {
650 if (url_con->post_data) free(url_con->post_data);
651 url_con->post_data = NULL;
652 if ((data) && (length > 0))
653 {
654 url_con->post_data = malloc(length);
655 if (url_con->post_data)
656 {
657 memcpy(url_con->post_data, data, length);
658 if ((content_type) && (strlen(content_type) < 450))
659 {
660 snprintf(tmp, sizeof(tmp), "Content-Type: %s", content_type);
661 url_con->headers = curl_slist_append(url_con->headers, tmp);
662 }
663 curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, url_con->post_data);
664 curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, length);
665 }
666 else
667 return EINA_FALSE;
668 }
669 else curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, 0);
670 if (mode == MODE_POST)
671 curl_easy_setopt(url_con->curl_easy, CURLOPT_POST, 1);
672 }
673
674 switch (url_con->time_condition)
675 {
676 case ECORE_CON_URL_TIME_NONE:
677 curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION,
678 CURL_TIMECOND_NONE);
679 break;
680
681 case ECORE_CON_URL_TIME_IFMODSINCE:
682 curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION,
683 CURL_TIMECOND_IFMODSINCE);
684 curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE,
685 (long)url_con->timestamp);
686 break;
687
688 case ECORE_CON_URL_TIME_IFUNMODSINCE:
689 curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION,
690 CURL_TIMECOND_IFUNMODSINCE);
691 curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE,
692 (long)url_con->timestamp);
693 break;
694 }
695
696 /* Additional headers */
697 EINA_LIST_FOREACH(url_con->additional_headers, l, s)
698 url_con->headers = curl_slist_append(url_con->headers, s);
699
700 curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPHEADER, url_con->headers);
701
702 url_con->received = 0;
703
704 return _ecore_con_url_perform(url_con);
705#else
706 return EINA_FALSE;
707 (void)url_con;
708 (void)mode;
709 (void)data;
710 (void)length;
711 (void)content_type;
712#endif
713}
714
715EAPI Eina_Bool
716ecore_con_url_get(Ecore_Con_Url *url_con)
717{
718 return _ecore_con_url_send(url_con, MODE_GET, NULL, 0, NULL);
719}
720
721EAPI Eina_Bool
722ecore_con_url_post(Ecore_Con_Url *url_con, const void *data, long length, const char *content_type)
723{
724 return _ecore_con_url_send(url_con, MODE_POST, data, length, content_type);
725}
726
727EAPI Eina_Bool
728ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, const char *filename, const char *user, const char *pass, const char *upload_dir)
729{
730#ifdef HAVE_CURL
731 char url[4096];
732 char userpwd[4096];
733 FILE *fd;
734 struct stat file_info;
735 CURLcode ret;
736
737 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
738 {
739 ECORE_MAGIC_FAIL(url_con,
740 ECORE_MAGIC_CON_URL,
741 "ecore_con_url_ftp_upload");
742 return EINA_FALSE;
743 }
744
745 if (url_con->dead) return EINA_FALSE;
746 if (!url_con->url) return EINA_FALSE;
747 if ((!filename) || (!filename[0])) return EINA_FALSE;
748
749 if (stat(filename, &file_info))
750 return EINA_FALSE;
751
752 snprintf(userpwd, sizeof(userpwd), "%s:%s", user, pass);
753 ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERPWD, userpwd);
754 if (ret != CURLE_OK)
755 {
756 ERR("Could not set username and password for FTP upload: %s",
757 curl_easy_strerror(ret));
758 return EINA_FALSE;
759 }
760
761 char tmp[PATH_MAX];
762 snprintf(tmp, PATH_MAX, "%s", filename);
763
764 if (upload_dir)
765 snprintf(url, sizeof(url), "ftp://%s/%s/%s", url_con->url,
766 upload_dir, basename(tmp));
767 else
768 snprintf(url, sizeof(url), "ftp://%s/%s", url_con->url,
769 basename(tmp));
770
771 if (!ecore_con_url_url_set(url_con, url))
772 return EINA_FALSE;
773
774 curl_easy_setopt(url_con->curl_easy, CURLOPT_INFILESIZE_LARGE,
775 (curl_off_t)file_info.st_size);
776 curl_easy_setopt(url_con->curl_easy, CURLOPT_UPLOAD, 1);
777 curl_easy_setopt(url_con->curl_easy, CURLOPT_READFUNCTION,
778 _ecore_con_url_read_cb);
779
780 fd = fopen(filename, "rb");
781 if (!fd)
782 {
783 ERR("Could not open \"%s\" for FTP upload", filename);
784 return EINA_FALSE;
785 }
786 curl_easy_setopt(url_con->curl_easy, CURLOPT_READDATA, fd);
787
788 return _ecore_con_url_perform(url_con);
789#else
790 return EINA_FALSE;
791 (void)url_con;
792 (void)filename;
793 (void)user;
794 (void)pass;
795 (void)upload_dir;
796#endif
797}
798
799EAPI void
800ecore_con_url_cookies_init(Ecore_Con_Url *url_con)
801{
802#ifdef HAVE_CURL
803 if (!url_con)
804 return;
805
806 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
807 {
808 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
809 "ecore_con_url_cookies_init");
810 return;
811 }
812
813 if (url_con->dead) return;
814 curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, "");
815#else
816 return;
817 (void)url_con;
818#endif
819}
820
821EAPI void
822ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, Eina_Bool ignore)
823{
824#ifdef HAVE_CURL
825 if (!url_con)
826 return;
827
828 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
829 {
830 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
831 "ecore_con_url_cookies_ignore_old_session_set");
832 return;
833 }
834
835 if (url_con->dead) return;
836 curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIESESSION, ignore);
837#else
838 return;
839 (void)url_con;
840 (void)ignore;
841#endif
842}
843
844EAPI void
845ecore_con_url_cookies_clear(Ecore_Con_Url *url_con)
846{
847#ifdef HAVE_CURL
848 if (!url_con)
849 return;
850
851 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
852 {
853 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
854 "ecore_con_url_cookies_clear");
855 return;
856 }
857
858 if (url_con->dead) return;
859 curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "ALL");
860#else
861 return;
862 (void)url_con;
863#endif
864}
865
866EAPI void
867ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con)
868{
869#ifdef HAVE_CURL
870 if (!url_con)
871 return;
872
873 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
874 {
875 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
876 "ecore_con_url_cookies_session_clear");
877 return;
878 }
879
880 if (url_con->dead) return;
881 curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "SESS");
882#else
883 return;
884 (void)url_con;
885#endif
886}
887
888EAPI void
889ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, const char *const file_name)
890{
891#ifdef HAVE_CURL
892 if (!url_con)
893 return;
894
895 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
896 {
897 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
898 "ecore_con_url_cookies_file_add");
899 return;
900 }
901
902 if (url_con->dead) return;
903 curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, file_name);
904#else
905 return;
906 (void)url_con;
907 (void)file_name;
908#endif
909}
910
911EAPI Eina_Bool
912ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, const char *const cookiejar_file)
913{
914#ifdef HAVE_CURL
915 CURLcode ret;
916
917 if (!url_con)
918 return EINA_FALSE;
919
920 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
921 {
922 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
923 "ecore_con_url_cookies_jar_file_set");
924 return EINA_FALSE;
925 }
926
927 if (url_con->dead) return EINA_FALSE;
928 ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEJAR,
929 cookiejar_file);
930 if (ret != CURLE_OK)
931 {
932 ERR("Setting the cookie-jar name failed: %s",
933 curl_easy_strerror(ret));
934 return EINA_FALSE;
935 }
936
937 return EINA_TRUE;
938#else
939 return EINA_FALSE;
940 (void)url_con;
941 (void)cookiejar_file;
942#endif
943}
944
945EAPI void
946ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con)
947{
948#ifdef HAVE_CURL
949 if (!url_con)
950 return;
951
952 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
953 {
954 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
955 "ecore_con_url_cookies_jar_write");
956 return;
957 }
958
959 if (url_con->dead) return;
960 curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "FLUSH");
961#else
962 return;
963 (void)url_con;
964#endif
965}
966
967EAPI void
968ecore_con_url_verbose_set(Ecore_Con_Url *url_con, Eina_Bool verbose)
969{
970#ifdef HAVE_CURL
971 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
972 {
973 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
974 "ecore_con_url_verbose_set");
975 return;
976 }
977
978 if (!url_con->url)
979 return;
980
981 if (url_con->dead) return;
982 curl_easy_setopt(url_con->curl_easy, CURLOPT_VERBOSE, (int)verbose);
983#else
984 return;
985 (void)url_con;
986 (void)verbose;
987#endif
988}
989
990EAPI void
991ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, Eina_Bool use_epsv)
992{
993#ifdef HAVE_CURL
994 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
995 {
996 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
997 "ecore_con_url_ftp_use_epsv_set");
998 return;
999 }
1000
1001 if (!url_con->url)
1002 return;
1003
1004 if (url_con->dead) return;
1005 curl_easy_setopt(url_con->curl_easy, CURLOPT_FTP_USE_EPSV, (int)use_epsv);
1006#else
1007 return;
1008 (void)url_con;
1009 (void)use_epsv;
1010#endif
1011}
1012
1013/**
1014 * Toggle libcurl's verify peer's certificate option.
1015 *
1016 * If @p verify is @c EINA_TRUE, libcurl will verify
1017 * the authenticity of the peer's certificate, otherwise
1018 * it will not. Default behavior of libcurl is to check
1019 * peer's certificate.
1020 *
1021 * @param url_con Ecore_Con_Url instance which will be acted upon.
1022 * @param verify Whether or not libcurl will check peer's certificate.
1023 * @since 1.1.0
1024 */
1025EAPI void
1026ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con, Eina_Bool verify)
1027{
1028#ifdef HAVE_CURL
1029 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1030 {
1031 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL,
1032 "ecore_con_url_ssl_verify_peer_set");
1033 return;
1034 }
1035
1036 if (!url_con->url)
1037 return;
1038
1039 if (url_con->dead) return;
1040 curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, (int)verify);
1041#else
1042 return;
1043 (void)url_con;
1044 (void)verify;
1045#endif
1046}
1047
1048/**
1049 * Set a custom CA to trust for SSL/TLS connections.
1050 *
1051 * Specify the path of a file (in PEM format) containing one or more
1052 * CA certificate(s) to use for the validation of the server certificate.
1053 *
1054 * This function can also disable CA validation if @p ca_path is @c NULL.
1055 * However, the server certificate still needs to be valid for the connection
1056 * to succeed (i.e., the certificate must concern the server the
1057 * connection is made to).
1058 *
1059 * @param url_con Connection object that will use the custom CA.
1060 * @param ca_path Path to a CA certificate(s) file or @c NULL to disable
1061 * CA validation.
1062 *
1063 * @return @c 0 on success. When cURL is used, non-zero return values
1064 * are equal to cURL error codes.
1065 */
1066EAPI int
1067ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path)
1068{
1069 int res = -1;
1070
1071#ifdef HAVE_CURL
1072 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1073 {
1074 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_ssl_ca_set");
1075 return -1;
1076 }
1077
1078 if (!url_con->url) return -1;
1079 if (url_con->dead) return -1;
1080 if (ca_path == NULL)
1081 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 0);
1082 else
1083 {
1084 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 1);
1085 if (!res)
1086 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_CAINFO, ca_path);
1087 }
1088#else
1089 return -1;
1090 (void)url_con;
1091 (void)ca_path;
1092#endif
1093
1094 return res;
1095}
1096
1097EAPI Eina_Bool
1098ecore_con_url_http_version_set(Ecore_Con_Url *url_con, Ecore_Con_Url_Http_Version version)
1099{
1100#ifdef HAVE_CURL
1101 int res = -1;
1102 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1103 {
1104 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_http_version_set");
1105 return EINA_FALSE;
1106 }
1107 if (url_con->dead) return EINA_FALSE;
1108 switch (version)
1109 {
1110 case ECORE_CON_URL_HTTP_VERSION_1_0:
1111 res = curl_easy_setopt(url_con->curl_easy,
1112 CURLOPT_HTTP_VERSION,
1113 CURL_HTTP_VERSION_1_0);
1114 break;
1115
1116 case ECORE_CON_URL_HTTP_VERSION_1_1:
1117 res = curl_easy_setopt(url_con->curl_easy,
1118 CURLOPT_HTTP_VERSION,
1119 CURL_HTTP_VERSION_1_1);
1120 break;
1121
1122 default:
1123 break;
1124 }
1125 if (res != CURLE_OK)
1126 {
1127 ERR("curl http version setting failed: %s", curl_easy_strerror(res));
1128 return EINA_FALSE;
1129 }
1130 return EINA_TRUE;
1131#else
1132 (void)url_con;
1133 (void)version;
1134 return EINA_FALSE;
1135#endif
1136}
1137
1138EAPI Eina_Bool
1139ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy)
1140{
1141#ifdef HAVE_CURL
1142 int res = -1;
1143 curl_version_info_data *vers = NULL;
1144
1145 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1146 {
1147 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_set");
1148 return EINA_FALSE;
1149 }
1150
1151 if (!url_con->url) return EINA_FALSE;
1152 if (url_con->dead) return EINA_FALSE;
1153
1154 if (!proxy) res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, "");
1155 else
1156 {
1157 // before curl version 7.21.7, socks protocol:// prefix is not supported
1158 // (e.g. socks4://, socks4a://, socks5:// or socks5h://, etc.)
1159 vers = curl_version_info(CURLVERSION_NOW);
1160 if (vers->version_num < 0x71507)
1161 {
1162 url_con->proxy_type = CURLPROXY_HTTP;
1163 if (strstr(proxy, "socks4a"))
1164 url_con->proxy_type = CURLPROXY_SOCKS4A;
1165 else if (strstr(proxy, "socks4"))
1166 url_con->proxy_type = CURLPROXY_SOCKS4;
1167 else if (strstr(proxy, "socks5h"))
1168 url_con->proxy_type = CURLPROXY_SOCKS5_HOSTNAME;
1169 else if (strstr(proxy, "socks5"))
1170 url_con->proxy_type = CURLPROXY_SOCKS5;
1171 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXYTYPE,
1172 url_con->proxy_type);
1173 if (res != CURLE_OK)
1174 {
1175 ERR("curl proxy type setting failed: %s",
1176 curl_easy_strerror(res));
1177 url_con->proxy_type = -1;
1178 return EINA_FALSE;
1179 }
1180 }
1181 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, proxy);
1182 }
1183 if (res != CURLE_OK)
1184 {
1185 ERR("curl proxy setting failed: %s", curl_easy_strerror(res));
1186 url_con->proxy_type = -1;
1187 return EINA_FALSE;
1188 }
1189 return EINA_TRUE;
1190#else
1191 return EINA_FALSE;
1192 (void)url_con;
1193 (void)proxy;
1194#endif
1195}
1196
1197EAPI void
1198ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout)
1199{
1200#ifdef HAVE_CURL
1201 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1202 {
1203 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_timeout_set");
1204 return;
1205 }
1206
1207 if (url_con->dead) return;
1208 if (!url_con->url || timeout < 0) return;
1209 if (url_con->timer) ecore_timer_del(url_con->timer);
1210 url_con->timer = ecore_timer_add(timeout, _ecore_con_url_timeout_cb, url_con);
1211#else
1212 return;
1213 (void)url_con;
1214 (void)timeout;
1215#endif
1216}
1217
1218EAPI Eina_Bool
1219ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username)
1220{
1221#ifdef HAVE_CURL
1222 int res = -1;
1223 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1224 {
1225 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_username_set");
1226 return EINA_FALSE;
1227 }
1228
1229 if (url_con->dead) return EINA_FALSE;
1230 if (!url_con->url) return EINA_FALSE;
1231 if ((!username) || (!username[0])) return EINA_FALSE;
1232 if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A)
1233 {
1234 ERR("Proxy type should be socks5 and above");
1235 return EINA_FALSE;
1236 }
1237
1238 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERNAME, username);
1239 if (res != CURLE_OK)
1240 {
1241 ERR("curl_easy_setopt() failed: %s", curl_easy_strerror(res));
1242 return EINA_FALSE;
1243 }
1244 return EINA_TRUE;
1245#else
1246 return EINA_FALSE;
1247 (void)url_con;
1248 (void)username;
1249#endif
1250}
1251
1252EAPI Eina_Bool
1253ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password)
1254{
1255#ifdef HAVE_CURL
1256 int res = -1;
1257 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1258 {
1259 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_password_set");
1260 return EINA_FALSE;
1261 }
1262 if (!url_con->url) return EINA_FALSE;
1263 if (url_con->dead) return EINA_FALSE;
1264 if (!password) return EINA_FALSE;
1265 if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A)
1266 {
1267 ERR("Proxy type should be socks5 and above");
1268 return EINA_FALSE;
1269 }
1270
1271 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PASSWORD, password);
1272 if (res != CURLE_OK)
1273 {
1274 ERR("curl_easy_setopt() failed: %s", curl_easy_strerror(res));
1275 return EINA_FALSE;
1276 }
1277 return EINA_TRUE;
1278#else
1279 return EINA_FALSE;
1280 (void)url_con;
1281 (void)password;
1282#endif
1283}
1284
1285/**
1286 * @}
1287 */
1288
1289#ifdef HAVE_CURL
1290static void
1291_ecore_con_url_status_get(Ecore_Con_Url *url_con)
1292{
1293 long status = 0;
1294
1295 if (!url_con->curl_easy) return;
1296 if (!curl_easy_getinfo(url_con->curl_easy, CURLINFO_RESPONSE_CODE, &status))
1297 url_con->status = status;
1298 else
1299 url_con->status = 0;
1300}
1301
1302static void
1303_ecore_con_url_event_url_complete(Ecore_Con_Url *url_con, CURLMsg *curlmsg)
1304{
1305 Ecore_Con_Event_Url_Complete *e;
1306
1307 e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
1308 if (!e) return;
1309
1310 if (curlmsg && (curlmsg->data.result == CURLE_OK))
1311 {
1312 if (!url_con->status)
1313 _ecore_con_url_status_get(url_con);
1314 }
1315 else if (curlmsg)
1316 ERR("Curl message have errors: %d", curlmsg->data.result);
1317 else
1318 CRIT("THIS IS BAD.");
1319
1320 e->status = url_con->status;
1321 e->url_con = url_con;
1322 url_con->event_count++;
1323 ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con);
1324}
1325
1326static void
1327_ecore_con_url_multi_remove(Ecore_Con_Url *url_con)
1328{
1329 CURLMcode ret;
1330
1331 ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
1332 url_con->multi = EINA_FALSE;
1333 if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
1334}
1335
1336static Eina_Bool
1337_ecore_con_url_timeout_cb(void *data)
1338{
1339 Ecore_Con_Url *url_con = data;
1340
1341 if (!url_con) return ECORE_CALLBACK_CANCEL;
1342 if (!url_con->curl_easy) return ECORE_CALLBACK_CANCEL;
1343
1344 _ecore_con_url_multi_remove(url_con);
1345 _url_con_list = eina_list_remove(_url_con_list, url_con);
1346
1347 curl_slist_free_all(url_con->headers);
1348 url_con->headers = NULL;
1349
1350 url_con->timer = NULL;
1351
1352 _ecore_con_url_event_url_complete(url_con, NULL);
1353 return ECORE_CALLBACK_CANCEL;
1354}
1355
1356static size_t
1357_ecore_con_url_data_cb(void *buffer, size_t size, size_t nitems, void *userp)
1358{
1359 Ecore_Con_Url *url_con;
1360 Ecore_Con_Event_Url_Data *e;
1361 size_t real_size = size * nitems;
1362
1363 url_con = (Ecore_Con_Url *)userp;
1364
1365 if (!url_con)
1366 return -1;
1367
1368 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1369 {
1370 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_cb");
1371 return -1;
1372 }
1373
1374 url_con->received += real_size;
1375
1376 INF("reading from %s", url_con->url);
1377 if (url_con->write_fd < 0)
1378 {
1379 e =
1380 malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) *
1381 (real_size - 1));
1382 if (e)
1383 {
1384 e->url_con = url_con;
1385 e->size = real_size;
1386 memcpy(e->data, buffer, real_size);
1387 url_con->event_count++;
1388 ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con);
1389 }
1390 }
1391 else
1392 {
1393 ssize_t count = 0;
1394 size_t total_size = real_size;
1395 size_t offset = 0;
1396
1397 while (total_size > 0)
1398 {
1399 count = write(url_con->write_fd,
1400 (char *)buffer + offset,
1401 total_size);
1402 if (count < 0)
1403 {
1404 if (errno != EAGAIN && errno != EINTR)
1405 return -1;
1406 }
1407 else
1408 {
1409 total_size -= count;
1410 offset += count;
1411 }
1412 }
1413 }
1414
1415 return real_size;
1416}
1417
1418static size_t
1419_ecore_con_url_header_cb(void *ptr, size_t size, size_t nitems, void *stream)
1420{
1421 size_t real_size = size * nitems;
1422 Ecore_Con_Url *url_con = stream;
1423
1424 char *header = malloc(sizeof(char) * (real_size + 1));
1425 if (!header)
1426 return real_size;
1427
1428 memcpy(header, ptr, real_size);
1429 header[real_size] = '\0';
1430
1431 url_con->response_headers = eina_list_append(url_con->response_headers,
1432 header);
1433
1434 return real_size;
1435}
1436
1437static int
1438_ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
1439{
1440 Ecore_Con_Event_Url_Progress *e;
1441 Ecore_Con_Url *url_con;
1442
1443 url_con = clientp;
1444
1445 e = malloc(sizeof(Ecore_Con_Event_Url_Progress));
1446 if (e)
1447 {
1448 e->url_con = url_con;
1449 e->down.total = dltotal;
1450 e->down.now = dlnow;
1451 e->up.total = ultotal;
1452 e->up.now = ulnow;
1453 url_con->event_count++;
1454 ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con);
1455 }
1456
1457 return 0;
1458}
1459
1460static size_t
1461_ecore_con_url_read_cb(void *ptr, size_t size, size_t nitems, void *stream)
1462{
1463 size_t retcode = fread(ptr, size, nitems, stream);
1464
1465 if (ferror((FILE *)stream))
1466 {
1467 fclose(stream);
1468 return CURL_READFUNC_ABORT;
1469 }
1470 else if (retcode == 0)
1471 {
1472 fclose((FILE *)stream);
1473 return 0;
1474 }
1475
1476#ifdef _WIN32
1477 INF("*** We read %Iu bytes from file", retcode);
1478#else
1479 INF("*** We read %zu bytes from file", retcode);
1480#endif
1481 return retcode;
1482}
1483
1484static void
1485_ecore_con_url_info_read(void)
1486{
1487 CURLMsg *curlmsg;
1488 int n_remaining;
1489
1490 while ((curlmsg = curl_multi_info_read(_curlm, &n_remaining)))
1491 {
1492 Eina_List *l, *ll;
1493 Ecore_Con_Url *url_con = NULL;
1494 DBG("Curl message: %d", curlmsg->msg);
1495
1496 if (curlmsg->msg == CURLMSG_DONE)
1497 {
1498 EINA_LIST_FOREACH_SAFE(_url_con_list, l, ll, url_con)
1499 {
1500 if (curlmsg->easy_handle == url_con->curl_easy)
1501 _ecore_con_url_event_url_complete(url_con, curlmsg);
1502 }
1503 }
1504 }
1505}
1506
1507static void
1508_ecore_con_url_curl_clear(void)
1509{
1510 Ecore_Fd_Handler *fdh;
1511 Ecore_Con_Url *url_con;
1512
1513 EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh);
1514 EINA_LIST_FREE(_url_con_list, url_con) _ecore_con_url_multi_remove(url_con);
1515}
1516
1517static Eina_Bool
1518_ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
1519{
1520 Ecore_Fd_Handler *fdh;
1521 EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh);
1522 ecore_timer_interval_set(_curl_timer, 0.1);
1523 return ECORE_CALLBACK_CANCEL;
1524}
1525
1526static void
1527_ecore_con_url_fdset(void)
1528{
1529 CURLMcode ret;
1530 fd_set read_set, write_set, exc_set;
1531 int fd, fd_max;
1532
1533 FD_ZERO(&read_set);
1534 FD_ZERO(&write_set);
1535 FD_ZERO(&exc_set);
1536
1537 ret = curl_multi_fdset(_curlm, &read_set, &write_set, &exc_set, &fd_max);
1538 if (ret != CURLM_OK)
1539 {
1540 ERR("curl_multi_fdset failed: %s", curl_multi_strerror(ret));
1541 return;
1542 }
1543
1544 for (fd = 0; fd <= fd_max; fd++)
1545 {
1546 int flags = 0;
1547 if (FD_ISSET(fd, &read_set)) flags |= ECORE_FD_READ;
1548 if (FD_ISSET(fd, &write_set)) flags |= ECORE_FD_WRITE;
1549 if (FD_ISSET(fd, &exc_set)) flags |= ECORE_FD_ERROR;
1550 if (flags)
1551 {
1552 // FIXME: Who is owner (easy_handle) of this fd?? (Curl do not give this info.)
1553 // This cause "Failed to delete epoll fd xx!" error messages
1554 Ecore_Fd_Handler *fd_handler;
1555 fd_handler = ecore_main_fd_handler_add(fd, flags,
1556 _ecore_con_url_fd_handler,
1557 NULL, NULL, NULL);
1558 if (fd_handler)
1559 _fd_hd_list = eina_list_append(_fd_hd_list, fd_handler);
1560 }
1561 }
1562}
1563
1564static Eina_Bool
1565_ecore_con_url_timer(void *data __UNUSED__)
1566{
1567 Ecore_Fd_Handler *fdh;
1568 int still_running;
1569 CURLMcode ret;
1570
1571 EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh);
1572 _ecore_con_url_info_read();
1573
1574 ret = curl_multi_perform(_curlm, &still_running);
1575 if (ret == CURLM_CALL_MULTI_PERFORM)
1576 {
1577 DBG("curl_multi_perform() again immediately");
1578 return ECORE_CALLBACK_RENEW;
1579 }
1580 else if (ret != CURLM_OK)
1581 {
1582 ERR("curl_multi_perform() failed: %s", curl_multi_strerror(ret));
1583 _ecore_con_url_curl_clear();
1584 ecore_timer_freeze(_curl_timer);
1585 }
1586
1587 if (still_running)
1588 {
1589 long ms;
1590 _ecore_con_url_fdset();
1591 curl_multi_timeout(_curlm, &ms);
1592 DBG("multiperform is still running: %d, timeout: %ld", still_running, ms);
1593 if (ms >= CURL_MIN_TIMEOUT || ms <= 0) ms = CURL_MIN_TIMEOUT;
1594 ecore_timer_interval_set(_curl_timer, (double)ms / 1000);
1595 }
1596 else
1597 {
1598 DBG("multiperform ended");
1599 _ecore_con_url_info_read();
1600 _ecore_con_url_curl_clear();
1601 ecore_timer_freeze(_curl_timer);
1602 }
1603
1604 return ECORE_CALLBACK_RENEW;
1605}
1606
1607static Eina_Bool
1608_ecore_con_url_perform(Ecore_Con_Url *url_con)
1609{
1610 CURLMcode ret;
1611
1612 ret = curl_multi_add_handle(_curlm, url_con->curl_easy);
1613 if (ret != CURLM_OK)
1614 {
1615 ERR("curl_multi_add_handle() failed: %s", curl_multi_strerror(ret));
1616 return EINA_FALSE;
1617 }
1618
1619 url_con->multi = EINA_TRUE;
1620 _url_con_list = eina_list_append(_url_con_list, url_con);
1621 ecore_timer_thaw(_curl_timer);
1622
1623 return EINA_TRUE;
1624}
1625
1626static void
1627_ecore_con_event_url_free(Ecore_Con_Url *url_con, void *ev)
1628{
1629 free(ev);
1630 url_con->event_count--;
1631 if (url_con->dead && (!url_con->event_count))
1632 ecore_con_url_free(url_con);
1633}
1634
1635#endif