diff options
Diffstat (limited to '')
25 files changed, 16584 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_con/Ecore_Con.h b/libraries/ecore/src/lib/ecore_con/Ecore_Con.h new file mode 100644 index 0000000..e3b68c4 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/Ecore_Con.h | |||
@@ -0,0 +1,1801 @@ | |||
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 | ||
216 | extern "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 | */ | ||
227 | typedef 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 | */ | ||
234 | typedef struct _Ecore_Con_Client Ecore_Con_Client; | ||
235 | |||
236 | /** | ||
237 | * @typedef Ecore_Con_Url | ||
238 | * A handle to an http upload/download object | ||
239 | * @ingroup Ecore_Con_Url_Group | ||
240 | */ | ||
241 | typedef struct _Ecore_Con_Url Ecore_Con_Url; | ||
242 | |||
243 | |||
244 | /** | ||
245 | * @addtogroup Ecore_Con_Events_Group Events | ||
246 | * @{ | ||
247 | */ | ||
248 | |||
249 | /** | ||
250 | * @typedef Ecore_Con_Event_Client_Add | ||
251 | * Used as the @p data param for the corresponding event | ||
252 | */ | ||
253 | typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add; | ||
254 | |||
255 | /** | ||
256 | * @typedef Ecore_Con_Event_Client_Upgrade | ||
257 | * Used as the @p data param for the corresponding event | ||
258 | * @since 1.1 | ||
259 | */ | ||
260 | typedef struct _Ecore_Con_Event_Client_Upgrade Ecore_Con_Event_Client_Upgrade; | ||
261 | |||
262 | /** | ||
263 | * @typedef Ecore_Con_Event_Client_Del | ||
264 | * Used as the @p data param for the corresponding event | ||
265 | */ | ||
266 | typedef struct _Ecore_Con_Event_Client_Del Ecore_Con_Event_Client_Del; | ||
267 | |||
268 | /** | ||
269 | * @typedef Ecore_Con_Event_Client_Error | ||
270 | * Used as the @p data param for the corresponding event | ||
271 | * @since 1.1 | ||
272 | */ | ||
273 | typedef struct _Ecore_Con_Event_Client_Error Ecore_Con_Event_Client_Error; | ||
274 | |||
275 | /** | ||
276 | * @typedef Ecore_Con_Event_Server_Add | ||
277 | * Used as the @p data param for the corresponding event | ||
278 | */ | ||
279 | typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add; | ||
280 | |||
281 | /** | ||
282 | * @typedef Ecore_Con_Event_Server_Upgrade | ||
283 | * Used as the @p data param for the corresponding event | ||
284 | * @since 1.1 | ||
285 | */ | ||
286 | typedef struct _Ecore_Con_Event_Server_Upgrade Ecore_Con_Event_Server_Upgrade; | ||
287 | |||
288 | /** | ||
289 | * @typedef Ecore_Con_Event_Server_Del | ||
290 | * Used as the @p data param for the corresponding event | ||
291 | */ | ||
292 | typedef struct _Ecore_Con_Event_Server_Del Ecore_Con_Event_Server_Del; | ||
293 | |||
294 | /** | ||
295 | * @typedef Ecore_Con_Event_Server_Error | ||
296 | * Used as the @p data param for the corresponding event | ||
297 | * @since 1.1 | ||
298 | */ | ||
299 | typedef struct _Ecore_Con_Event_Server_Error Ecore_Con_Event_Server_Error; | ||
300 | |||
301 | /** | ||
302 | * @typedef Ecore_Con_Event_Client_Data | ||
303 | * Used as the @p data param for the corresponding event | ||
304 | */ | ||
305 | typedef struct _Ecore_Con_Event_Client_Data Ecore_Con_Event_Client_Data; | ||
306 | |||
307 | /** | ||
308 | * @typedef Ecore_Con_Event_Server_Data | ||
309 | * Used as the @p data param for the corresponding event | ||
310 | */ | ||
311 | typedef struct _Ecore_Con_Event_Server_Data Ecore_Con_Event_Server_Data; | ||
312 | |||
313 | /** | ||
314 | * @typedef Ecore_Con_Event_Client_Write | ||
315 | * Used as the @p data param for the corresponding event | ||
316 | * @since 1.1 | ||
317 | */ | ||
318 | typedef struct _Ecore_Con_Event_Client_Write Ecore_Con_Event_Client_Write; | ||
319 | |||
320 | /** | ||
321 | * @typedef Ecore_Con_Event_Server_Write | ||
322 | * Used as the @p data param for the corresponding event | ||
323 | * @since 1.1 | ||
324 | */ | ||
325 | typedef struct _Ecore_Con_Event_Server_Write Ecore_Con_Event_Server_Write; | ||
326 | |||
327 | /** | ||
328 | * @typedef Ecore_Con_Event_Url_Data | ||
329 | * Used as the @p data param for the corresponding event | ||
330 | * @ingroup Ecore_Con_Url_Group | ||
331 | */ | ||
332 | typedef struct _Ecore_Con_Event_Url_Data Ecore_Con_Event_Url_Data; | ||
333 | |||
334 | /** | ||
335 | * @typedef Ecore_Con_Event_Url_Complete | ||
336 | * Used as the @p data param for the corresponding event | ||
337 | * @ingroup Ecore_Con_Url_Group | ||
338 | */ | ||
339 | typedef struct _Ecore_Con_Event_Url_Complete Ecore_Con_Event_Url_Complete; | ||
340 | |||
341 | /** | ||
342 | * @typedef Ecore_Con_Event_Url_Progress | ||
343 | * Used as the @p data param for the corresponding event | ||
344 | * @ingroup Ecore_Con_Url_Group | ||
345 | */ | ||
346 | typedef struct _Ecore_Con_Event_Url_Progress Ecore_Con_Event_Url_Progress; | ||
347 | |||
348 | /** | ||
349 | * @struct _Ecore_Con_Event_Client_Add | ||
350 | * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ADD event | ||
351 | */ | ||
352 | struct _Ecore_Con_Event_Client_Add | ||
353 | { | ||
354 | Ecore_Con_Client *client; /** the client that connected */ | ||
355 | }; | ||
356 | |||
357 | /** | ||
358 | * @struct _Ecore_Con_Event_Client_Upgrade | ||
359 | * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_UPGRADE event | ||
360 | * @since 1.1 | ||
361 | */ | ||
362 | struct _Ecore_Con_Event_Client_Upgrade | ||
363 | { | ||
364 | Ecore_Con_Client *client; /** the client that completed handshake */ | ||
365 | }; | ||
366 | |||
367 | /** | ||
368 | * @struct _Ecore_Con_Event_Client_Del | ||
369 | * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DEL event | ||
370 | */ | ||
371 | struct _Ecore_Con_Event_Client_Del | ||
372 | { | ||
373 | Ecore_Con_Client *client; /** the client that was lost */ | ||
374 | }; | ||
375 | |||
376 | /** | ||
377 | * @struct _Ecore_Con_Event_Client_Error | ||
378 | * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ERROR event | ||
379 | */ | ||
380 | struct _Ecore_Con_Event_Client_Error | ||
381 | { | ||
382 | Ecore_Con_Client *client; /** the client for which an error occurred */ | ||
383 | char *error; /**< the error string describing what happened */ | ||
384 | }; | ||
385 | |||
386 | /** | ||
387 | * @struct _Ecore_Con_Event_Server_Add | ||
388 | * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ADD event | ||
389 | */ | ||
390 | struct _Ecore_Con_Event_Server_Add | ||
391 | { | ||
392 | Ecore_Con_Server *server; /** the server that was connected to */ | ||
393 | }; | ||
394 | |||
395 | /** | ||
396 | * @struct _Ecore_Con_Event_Server_Upgrade | ||
397 | * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_UPGRADE event | ||
398 | * @since 1.1 | ||
399 | */ | ||
400 | struct _Ecore_Con_Event_Server_Upgrade | ||
401 | { | ||
402 | Ecore_Con_Server *server; /** the server that was connected to */ | ||
403 | }; | ||
404 | |||
405 | /** | ||
406 | * @struct _Ecore_Con_Event_Server_Del | ||
407 | * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DEL event | ||
408 | */ | ||
409 | struct _Ecore_Con_Event_Server_Del | ||
410 | { | ||
411 | Ecore_Con_Server *server; /** the client that was lost */ | ||
412 | }; | ||
413 | |||
414 | /** | ||
415 | * @struct _Ecore_Con_Event_Server_Error | ||
416 | * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ERROR event | ||
417 | */ | ||
418 | struct _Ecore_Con_Event_Server_Error | ||
419 | { | ||
420 | Ecore_Con_Server *server; /** the server for which an error occurred */ | ||
421 | char *error; /**< the error string describing what happened */ | ||
422 | }; | ||
423 | |||
424 | /** | ||
425 | * @struct _Ecore_Con_Event_Client_Data | ||
426 | * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DATA event | ||
427 | */ | ||
428 | struct _Ecore_Con_Event_Client_Data | ||
429 | { | ||
430 | Ecore_Con_Client *client; /**< the client that connected */ | ||
431 | void *data; /**< the data that the client sent */ | ||
432 | int size; /**< the length of the data sent */ | ||
433 | }; | ||
434 | |||
435 | /** | ||
436 | * @struct _Ecore_Con_Event_Server_Data | ||
437 | * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DATA event | ||
438 | */ | ||
439 | struct _Ecore_Con_Event_Server_Data | ||
440 | { | ||
441 | Ecore_Con_Server *server; /**< the server that was connected to */ | ||
442 | void *data; /**< the data that the server sent */ | ||
443 | int size; /**< the length of the data sent */ | ||
444 | }; | ||
445 | |||
446 | /** | ||
447 | * @struct _Ecore_Con_Event_Client_Write | ||
448 | * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_WRITE event | ||
449 | */ | ||
450 | struct _Ecore_Con_Event_Client_Write | ||
451 | { | ||
452 | Ecore_Con_Client *client; /**< the client that connected */ | ||
453 | int size; /**< the length of the data sent */ | ||
454 | }; | ||
455 | |||
456 | /** | ||
457 | * @struct _Ecore_Con_Event_Server_Write | ||
458 | * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_WRITE event | ||
459 | */ | ||
460 | struct _Ecore_Con_Event_Server_Write | ||
461 | { | ||
462 | Ecore_Con_Server *server; /**< the server that was connected to */ | ||
463 | int size; /**< the length of the data sent */ | ||
464 | }; | ||
465 | |||
466 | /** | ||
467 | * @struct _Ecore_Con_Event_Url_Data | ||
468 | * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_DATA event | ||
469 | * @ingroup Ecore_Con_Url_Group | ||
470 | */ | ||
471 | struct _Ecore_Con_Event_Url_Data | ||
472 | { | ||
473 | Ecore_Con_Url *url_con; /**< a pointer to the connection object */ | ||
474 | int size; /**< the size of the current received data (in bytes) */ | ||
475 | unsigned char data[1]; /**< the data received on this event */ | ||
476 | }; | ||
477 | |||
478 | /** | ||
479 | * @struct _Ecore_Con_Event_Url_Complete | ||
480 | * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_COMPLETE event | ||
481 | * @ingroup Ecore_Con_Url_Group | ||
482 | */ | ||
483 | struct _Ecore_Con_Event_Url_Complete | ||
484 | { | ||
485 | Ecore_Con_Url *url_con; /**< a pointer to the connection object */ | ||
486 | int status; /**< HTTP status code of the operation (200, 404, 401, etc.) */ | ||
487 | }; | ||
488 | |||
489 | /** | ||
490 | * @struct _Ecore_Con_Event_Url_Progress | ||
491 | * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_PROGRESS event | ||
492 | * @ingroup Ecore_Con_Url_Group | ||
493 | */ | ||
494 | struct _Ecore_Con_Event_Url_Progress | ||
495 | { | ||
496 | Ecore_Con_Url *url_con; /**< a pointer to the connection object */ | ||
497 | struct | ||
498 | { | ||
499 | double total; /**< total size of the downloading data (in bytes) */ | ||
500 | double now; /**< current size of the downloading data (in bytes) */ | ||
501 | } down; /**< download info */ | ||
502 | struct | ||
503 | { | ||
504 | double total; /**< total size of the uploading data (in bytes) */ | ||
505 | double now; /**< current size of the uploading data (in bytes) */ | ||
506 | } up; /**< upload info */ | ||
507 | }; | ||
508 | |||
509 | /** A client has connected to the server */ | ||
510 | EAPI extern int ECORE_CON_EVENT_CLIENT_ADD; | ||
511 | /** A client has disconnected from the server */ | ||
512 | EAPI extern int ECORE_CON_EVENT_CLIENT_DEL; | ||
513 | /** A client experienced an error | ||
514 | * @since 1.1 | ||
515 | */ | ||
516 | EAPI extern int ECORE_CON_EVENT_CLIENT_ERROR; | ||
517 | /** A client connection has been upgraded to SSL | ||
518 | * @since 1.1 | ||
519 | */ | ||
520 | EAPI extern int ECORE_CON_EVENT_CLIENT_UPGRADE; | ||
521 | /** A server was created */ | ||
522 | EAPI extern int ECORE_CON_EVENT_SERVER_ADD; | ||
523 | /** A server connection was lost */ | ||
524 | EAPI extern int ECORE_CON_EVENT_SERVER_DEL; | ||
525 | /** A server experienced an error | ||
526 | * @since 1.1 | ||
527 | */ | ||
528 | EAPI extern int ECORE_CON_EVENT_SERVER_ERROR; | ||
529 | /** A server connection has been upgraded to SSL | ||
530 | * @since 1.1 | ||
531 | */ | ||
532 | EAPI extern int ECORE_CON_EVENT_SERVER_UPGRADE; | ||
533 | /** A server connection has sent data to its client | ||
534 | * @since 1.1 | ||
535 | */ | ||
536 | EAPI extern int ECORE_CON_EVENT_CLIENT_WRITE; | ||
537 | /** A server connection object has sent data | ||
538 | * @since 1.1 | ||
539 | */ | ||
540 | EAPI extern int ECORE_CON_EVENT_SERVER_WRITE; | ||
541 | /** A client connected to the server has sent data */ | ||
542 | EAPI extern int ECORE_CON_EVENT_CLIENT_DATA; | ||
543 | /** A server connection object has data */ | ||
544 | EAPI extern int ECORE_CON_EVENT_SERVER_DATA; | ||
545 | /** A URL object has data */ | ||
546 | EAPI extern int ECORE_CON_EVENT_URL_DATA; | ||
547 | /** A URL object has completed its transfer to and from the server and can be reused */ | ||
548 | EAPI extern int ECORE_CON_EVENT_URL_COMPLETE; | ||
549 | /** A URL object has made progress in its transfer */ | ||
550 | EAPI extern int ECORE_CON_EVENT_URL_PROGRESS; | ||
551 | |||
552 | /** | ||
553 | * @} | ||
554 | */ | ||
555 | |||
556 | /** | ||
557 | * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions | ||
558 | * | ||
559 | * Utility functions that set up and shut down the Ecore Connection | ||
560 | * library. | ||
561 | * | ||
562 | * There's also ecore_con_lookup() that can be used to make simple asynchronous | ||
563 | * DNS lookups. | ||
564 | * | ||
565 | * A simple example of how to use these functions: | ||
566 | * @li @ref ecore_con_lookup_example_c | ||
567 | * | ||
568 | * @{ | ||
569 | */ | ||
570 | |||
571 | /** | ||
572 | * @typedef Ecore_Con_Dns_Cb | ||
573 | * A callback type for use with @ref ecore_con_lookup. | ||
574 | */ | ||
575 | typedef void (*Ecore_Con_Dns_Cb)(const char *canonname, | ||
576 | const char *ip, | ||
577 | struct sockaddr *addr, | ||
578 | int addrlen, | ||
579 | void *data); | ||
580 | |||
581 | /** | ||
582 | * @typedef Ecore_Con_Type | ||
583 | * @enum _Ecore_Con_Type | ||
584 | * Types for an ecore_con client/server object. A correct way to set this type is | ||
585 | * with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if encryption is desired, | ||
586 | * and LOAD_CERT if the previously loaded certificate should be used. | ||
587 | * @code | ||
588 | * ECORE_CON_REMOTE_TCP | ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT | ||
589 | * @endcode | ||
590 | * @ingroup Ecore_Con_Server_Group | ||
591 | */ | ||
592 | typedef enum _Ecore_Con_Type | ||
593 | { | ||
594 | /** Socket in ~/.ecore */ | ||
595 | ECORE_CON_LOCAL_USER = 0, | ||
596 | /** Socket in /tmp */ | ||
597 | ECORE_CON_LOCAL_SYSTEM = 1, | ||
598 | /** Abstract socket */ | ||
599 | ECORE_CON_LOCAL_ABSTRACT = 2, | ||
600 | /** Remote server using TCP */ | ||
601 | ECORE_CON_REMOTE_TCP = 3, | ||
602 | /** Remote multicast server */ | ||
603 | ECORE_CON_REMOTE_MCAST = 4, | ||
604 | /** Remote server using UDP */ | ||
605 | ECORE_CON_REMOTE_UDP = 5, | ||
606 | /** Remote broadcast using UDP */ | ||
607 | ECORE_CON_REMOTE_BROADCAST = 6, | ||
608 | ECORE_CON_REMOTE_NODELAY = 7, | ||
609 | /** Use SSL2: UNSUPPORTED. **/ | ||
610 | ECORE_CON_USE_SSL2 = (1 << 4), | ||
611 | /** Use SSL3 */ | ||
612 | ECORE_CON_USE_SSL3 = (1 << 5), | ||
613 | /** Use TLS */ | ||
614 | ECORE_CON_USE_TLS = (1 << 6), | ||
615 | /** Use both TLS and SSL3 */ | ||
616 | ECORE_CON_USE_MIXED = ECORE_CON_USE_SSL3 | ECORE_CON_USE_TLS, | ||
617 | /** Attempt to use the loaded certificate */ | ||
618 | ECORE_CON_LOAD_CERT = (1 << 7) | ||
619 | } Ecore_Con_Type; | ||
620 | |||
621 | /** | ||
622 | * Initialises the Ecore_Con library. | ||
623 | * @return Number of times the library has been initialised without being | ||
624 | * shut down. | ||
625 | * | ||
626 | * @note This function already calls ecore_init() internally, so you don't need | ||
627 | * to call it explicitly. | ||
628 | */ | ||
629 | EAPI int ecore_con_init(void); | ||
630 | |||
631 | /** | ||
632 | * Shuts down the Ecore_Con library. | ||
633 | * @return Number of times the library has been initialised without being | ||
634 | * shut down. | ||
635 | * @note This function already calls ecore_shutdown() internally, so you don't | ||
636 | * need to call it explicitly unless you called ecore_init() explicitly too. | ||
637 | */ | ||
638 | EAPI int ecore_con_shutdown(void); | ||
639 | |||
640 | /** | ||
641 | * Do an asynchronous DNS lookup. | ||
642 | * | ||
643 | * @param name IP address or server name to translate. | ||
644 | * @param done_cb Callback to notify when done. | ||
645 | * @param data User data to be given to done_cb. | ||
646 | * @return EINA_TRUE if the request did not fail to be set up, EINA_FALSE if it | ||
647 | * failed. | ||
648 | * | ||
649 | * This function performs a DNS lookup on the hostname specified by @p name, | ||
650 | * then calls @p done_cb with the result and the @p data given as parameter. | ||
651 | * The result will be given to the @p done_cb as follows: | ||
652 | * @li @c canonname - the canonical name of the address | ||
653 | * @li @c ip - the resolved ip address | ||
654 | * @li @c addr - a pointer to the socket address | ||
655 | * @li @c addrlen - the length of the socket address, in bytes | ||
656 | * @li @c data - the data pointer given as parameter to ecore_con_lookup() | ||
657 | */ | ||
658 | EAPI Eina_Bool ecore_con_lookup(const char *name, | ||
659 | Ecore_Con_Dns_Cb done_cb, | ||
660 | const void *data); | ||
661 | |||
662 | /** | ||
663 | * @} | ||
664 | */ | ||
665 | |||
666 | /** | ||
667 | * @defgroup Ecore_Con_SSL_Group Ecore Connection SSL Functions | ||
668 | * | ||
669 | * @{ | ||
670 | */ | ||
671 | EAPI int ecore_con_ssl_available_get(void); | ||
672 | EAPI Eina_Bool ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr, const char *cert); | ||
673 | EAPI Eina_Bool ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr, const char *key_file); | ||
674 | EAPI Eina_Bool ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, const char *crl_file); | ||
675 | EAPI Eina_Bool ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, const char *ca_file); | ||
676 | EAPI void ecore_con_ssl_server_verify(Ecore_Con_Server *svr); | ||
677 | EAPI void ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr); | ||
678 | EAPI Eina_Bool ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type compl_type); | ||
679 | EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type compl_type); | ||
680 | |||
681 | /** | ||
682 | * @} | ||
683 | */ | ||
684 | |||
685 | /** | ||
686 | * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions | ||
687 | * | ||
688 | * This group of functions is applied to an @ref Ecore_Con_Server object. It | ||
689 | * doesn't mean that they should be used in the server application, but on the | ||
690 | * server object. In fact, most of them should be used in the client | ||
691 | * application, when retrieving information or sending data. | ||
692 | * | ||
693 | * Setting up a server is very simple: you just need to start it with | ||
694 | * ecore_con_server_add() and setup some callbacks to the events | ||
695 | * #ECORE_CON_EVENT_CLIENT_ADD, #ECORE_CON_EVENT_CLIENT_DEL and | ||
696 | * #ECORE_CON_EVENT_CLIENT_DATA, that will be called when a client is | ||
697 | * communicating with the server: | ||
698 | * | ||
699 | * @code | ||
700 | * if (!(svr = ecore_con_server_add(ECORE_CON_REMOTE_TCP, "127.0.0.1", 8080, NULL))) | ||
701 | * exit(1); | ||
702 | * | ||
703 | * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, _add_cb, NULL); | ||
704 | * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, _del_cb, NULL); | ||
705 | * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, _data_cb, NULL); | ||
706 | * | ||
707 | * ecore_main_loop_begin(); | ||
708 | * @endcode | ||
709 | * | ||
710 | * The function ecore_con_server_connect() can be used to write a client that | ||
711 | * connects to a server. The resulting code will be very similar to the server | ||
712 | * code: | ||
713 | * | ||
714 | * @code | ||
715 | * if (!(svr = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, "127.0.0.1", 8080, NULL))) | ||
716 | * exit(1); | ||
717 | * | ||
718 | * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _add_cb, NULL); | ||
719 | * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _del_cb, NULL); | ||
720 | * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _data_cb, NULL); | ||
721 | * | ||
722 | * ecore_main_loop_begin(); | ||
723 | * @endcode | ||
724 | * | ||
725 | * After these two pieces of code are executed, respectively, in the server and | ||
726 | * client code, the server will be up and running and the client will try to | ||
727 | * connect to it. The connection, with its subsequent messages being sent from | ||
728 | * server to client and client to server, can be represented in the following | ||
729 | * sequence diagram: | ||
730 | * | ||
731 | * @htmlonly | ||
732 | * <img src="ecore_con-client-server.png" style="max-width: 400px"/> | ||
733 | * <a href="ecore_con-client-server.png">Full size</a> | ||
734 | * @endhtmlonly | ||
735 | * | ||
736 | * @image rtf ecore_con-client-server.png | ||
737 | * @image latex ecore_con-client-server.eps width=\textwidth | ||
738 | * | ||
739 | * Please notice the important difference between these two codes: the first is | ||
740 | * used for writing a @b server, while the second should be used for writing a | ||
741 | * @b client. | ||
742 | * | ||
743 | * A reference for the @c client functions can be found at @ref | ||
744 | * Ecore_Con_Client_Group. | ||
745 | * | ||
746 | * Examples of usage for this API can be found here: | ||
747 | * @li @ref ecore_con_server_simple_example_c | ||
748 | * @li @ref ecore_con_client_simple_example_c | ||
749 | * | ||
750 | * @{ | ||
751 | */ | ||
752 | |||
753 | /** | ||
754 | * Creates a server to listen for connections. | ||
755 | * | ||
756 | * @param type The connection type. | ||
757 | * @param name Name to associate with the socket. It is used when | ||
758 | * generating the socket name of a Unix socket, or for | ||
759 | * determining what host to listen on for TCP sockets. | ||
760 | * @c NULL will not be accepted. | ||
761 | * @param port Number to identify socket. When a Unix socket is used, | ||
762 | * it becomes part of the socket name. When a TCP socket | ||
763 | * is used, it is used as the TCP port. | ||
764 | * @param data Data to associate with the created Ecore_Con_Server | ||
765 | * object. | ||
766 | * @return A new Ecore_Con_Server. | ||
767 | * | ||
768 | * The socket on which the server listens depends on the connection | ||
769 | * type: | ||
770 | * @li If @a type is @c ECORE_CON_LOCAL_USER, the server will listen on | ||
771 | * the Unix socket "~/.ecore/[name]/[port]". | ||
772 | * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen | ||
773 | * on Unix socket "/tmp/.ecore_service|[name]|[port]". | ||
774 | * @li If @a type is @c ECORE_CON_REMOTE_TCP, the server will listen | ||
775 | * on TCP port @c port. | ||
776 | * | ||
777 | * More information about the @p type can be found at @ref _Ecore_Con_Type. | ||
778 | * | ||
779 | * The @p data parameter can be fetched later using ecore_con_server_data_get() | ||
780 | * or changed with ecore_con_server_data_set(). | ||
781 | */ | ||
782 | EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type, | ||
783 | const char *name, int port, | ||
784 | const void *data); | ||
785 | |||
786 | /** | ||
787 | * Creates a connection to the specified server and returns an associated object. | ||
788 | * | ||
789 | * @param type The connection type. | ||
790 | * @param name Name used when determining what socket to connect to. | ||
791 | * It is used to generate the socket name when the socket | ||
792 | * is a Unix socket. It is used as the hostname when | ||
793 | * connecting with a TCP socket. | ||
794 | * @param port Number to identify the socket to connect to. Used when | ||
795 | * generating the socket name for a Unix socket, or as the | ||
796 | * TCP port when connecting to a TCP socket. | ||
797 | * @param data Data to associate with the created Ecore_Con_Server | ||
798 | * object. | ||
799 | * @return A new Ecore_Con_Server. | ||
800 | * | ||
801 | * The socket to which the connection is made depends on the connection type: | ||
802 | * @li If @a type is @c ECORE_CON_LOCAL_USER, the function will | ||
803 | * connect to the server at the Unix socket | ||
804 | * "~/.ecore/[name]/[port]". | ||
805 | * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the function will | ||
806 | * connect to the server at the Unix socket | ||
807 | * "/tmp/.ecore_service|[name]|[port]". | ||
808 | * @li If @a type is @c ECORE_CON_REMOTE_TCP, the function will | ||
809 | * connect to the server at the TCP port "[name]:[port]". | ||
810 | * | ||
811 | * More information about the @p type can be found at @ref _Ecore_Con_Type. | ||
812 | * | ||
813 | * This function won't block. It will either succeed, or fail due to invalid | ||
814 | * parameters, failed memory allocation, etc., returning @c NULL on that case. | ||
815 | * | ||
816 | * However, even if this call returns a valid @ref Ecore_Con_Server, the | ||
817 | * connection will only be successfully completed if an event of type | ||
818 | * #ECORE_CON_EVENT_SERVER_ADD is received. If it fails to complete, an | ||
819 | * #ECORE_CON_EVENT_SERVER_DEL will be received. | ||
820 | * | ||
821 | * The @p data parameter can be fetched later using ecore_con_server_data_get() | ||
822 | * or changed with ecore_con_server_data_set(). | ||
823 | */ | ||
824 | EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, | ||
825 | const char *name, int port, | ||
826 | const void *data); | ||
827 | /** | ||
828 | * Closes the connection and frees the given server. | ||
829 | * | ||
830 | * @param svr The given server. | ||
831 | * @return Data associated with the server when it was created. | ||
832 | * | ||
833 | * All the clients connected to this server will be disconnected. | ||
834 | * | ||
835 | * @see ecore_con_server_add, ecore_con_server_connect | ||
836 | */ | ||
837 | EAPI void * ecore_con_server_del(Ecore_Con_Server *svr); | ||
838 | |||
839 | /** | ||
840 | * Retrieves the data associated with the given server. | ||
841 | * | ||
842 | * @param svr The given server. | ||
843 | * @return The associated data. | ||
844 | * | ||
845 | * @see ecore_con_server_data_set() | ||
846 | */ | ||
847 | EAPI void * ecore_con_server_data_get(Ecore_Con_Server *svr); | ||
848 | /** | ||
849 | * Sets the data associated with the given server. | ||
850 | * | ||
851 | * @param svr The given server. | ||
852 | * @param data The data to associate with @p svr | ||
853 | * @return The previously associated data, if any. | ||
854 | * | ||
855 | * @see ecore_con_server_data_get() | ||
856 | */ | ||
857 | EAPI void * ecore_con_server_data_set(Ecore_Con_Server *svr, | ||
858 | void *data); | ||
859 | /** | ||
860 | * Retrieves whether the given server is currently connected. | ||
861 | * | ||
862 | * @param svr The given server. | ||
863 | * @return #EINA_TRUE if the server is connected. #EINA_FALSE otherwise. | ||
864 | */ | ||
865 | EAPI Eina_Bool ecore_con_server_connected_get(Ecore_Con_Server *svr); | ||
866 | /** | ||
867 | * Retrieves the current list of clients. | ||
868 | * | ||
869 | * @param svr The given server. | ||
870 | * @return The list of clients on this server. | ||
871 | * | ||
872 | * Each node in the returned list points to an @ref Ecore_Con_Client. This list | ||
873 | * cannot be modified or freed. It can also change if new clients are connected | ||
874 | * or disconnected, and will become invalid when the server is deleted/freed. | ||
875 | */ | ||
876 | EAPI const Eina_List * ecore_con_server_clients_get(Ecore_Con_Server *svr); | ||
877 | |||
878 | /** | ||
879 | * Retrieves the name of server. | ||
880 | * | ||
881 | * @param svr The given server. | ||
882 | * @return The name of the server. | ||
883 | * | ||
884 | * The name returned is the name used to connect on this server. | ||
885 | */ | ||
886 | EAPI const char * ecore_con_server_name_get(Ecore_Con_Server *svr); | ||
887 | |||
888 | /** | ||
889 | * Retrieves the server port in use. | ||
890 | * | ||
891 | * @param svr The given server. | ||
892 | * @return The server port in use. | ||
893 | * | ||
894 | * The port where the server is listening for connections. | ||
895 | */ | ||
896 | EAPI int ecore_con_server_port_get(Ecore_Con_Server *svr); | ||
897 | /** | ||
898 | * @brief Check how long a server has been connected | ||
899 | * | ||
900 | * @param svr The server to check | ||
901 | * @return The total time, in seconds, that the server has been | ||
902 | * connected/running | ||
903 | * | ||
904 | * This function is used to find out the time that has been elapsed since | ||
905 | * ecore_con_server_add() succeeded. | ||
906 | */ | ||
907 | EAPI double ecore_con_server_uptime_get(Ecore_Con_Server *svr); | ||
908 | /** | ||
909 | * Sends the given data to the given server. | ||
910 | * | ||
911 | * @param svr The given server. | ||
912 | * @param data The given data. | ||
913 | * @param size Length of the data, in bytes, to send. | ||
914 | * @return The number of bytes sent. @c 0 will be returned if there is an | ||
915 | * error. | ||
916 | * | ||
917 | * This function will send the given data to the server as soon as the program | ||
918 | * is back to the main loop. Thus, this function returns immediately | ||
919 | * (non-blocking). If the data needs to be sent @b now, call | ||
920 | * ecore_con_server_flush() after this one. | ||
921 | * | ||
922 | * @see ecore_con_client_send() | ||
923 | * @see ecore_con_server_flush() | ||
924 | */ | ||
925 | EAPI int ecore_con_server_send(Ecore_Con_Server *svr, | ||
926 | const void *data, | ||
927 | int size); | ||
928 | /** | ||
929 | * Sets a limit on the number of clients that can be handled concurrently | ||
930 | * by the given server, and a policy on what to do if excess clients try to | ||
931 | * connect. | ||
932 | * | ||
933 | * @param svr The given server. | ||
934 | * @param client_limit The maximum number of clients to handle | ||
935 | * concurrently. -1 means unlimited (default). 0 | ||
936 | * effectively disables the server. | ||
937 | * @param reject_excess_clients Set to 1 to automatically disconnect | ||
938 | * excess clients as soon as they connect if you are | ||
939 | * already handling client_limit clients. Set to 0 | ||
940 | * (default) to just hold off on the "accept()" | ||
941 | * system call until the number of active clients | ||
942 | * drops. This causes the kernel to queue up to 4096 | ||
943 | * connections (or your kernel's limit, whichever is | ||
944 | * lower). | ||
945 | * | ||
946 | * Beware that if you set this once ecore is already running, you may | ||
947 | * already have pending CLIENT_ADD events in your event queue. Those | ||
948 | * clients have already connected and will not be affected by this call. | ||
949 | * Only clients subsequently trying to connect will be affected. | ||
950 | */ | ||
951 | EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr, | ||
952 | int client_limit, | ||
953 | char reject_excess_clients); | ||
954 | /** | ||
955 | * Gets the IP address of a server that has been connected to. | ||
956 | * | ||
957 | * @param svr The given server. | ||
958 | * @return A pointer to an internal string that contains the IP address of | ||
959 | * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation. | ||
960 | * This string should not be modified or trusted to stay valid after | ||
961 | * deletion for the @p svr object. If no IP is known NULL is returned. | ||
962 | */ | ||
963 | EAPI const char * ecore_con_server_ip_get(Ecore_Con_Server *svr); | ||
964 | /** | ||
965 | * Flushes all pending data to the given server. | ||
966 | * | ||
967 | * @param svr The given server. | ||
968 | * | ||
969 | * This function will block until all data is sent to the server. | ||
970 | * | ||
971 | * @see ecore_con_server_send() | ||
972 | * @see ecore_con_client_flush() | ||
973 | */ | ||
974 | EAPI void ecore_con_server_flush(Ecore_Con_Server *svr); | ||
975 | /** | ||
976 | * Set the default time after which an inactive client will be disconnected | ||
977 | * | ||
978 | * @param svr The server object | ||
979 | * @param timeout The timeout, in seconds, to disconnect after | ||
980 | * | ||
981 | * This function is used by the server to set the default idle timeout on | ||
982 | * clients. If the any of the clients becomes idle for a time higher than this | ||
983 | * value, it will be disconnected. A value of < 1 disables the idle timeout. | ||
984 | * | ||
985 | * This timeout is not affected by the one set by | ||
986 | * ecore_con_client_timeout_set(). A client will be disconnected whenever the | ||
987 | * client or the server timeout is reached. That means, the lower timeout value | ||
988 | * will be used for that client if ecore_con_client_timeout_set() is used on it. | ||
989 | * | ||
990 | * @see ecore_con_server_timeout_get() | ||
991 | * @see ecore_con_client_timeout_set() | ||
992 | */ | ||
993 | EAPI void ecore_con_server_timeout_set(Ecore_Con_Server *svr, double timeout); | ||
994 | /** | ||
995 | * Get the default time after which an inactive client will be disconnected | ||
996 | * | ||
997 | * @param svr The server object | ||
998 | * @return The timeout, in seconds, to disconnect after | ||
999 | * | ||
1000 | * This function is used to get the idle timeout for clients. A value of < 1 | ||
1001 | * means the idle timeout is disabled. | ||
1002 | * | ||
1003 | * @see ecore_con_server_timeout_set() | ||
1004 | * @see ecore_con_client_timeout_get() | ||
1005 | */ | ||
1006 | EAPI double ecore_con_server_timeout_get(Ecore_Con_Server *svr); | ||
1007 | |||
1008 | /** | ||
1009 | * Get the fd that the server is connected to | ||
1010 | * | ||
1011 | * @param svr The server object | ||
1012 | * @return The fd, or -1 on failure | ||
1013 | * | ||
1014 | * This function returns the fd which is used by the underlying server connection. | ||
1015 | * It should not be tampered with unless you REALLY know what you are doing. | ||
1016 | * @note This function is only valid for servers created with ecore_con_server_connect() | ||
1017 | * @warning Seriously. Don't use this unless you know what you are doing. | ||
1018 | * @since 1.1 | ||
1019 | */ | ||
1020 | EAPI int ecore_con_server_fd_get(Ecore_Con_Server *svr); | ||
1021 | |||
1022 | /** | ||
1023 | * Get the fd that the client is connected to | ||
1024 | * | ||
1025 | * @param cl The client object | ||
1026 | * @return The fd, or -1 on failure | ||
1027 | * | ||
1028 | * This function returns the fd which is used by the underlying client connection. | ||
1029 | * It should not be tampered with unless you REALLY know what you are doing. | ||
1030 | * @since 1.1 | ||
1031 | */ | ||
1032 | EAPI int ecore_con_client_fd_get(Ecore_Con_Client *cl); | ||
1033 | /** | ||
1034 | * @} | ||
1035 | */ | ||
1036 | |||
1037 | /** | ||
1038 | * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions | ||
1039 | * | ||
1040 | * Functions to communicate with and/or set options on a client. | ||
1041 | * | ||
1042 | * This set of functions, as explained in @ref Ecore_Con_Server_Group, is used | ||
1043 | * to send data to a client, or to set options and get information about this | ||
1044 | * client. Most of them should be used on the server, applied on the client | ||
1045 | * object. | ||
1046 | * | ||
1047 | * If you need to implement a client, the way to connect to a server is | ||
1048 | * described in @ref Ecore_Con_Server_Group. | ||
1049 | * | ||
1050 | * An example of usage of these functions can be found at: | ||
1051 | * @li @ref ecore_con_client_simple_example_c | ||
1052 | * | ||
1053 | * @{ | ||
1054 | */ | ||
1055 | |||
1056 | /** | ||
1057 | * Sends the given data to the given client. | ||
1058 | * | ||
1059 | * @param cl The given client. | ||
1060 | * @param data The given data. | ||
1061 | * @param size Length of the data, in bytes, to send. | ||
1062 | * @return The number of bytes sent. @c 0 will be returned if there is an | ||
1063 | * error. | ||
1064 | * | ||
1065 | * This function will send the given data to the client as soon as the program | ||
1066 | * is back to the main loop. Thus, this function returns immediately | ||
1067 | * (non-blocking). If the data needs to be sent @b now, call | ||
1068 | * ecore_con_client_flush() after this one. | ||
1069 | * | ||
1070 | * @see ecore_con_server_send() | ||
1071 | * @see ecore_con_client_flush() | ||
1072 | */ | ||
1073 | EAPI int ecore_con_client_send(Ecore_Con_Client *cl, | ||
1074 | const void *data, | ||
1075 | int size); | ||
1076 | /** | ||
1077 | * Retrieves the server representing the socket the client has | ||
1078 | * connected to. | ||
1079 | * | ||
1080 | * @param cl The given client. | ||
1081 | * @return The server that the client connected to. | ||
1082 | */ | ||
1083 | EAPI Ecore_Con_Server *ecore_con_client_server_get(Ecore_Con_Client *cl); | ||
1084 | /** | ||
1085 | * Closes the connection and frees memory allocated to the given client. | ||
1086 | * | ||
1087 | * @param cl The given client. | ||
1088 | * @return Data associated with the client. | ||
1089 | */ | ||
1090 | EAPI void * ecore_con_client_del(Ecore_Con_Client *cl); | ||
1091 | /** | ||
1092 | * Sets the data associated with the given client to @p data. | ||
1093 | * | ||
1094 | * @param cl The given client. | ||
1095 | * @param data What to set the data to. | ||
1096 | */ | ||
1097 | EAPI void ecore_con_client_data_set(Ecore_Con_Client *cl, | ||
1098 | const void *data); | ||
1099 | /** | ||
1100 | * Retrieves the data associated with the given client. | ||
1101 | * | ||
1102 | * @param cl The given client. | ||
1103 | * @return The data associated with @p cl. | ||
1104 | */ | ||
1105 | EAPI void * ecore_con_client_data_get(Ecore_Con_Client *cl); | ||
1106 | |||
1107 | /** | ||
1108 | * Gets the IP address of a client that has connected. | ||
1109 | * | ||
1110 | * @param cl The given client. | ||
1111 | * @return A pointer to an internal string that contains the IP address of | ||
1112 | * the connected client in the form "XXX.YYY.ZZZ.AAA" IP notation. | ||
1113 | * | ||
1114 | * The returned string should not be modified, freed or trusted to stay valid | ||
1115 | * after deletion for the @p cl object. If no IP is known NULL is returned. | ||
1116 | */ | ||
1117 | EAPI const char * ecore_con_client_ip_get(Ecore_Con_Client *cl); | ||
1118 | /** | ||
1119 | * Flushes all pending data to the given client. | ||
1120 | * | ||
1121 | * @param cl The given client. | ||
1122 | * | ||
1123 | * This function will block until all data is sent to the server. | ||
1124 | * | ||
1125 | * @see ecore_con_client_send() | ||
1126 | * @see ecore_con_server_flush() | ||
1127 | */ | ||
1128 | EAPI void ecore_con_client_flush(Ecore_Con_Client *cl); | ||
1129 | /** | ||
1130 | * @brief Check how long a client has been connected | ||
1131 | * | ||
1132 | * @param cl The client to check | ||
1133 | * @return The total time, in seconds, that the client has been connected to | ||
1134 | * the server | ||
1135 | * | ||
1136 | * This function is used to find out how long a client has been connected for. | ||
1137 | */ | ||
1138 | EAPI double ecore_con_client_uptime_get(Ecore_Con_Client *cl); | ||
1139 | /** | ||
1140 | * Get the default time after which the client will be disconnected when | ||
1141 | * inactive | ||
1142 | * | ||
1143 | * @param cl The client object | ||
1144 | * @return The timeout, in seconds, to disconnect after | ||
1145 | * | ||
1146 | * This function is used to get the idle timeout for a client. A value of < 1 | ||
1147 | * means the idle timeout is disabled. | ||
1148 | * | ||
1149 | * @see ecore_con_client_timeout_set() | ||
1150 | */ | ||
1151 | EAPI double ecore_con_client_timeout_get(Ecore_Con_Client *cl); | ||
1152 | /** | ||
1153 | * Set the time after which the client will be disconnected when inactive | ||
1154 | * | ||
1155 | * @param cl The client object | ||
1156 | * @param timeout The timeout, in seconds, to disconnect after | ||
1157 | * | ||
1158 | * This function is used by the server to set the idle timeout on a specific | ||
1159 | * client. If the client becomes idle for a time higher than this value, it will | ||
1160 | * be disconnected. A value of < 1 disables the idle timeout. | ||
1161 | * | ||
1162 | * This timeout is not affected by the one set by | ||
1163 | * ecore_con_server_timeout_set(). A client will be disconnected whenever the | ||
1164 | * client or the server timeout is reached. That means, the lower timeout value | ||
1165 | * will be used for that client if ecore_con_server_timeout_set() is used on the | ||
1166 | * server. | ||
1167 | * | ||
1168 | * @see ecore_con_client_timeout_get() | ||
1169 | * @see ecore_con_server_timeout_set() | ||
1170 | */ | ||
1171 | EAPI void ecore_con_client_timeout_set(Ecore_Con_Client *cl, double timeout); | ||
1172 | /** | ||
1173 | * Returns whether the client is still connected | ||
1174 | * | ||
1175 | * @param cl The given client. | ||
1176 | * @return #EINA_TRUE if connected, else EINA_FALSE | ||
1177 | */ | ||
1178 | EAPI Eina_Bool ecore_con_client_connected_get(Ecore_Con_Client *cl); | ||
1179 | /** | ||
1180 | * @brief Return the port that the client has connected to | ||
1181 | * | ||
1182 | * @param cl The client | ||
1183 | * @return The port that @p cl has connected to, or -1 on error | ||
1184 | * Use this function to return the port on which a given client has connected. | ||
1185 | */ | ||
1186 | EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl); | ||
1187 | |||
1188 | /** | ||
1189 | * @} | ||
1190 | */ | ||
1191 | |||
1192 | /** | ||
1193 | * @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions | ||
1194 | * | ||
1195 | * Utility functions that set up, use and shut down the Ecore URL | ||
1196 | * Connection library. | ||
1197 | * | ||
1198 | * These functions are a shortcut to make it easy to perform http requests | ||
1199 | * (POST, GET, etc). | ||
1200 | * | ||
1201 | * Brief usage: | ||
1202 | * 1. Create an Ecore_Con_Url object with ecore_con_url_new(url); | ||
1203 | * 2. Register to receive the #ECORE_CON_EVENT_URL_COMPLETE event | ||
1204 | * (and optionally the #ECORE_CON_EVENT_URL_DATA and | ||
1205 | * #ECORE_CON_EVENT_URL_PROGRESS event to receive | ||
1206 | * the response, e.g. for HTTP/FTP downloads) | ||
1207 | * 3. Perform the operation with ecore_con_url_get(...); | ||
1208 | * | ||
1209 | * Note that it is good to reuse @ref Ecore_Con_Url objects wherever possible, | ||
1210 | * but bear in mind that each one can only perform one operation at a time. You | ||
1211 | * need to wait for the #ECORE_CON_EVENT_URL_COMPLETE event before re-using or | ||
1212 | * destroying the object. | ||
1213 | * | ||
1214 | * If it's necessary to change the @ref Ecore_Con_Url object url, use | ||
1215 | * ecore_con_url_url_set(). | ||
1216 | * | ||
1217 | * Simple Usage 1 (HTTP GET): | ||
1218 | * @code | ||
1219 | * ecore_con_url_url_set(url_con, "http://www.google.com"); | ||
1220 | * ecore_con_url_get(url_con); | ||
1221 | * @endcode | ||
1222 | * | ||
1223 | * Simple usage 2 (HTTP POST): | ||
1224 | * @code | ||
1225 | * ecore_con_url_url_set(url_con, "http://www.example.com/post_handler.cgi"); | ||
1226 | * ecore_con_url_post(url_con, data, data_length, "multipart/form-data"); | ||
1227 | * @endcode | ||
1228 | * | ||
1229 | * Simple Usage 3 (FTP download): | ||
1230 | * @code | ||
1231 | * fd = creat(filename, 0644) | ||
1232 | * ecore_con_url_url_set(url_con, "ftp://ftp.example.com/pub/myfile"); | ||
1233 | * ecore_con_url_fd_set(url_con, fd); | ||
1234 | * ecore_con_url_get(url_con); | ||
1235 | * @endcode | ||
1236 | * | ||
1237 | * Simple Usage 4 (FTP upload as ftp://ftp.example.com/file): | ||
1238 | * @code | ||
1239 | * ecore_con_url_url_set(url_con, "ftp://ftp.example.com"); | ||
1240 | * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass", NULL); | ||
1241 | * @endcode | ||
1242 | * | ||
1243 | * Simple Usage 5 (FTP upload as ftp://ftp.example.com/dir/file): | ||
1244 | * @code | ||
1245 | * ecore_con_url_url_set(url_con, "ftp://ftp.example.com"); | ||
1246 | * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass","dir"); | ||
1247 | * @endcode | ||
1248 | * | ||
1249 | * These are complete examples for the API: | ||
1250 | * @li @ref ecore_con_url_download_example.c "Downloading a file" | ||
1251 | * @li @ref ecore_con_url_headers_example.c "Setting many options for the | ||
1252 | * connection" | ||
1253 | * | ||
1254 | * @{ | ||
1255 | */ | ||
1256 | |||
1257 | /** | ||
1258 | * @typedef Ecore_Con_Url_Time | ||
1259 | * @enum _Ecore_Con_Url_Time | ||
1260 | * The type of condition to use when making an HTTP request dependent on time, | ||
1261 | * so that headers such as "If-Modified-Since" are used. | ||
1262 | */ | ||
1263 | typedef enum _Ecore_Con_Url_Time | ||
1264 | { | ||
1265 | /** | ||
1266 | * Do not place time restrictions on the HTTP requests. | ||
1267 | */ | ||
1268 | ECORE_CON_URL_TIME_NONE = 0, | ||
1269 | /** | ||
1270 | * Add the "If-Modified-Since" HTTP header, so that the request is performed | ||
1271 | * by the server only if the target has been modified since the time value | ||
1272 | * passed to it in the request. | ||
1273 | */ | ||
1274 | ECORE_CON_URL_TIME_IFMODSINCE, | ||
1275 | /** | ||
1276 | * Add the "If-Unmodified-Since" HTTP header, so that the request is | ||
1277 | * performed by the server only if the target has NOT been modified since | ||
1278 | * the time value passed to it in the request. | ||
1279 | */ | ||
1280 | ECORE_CON_URL_TIME_IFUNMODSINCE | ||
1281 | } Ecore_Con_Url_Time; | ||
1282 | |||
1283 | /** | ||
1284 | * Initialises the Ecore_Con_Url library. | ||
1285 | * @return Number of times the library has been initialised without being | ||
1286 | * shut down. | ||
1287 | * | ||
1288 | * @note This function doesn't call ecore_con_init(). You still need to call it | ||
1289 | * explicitly before calling this one. | ||
1290 | */ | ||
1291 | EAPI int ecore_con_url_init(void); | ||
1292 | |||
1293 | /** | ||
1294 | * Shuts down the Ecore_Con_Url library. | ||
1295 | * @return Number of calls that still uses Ecore_Con_Url | ||
1296 | * | ||
1297 | * @note This function doesn't call ecore_con_shutdown(). You still need to call | ||
1298 | * it explicitly after calling this one. | ||
1299 | */ | ||
1300 | EAPI int ecore_con_url_shutdown(void); | ||
1301 | |||
1302 | /** | ||
1303 | * Enable or disable HTTP 1.1 pipelining. | ||
1304 | * @param enable EINA_TRUE will turn it on, EINA_FALSE will disable it. | ||
1305 | * | ||
1306 | * Pipelining allows to send one request after another one, without having to | ||
1307 | * wait for the reply of the first request. The respective replies are received | ||
1308 | * in the order that the requests were sent. | ||
1309 | * | ||
1310 | * Enabling this feature will be valid for all requests done using @c | ||
1311 | * ecore_con_url. | ||
1312 | * | ||
1313 | * See http://en.wikipedia.org/wiki/HTTP_pipelining for more info. | ||
1314 | * | ||
1315 | * @see ecore_con_url_pipeline_get() | ||
1316 | */ | ||
1317 | EAPI void ecore_con_url_pipeline_set(Eina_Bool enable); | ||
1318 | /** | ||
1319 | * Is HTTP 1.1 pipelining enable ? | ||
1320 | * @return EINA_TRUE if it is enable. | ||
1321 | * | ||
1322 | * @see ecore_con_url_pipeline_set() | ||
1323 | */ | ||
1324 | EAPI Eina_Bool ecore_con_url_pipeline_get(void); | ||
1325 | |||
1326 | /** | ||
1327 | * Creates and initializes a new Ecore_Con_Url connection object. | ||
1328 | * | ||
1329 | * @param url URL that will receive requests. Can be changed using | ||
1330 | * ecore_con_url_url_set. | ||
1331 | * | ||
1332 | * @return NULL on error, a new Ecore_Con_Url on success. | ||
1333 | * | ||
1334 | * Creates and initializes a new Ecore_Con_Url connection object that can be | ||
1335 | * used for sending requests. | ||
1336 | * | ||
1337 | * @see ecore_con_url_custom_new() | ||
1338 | * @see ecore_con_url_url_set() | ||
1339 | */ | ||
1340 | EAPI Ecore_Con_Url * ecore_con_url_new(const char *url); | ||
1341 | /** | ||
1342 | * Creates a custom connection object. | ||
1343 | * | ||
1344 | * @param url URL that will receive requests | ||
1345 | * @param custom_request Custom request (e.g. GET, POST, HEAD, PUT, etc) | ||
1346 | * | ||
1347 | * @return NULL on error, a new Ecore_Con_Url on success. | ||
1348 | * | ||
1349 | * Creates and initializes a new Ecore_Con_Url for a custom request (e.g. HEAD, | ||
1350 | * SUBSCRIBE and other obscure HTTP requests). This object should be used like | ||
1351 | * one created with ecore_con_url_new(). | ||
1352 | * | ||
1353 | * @see ecore_con_url_new() | ||
1354 | * @see ecore_con_url_url_set() | ||
1355 | */ | ||
1356 | EAPI Ecore_Con_Url * ecore_con_url_custom_new(const char *url, | ||
1357 | const char *custom_request); | ||
1358 | /** | ||
1359 | * Destroys a Ecore_Con_Url connection object. | ||
1360 | * | ||
1361 | * @param url_con Connection object to free. | ||
1362 | * | ||
1363 | * @see ecore_con_url_new() | ||
1364 | */ | ||
1365 | EAPI void ecore_con_url_free(Ecore_Con_Url *url_con); | ||
1366 | /** | ||
1367 | * Sets the URL to send the request to. | ||
1368 | * | ||
1369 | * @param url_con Connection object through which the request will be sent. | ||
1370 | * @param url URL that will receive the request | ||
1371 | * | ||
1372 | * @return EINA_TRUE on success, EINA_FALSE on error. | ||
1373 | * | ||
1374 | */ | ||
1375 | EAPI Eina_Bool ecore_con_url_url_set(Ecore_Con_Url *url_con, | ||
1376 | const char *url); | ||
1377 | /** | ||
1378 | * Gets the URL to send the request to. | ||
1379 | * | ||
1380 | * @param url_con Connection object through which the request will be sent. | ||
1381 | * @return URL that will receive the request, NULL on failure. URL is stringshared. | ||
1382 | * @since 1.1 | ||
1383 | */ | ||
1384 | EAPI const char *ecore_con_url_url_get(Ecore_Con_Url *url_con); | ||
1385 | /** | ||
1386 | * Associates data with a connection object. | ||
1387 | * | ||
1388 | * @param url_con Connection object to associate data. | ||
1389 | * @param data Data to be set. | ||
1390 | * | ||
1391 | * Associates data with a connection object, which can be retrieved later with | ||
1392 | * ecore_con_url_data_get()). | ||
1393 | * | ||
1394 | * @see ecore_con_url_data_get() | ||
1395 | */ | ||
1396 | EAPI void ecore_con_url_data_set(Ecore_Con_Url *url_con, | ||
1397 | void *data); | ||
1398 | /** | ||
1399 | * Retrieves data associated with a Ecore_Con_Url connection object. | ||
1400 | * | ||
1401 | * @param url_con Connection object to retrieve data from. | ||
1402 | * | ||
1403 | * @return Data associated with the given object. | ||
1404 | * | ||
1405 | * Retrieves data associated with a Ecore_Con_Url connection object (previously | ||
1406 | * set with ecore_con_url_data_set()). | ||
1407 | * | ||
1408 | * @see ecore_con_url_data_set() | ||
1409 | */ | ||
1410 | EAPI void * ecore_con_url_data_get(Ecore_Con_Url *url_con); | ||
1411 | /** | ||
1412 | * Adds an additional header to the request connection object. | ||
1413 | * | ||
1414 | * @param url_con Connection object | ||
1415 | * @param key Header key | ||
1416 | * @param value Header value | ||
1417 | * | ||
1418 | * Adds an additional header (User-Agent, Content-Type, etc.) to the request | ||
1419 | * connection object. This addition will be valid for only one | ||
1420 | * ecore_con_url_get() or ecore_con_url_post() call. | ||
1421 | * | ||
1422 | * Some functions like ecore_con_url_time() also add headers to the request. | ||
1423 | * | ||
1424 | * @see ecore_con_url_get() | ||
1425 | * @see ecore_con_url_post() | ||
1426 | * @see ecore_con_url_additional_headers_clear() | ||
1427 | */ | ||
1428 | EAPI void ecore_con_url_additional_header_add(Ecore_Con_Url *url_con, | ||
1429 | const char *key, | ||
1430 | const char *value); | ||
1431 | /** | ||
1432 | * Cleans additional headers. | ||
1433 | * | ||
1434 | * @param url_con Connection object to clean additional headers. | ||
1435 | * | ||
1436 | * Cleans additional headers associated with a connection object (previously | ||
1437 | * added with ecore_con_url_additional_header_add()). | ||
1438 | * | ||
1439 | * @see ecore_con_url_additional_header_add() | ||
1440 | * @see ecore_con_url_get() | ||
1441 | * @see ecore_con_url_post() | ||
1442 | */ | ||
1443 | EAPI void ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con); | ||
1444 | /** | ||
1445 | * Retrieves headers from last request sent. | ||
1446 | * | ||
1447 | * @param url_con Connection object to retrieve response headers from. | ||
1448 | * | ||
1449 | * Retrieves a list containing the response headers. This function should be | ||
1450 | * used after an ECORE_CON_EVENT_URL_COMPLETE event (headers should normally be | ||
1451 | * ready at that time). | ||
1452 | * | ||
1453 | * @return List of response headers. This list must not be modified by the user. | ||
1454 | */ | ||
1455 | EAPI const Eina_List * ecore_con_url_response_headers_get(Ecore_Con_Url *url_con); | ||
1456 | /** | ||
1457 | * Setup a file for receiving response data. | ||
1458 | * | ||
1459 | * @param url_con Connection object to set file | ||
1460 | * @param fd File descriptor associated with the file. A negative value will | ||
1461 | * unset any previously set fd. | ||
1462 | * | ||
1463 | * Sets up a file to have response data written into. Note that | ||
1464 | * ECORE_CON_EVENT_URL_DATA events will not be emitted if a file has been set to | ||
1465 | * receive the response data. | ||
1466 | * | ||
1467 | * This call can be used to easily setup a file where the downloaded data will | ||
1468 | * be saved. | ||
1469 | */ | ||
1470 | EAPI void ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd); | ||
1471 | /** | ||
1472 | * Retrieves the number of bytes received. | ||
1473 | * | ||
1474 | * Retrieves the number of bytes received on the last request of the given | ||
1475 | * connection object. | ||
1476 | * | ||
1477 | * @param url_con Connection object which the request was sent on. | ||
1478 | * | ||
1479 | * @return Number of bytes received on request. | ||
1480 | * | ||
1481 | * @see ecore_con_url_get() | ||
1482 | * @see ecore_con_url_post() | ||
1483 | */ | ||
1484 | EAPI int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con); | ||
1485 | /** | ||
1486 | * Sets url_con to use http auth, with given username and password, "safely" or not. | ||
1487 | * | ||
1488 | * @param url_con Connection object to perform a request on, previously created | ||
1489 | * with ecore_con_url_new() or ecore_con_url_custom_new(). | ||
1490 | * @param username Username to use in authentication | ||
1491 | * @param password Password to use in authentication | ||
1492 | * @param safe Whether to use "safer" methods (eg, NOT http basic auth) | ||
1493 | * | ||
1494 | * @return #EINA_TRUE on success, #EINA_FALSE on error. | ||
1495 | * | ||
1496 | * ATTENTION: requires libcurl >= 7.19.1 to work, otherwise will always return 0. | ||
1497 | */ | ||
1498 | EAPI Eina_Bool ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, | ||
1499 | const char *username, | ||
1500 | const char *password, | ||
1501 | Eina_Bool safe); | ||
1502 | /** | ||
1503 | * Sends a request. | ||
1504 | * | ||
1505 | * @param url_con Connection object to perform a request on, previously created | ||
1506 | * with ecore_con_url_new() or ecore_con_url_custom_new(). | ||
1507 | * @param data Payload (data sent on the request) | ||
1508 | * @param length Payload length. If @c -1, rely on automatic length | ||
1509 | * calculation via @c strlen() on @p data. | ||
1510 | * @param content_type Content type of the payload (e.g. text/xml) | ||
1511 | * | ||
1512 | * @return #EINA_TRUE on success, #EINA_FALSE on error. | ||
1513 | * | ||
1514 | * @see ecore_con_url_custom_new() | ||
1515 | * @see ecore_con_url_additional_headers_clear() | ||
1516 | * @see ecore_con_url_additional_header_add() | ||
1517 | * @see ecore_con_url_data_set() | ||
1518 | * @see ecore_con_url_data_get() | ||
1519 | * @see ecore_con_url_response_headers_get() | ||
1520 | * @see ecore_con_url_time() | ||
1521 | * @see ecore_con_url_get() | ||
1522 | * @see ecore_con_url_post() | ||
1523 | * | ||
1524 | * @deprecated Use ecore_con_url_post() instead of this. | ||
1525 | */ | ||
1526 | EINA_DEPRECATED EAPI Eina_Bool ecore_con_url_send(Ecore_Con_Url *url_con, | ||
1527 | const void *data, long length, | ||
1528 | const char *content_type); | ||
1529 | /** | ||
1530 | * Sends a get request. | ||
1531 | * | ||
1532 | * @param url_con Connection object to perform a request on, previously created | ||
1533 | * | ||
1534 | * @return #EINA_TRUE on success, #EINA_FALSE on error. | ||
1535 | * | ||
1536 | * The request is performed immediately, but you need to setup event handlers | ||
1537 | * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or | ||
1538 | * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. | ||
1539 | * | ||
1540 | * @see ecore_con_url_custom_new() | ||
1541 | * @see ecore_con_url_additional_headers_clear() | ||
1542 | * @see ecore_con_url_additional_header_add() | ||
1543 | * @see ecore_con_url_data_set() | ||
1544 | * @see ecore_con_url_data_get() | ||
1545 | * @see ecore_con_url_response_headers_get() | ||
1546 | * @see ecore_con_url_time() | ||
1547 | * @see ecore_con_url_post() | ||
1548 | */ | ||
1549 | EAPI Eina_Bool ecore_con_url_get(Ecore_Con_Url *url_con); | ||
1550 | /** | ||
1551 | * Sends a post request. | ||
1552 | * | ||
1553 | * @param url_con Connection object to perform a request on, previously created | ||
1554 | * with ecore_con_url_new() or ecore_con_url_custom_new(). | ||
1555 | * @param data Payload (data sent on the request). Can be @c NULL. | ||
1556 | * @param length Payload length. If @c -1, rely on automatic length | ||
1557 | * calculation via @c strlen() on @p data. | ||
1558 | * @param content_type Content type of the payload (e.g. text/xml). Can be @c | ||
1559 | * NULL. | ||
1560 | * | ||
1561 | * @return #EINA_TRUE on success, #EINA_FALSE on error. | ||
1562 | * | ||
1563 | * The request starts immediately, but you need to setup event handlers | ||
1564 | * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or | ||
1565 | * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. | ||
1566 | * | ||
1567 | * This call won't block your main loop. | ||
1568 | * | ||
1569 | * @see ecore_con_url_custom_new() | ||
1570 | * @see ecore_con_url_additional_headers_clear() | ||
1571 | * @see ecore_con_url_additional_header_add() | ||
1572 | * @see ecore_con_url_data_set() | ||
1573 | * @see ecore_con_url_data_get() | ||
1574 | * @see ecore_con_url_response_headers_get() | ||
1575 | * @see ecore_con_url_time() | ||
1576 | * @see ecore_con_url_get() | ||
1577 | */ | ||
1578 | EAPI Eina_Bool ecore_con_url_post(Ecore_Con_Url *url_con, | ||
1579 | const void *data, long length, | ||
1580 | const char *content_type); | ||
1581 | /** | ||
1582 | * Sets whether HTTP requests should be conditional, dependent on | ||
1583 | * modification time. | ||
1584 | * | ||
1585 | * @param url_con Ecore_Con_Url to act upon. | ||
1586 | * @param condition Condition to use for HTTP requests. | ||
1587 | * @param timestamp Time since 1 Jan 1970 to use in the condition. | ||
1588 | * | ||
1589 | * This function may set the header "If-Modified-Since" or | ||
1590 | * "If-Unmodified-Since", depending on the value of @p time_condition, with the | ||
1591 | * value @p timestamp. | ||
1592 | * | ||
1593 | * @sa ecore_con_url_get() | ||
1594 | * @sa ecore_con_url_post() | ||
1595 | */ | ||
1596 | EAPI void ecore_con_url_time(Ecore_Con_Url *url_con, | ||
1597 | Ecore_Con_Url_Time time_condition, | ||
1598 | double timestamp); | ||
1599 | |||
1600 | /** | ||
1601 | * @brief Uploads a file to an ftp site. | ||
1602 | * @param url_con The Ecore_Con_Url object to send with | ||
1603 | * @param filename The path to the file to send | ||
1604 | * @param user The username to log in with | ||
1605 | * @param pass The password to log in with | ||
1606 | * @param upload_dir The directory to which the file should be uploaded | ||
1607 | * @return #EINA_TRUE on success, else #EINA_FALSE. | ||
1608 | * Upload @p filename to an ftp server set in @p url_con using @p user | ||
1609 | * and @p pass to directory @p upload_dir | ||
1610 | */ | ||
1611 | EAPI Eina_Bool ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, | ||
1612 | const char *filename, | ||
1613 | const char *user, | ||
1614 | const char *pass, | ||
1615 | const char *upload_dir); | ||
1616 | /** | ||
1617 | * Toggle libcurl's verbose output. | ||
1618 | * | ||
1619 | * @param url_con Ecore_Con_Url instance which will be acted upon. | ||
1620 | * @param verbose Whether or not to enable libcurl's verbose output. | ||
1621 | * | ||
1622 | * If @p verbose is @c EINA_TRUE, libcurl will output a lot of verbose | ||
1623 | * information about its operations, which is useful for | ||
1624 | * debugging. The verbose information will be sent to stderr. | ||
1625 | */ | ||
1626 | EAPI void ecore_con_url_verbose_set(Ecore_Con_Url *url_con, | ||
1627 | Eina_Bool verbose); | ||
1628 | /** | ||
1629 | * Enable or disable EPSV extension | ||
1630 | * @return FIXME: To be more documented. | ||
1631 | */ | ||
1632 | EAPI void ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, | ||
1633 | Eina_Bool use_epsv); | ||
1634 | |||
1635 | /** | ||
1636 | * Enables the cookie engine for subsequent HTTP requests. | ||
1637 | * | ||
1638 | * @param url_con Ecore_Con_Url instance which will be acted upon. | ||
1639 | * | ||
1640 | * After this function is called, cookies set by the server in HTTP responses | ||
1641 | * will be parsed and stored, as well as sent back to the server in new HTTP | ||
1642 | * requests. | ||
1643 | * | ||
1644 | * @note Even though this function is called @c ecore_con_url_cookies_init(), | ||
1645 | * there is no symmetrical shutdown operation. | ||
1646 | */ | ||
1647 | EAPI void ecore_con_url_cookies_init(Ecore_Con_Url *url_con); | ||
1648 | /** | ||
1649 | * Controls whether session cookies from previous sessions shall be loaded. | ||
1650 | * | ||
1651 | * @param url_con Ecore_Con_Url instance which will be acted upon. | ||
1652 | * @param ignore If @c EINA_TRUE, ignore session cookies when loading cookies | ||
1653 | * from files. If @c EINA_FALSE, all cookies will be loaded. | ||
1654 | * | ||
1655 | * Session cookies are cookies with no expire date set, which usually means | ||
1656 | * they are removed after the current session is closed. | ||
1657 | * | ||
1658 | * By default, when Ecore_Con_Url loads cookies from a file, all cookies are | ||
1659 | * loaded, including session cookies, which, most of the time, were supposed | ||
1660 | * to be loaded and valid only for that session. | ||
1661 | * | ||
1662 | * If @p ignore is set to @c EINA_TRUE, when Ecore_Con_Url loads cookies from | ||
1663 | * the files passed to @c ecore_con_url_cookies_file_add(), session cookies | ||
1664 | * will not be loaded. | ||
1665 | * | ||
1666 | * @see ecore_con_url_cookies_file_add() | ||
1667 | */ | ||
1668 | EAPI void ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, | ||
1669 | Eina_Bool ignore); | ||
1670 | /** | ||
1671 | * Clears currently loaded cookies. | ||
1672 | * @param url_con Ecore_Con_Url instance which will be acted upon. | ||
1673 | * | ||
1674 | * The cleared cookies are removed and will not be sent in subsequent HTTP | ||
1675 | * requests, nor will they be written to the cookiejar file set via | ||
1676 | * @c ecore_con_url_cookies_jar_file_set(). | ||
1677 | * | ||
1678 | * @note This function will initialize the cookie engine if it has not been | ||
1679 | * initialized yet. | ||
1680 | * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded | ||
1681 | * immediately, just when the request is started. Thus, if you ask to | ||
1682 | * clear the cookies, but has a file already set by that function, the | ||
1683 | * cookies will then be loaded and you will have old cookies set. In order | ||
1684 | * to don't have any old cookie set, you need to don't call | ||
1685 | * ecore_con_url_cookies_file_add() ever on the @p url_con handler, and | ||
1686 | * call this function to clear any cookie set by a previous request on | ||
1687 | * this handler. | ||
1688 | * | ||
1689 | * @see ecore_con_url_cookies_session_clear() | ||
1690 | * @see ecore_con_url_cookies_ignore_old_session_set() | ||
1691 | */ | ||
1692 | EAPI void ecore_con_url_cookies_clear(Ecore_Con_Url *url_con); | ||
1693 | /** | ||
1694 | * Clears currently loaded session cookies. | ||
1695 | * | ||
1696 | * @param url_con Ecore_Con_Url instance which will be acted upon. | ||
1697 | * | ||
1698 | * Session cookies are cookies with no expire date set, which usually means | ||
1699 | * they are removed after the current session is closed. | ||
1700 | * | ||
1701 | * The cleared cookies are removed and will not be sent in subsequent HTTP | ||
1702 | * requests, nor will they be written to the cookiejar file set via | ||
1703 | * @c ecore_con_url_cookies_jar_file_set(). | ||
1704 | * | ||
1705 | * @note This function will initialize the cookie engine if it has not been | ||
1706 | * initialized yet. | ||
1707 | * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded | ||
1708 | * immediately, just when the request is started. Thus, if you ask to | ||
1709 | * clear the session cookies, but has a file already set by that function, | ||
1710 | * the session cookies will then be loaded and you will have old cookies | ||
1711 | * set. In order to don't have any old session cookie set, you need to | ||
1712 | * don't call ecore_con_url_cookies_file_add() ever on the @p url_con | ||
1713 | * handler, and call this function to clear any session cookie set by a | ||
1714 | * previous request on this handler. An easier way to don't use old | ||
1715 | * session cookies is by using the function | ||
1716 | * ecore_con_url_cookies_ignore_old_session_set(). | ||
1717 | * | ||
1718 | * @see ecore_con_url_cookies_clear() | ||
1719 | * @see ecore_con_url_cookies_ignore_old_session_set() | ||
1720 | */ | ||
1721 | EAPI void ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con); | ||
1722 | /** | ||
1723 | * Adds a file to the list of files from which to load cookies. | ||
1724 | * | ||
1725 | * @param url_con Ecore_Con_Url instance which will be acted upon. | ||
1726 | * @param file_name Name of the file that will be added to the list. | ||
1727 | * | ||
1728 | * Files must contain cookies defined according to two possible formats: | ||
1729 | * | ||
1730 | * @li HTTP-style header ("Set-Cookie: ..."). | ||
1731 | * @li <a href="http://www.cookiecentral.com/faq/#3.5">Netscape/Mozilla cookie data format.</a> | ||
1732 | * | ||
1733 | * Cookies will only be @b read from this file. If you want to save cookies to a | ||
1734 | * file, use ecore_con_url_cookies_jar_file_set(). Also notice that this | ||
1735 | * function supports the both types of cookie file cited above, while | ||
1736 | * ecore_con_url_cookies_jar_file_set() will save only in the Netscape/Mozilla's | ||
1737 | * format. | ||
1738 | * | ||
1739 | * Please notice that the file will not be read immediately, but rather added | ||
1740 | * to a list of files that will be loaded and parsed at a later time. | ||
1741 | * | ||
1742 | * @note This function will initialize the cookie engine if it has not been | ||
1743 | * initialized yet. | ||
1744 | * | ||
1745 | * @see ecore_con_url_cookies_ignore_old_session_set() | ||
1746 | * @see ecore_con_url_cookies_jar_file_set() | ||
1747 | */ | ||
1748 | EAPI void ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, | ||
1749 | const char * const file_name); | ||
1750 | /** | ||
1751 | * Sets the name of the file to which all current cookies will be written when | ||
1752 | * either cookies are flushed or Ecore_Con is shut down. | ||
1753 | * | ||
1754 | * @param url_con Ecore_Con_Url instance which will be acted upon. | ||
1755 | * @param cookiejar_file File to which the cookies will be written. | ||
1756 | * | ||
1757 | * @return @c EINA_TRUE is the file name has been set successfully, | ||
1758 | * @c EINA_FALSE otherwise. | ||
1759 | * | ||
1760 | * Cookies are written following Netscape/Mozilla's data format, also known as | ||
1761 | * cookie-jar. | ||
1762 | * | ||
1763 | * Cookies will only be @b saved to this file. If you need to read cookies from | ||
1764 | * a file, use ecore_con_url_cookies_file_add() instead. | ||
1765 | * | ||
1766 | * @note This function will initialize the cookie engine if it has not been | ||
1767 | * initialized yet. | ||
1768 | * | ||
1769 | * @see ecore_con_url_cookies_jar_write() | ||
1770 | */ | ||
1771 | EAPI Eina_Bool ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, | ||
1772 | const char * const cookiejar_file); | ||
1773 | /** | ||
1774 | * Writes all current cookies to the cookie jar immediately. | ||
1775 | * | ||
1776 | * @param url_con Ecore_Con_Url instance which will be acted upon. | ||
1777 | * | ||
1778 | * A cookie-jar file must have been previously set by | ||
1779 | * @c ecore_con_url_jar_file_set, otherwise nothing will be done. | ||
1780 | * | ||
1781 | * @note This function will initialize the cookie engine if it has not been | ||
1782 | * initialized yet. | ||
1783 | * | ||
1784 | * @see ecore_con_url_cookies_jar_file_set() | ||
1785 | */ | ||
1786 | EAPI void ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con); | ||
1787 | |||
1788 | EAPI void ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con, | ||
1789 | Eina_Bool verify); | ||
1790 | EAPI int ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, | ||
1791 | const char *ca_path); | ||
1792 | |||
1793 | /** | ||
1794 | * @} | ||
1795 | */ | ||
1796 | |||
1797 | #ifdef __cplusplus | ||
1798 | } | ||
1799 | #endif | ||
1800 | |||
1801 | #endif | ||
diff --git a/libraries/ecore/src/lib/ecore_con/Makefile.am b/libraries/ecore/src/lib/ecore_con/Makefile.am new file mode 100644 index 0000000..300586d --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/Makefile.am | |||
@@ -0,0 +1,45 @@ | |||
1 | MAINTAINERCLEANFILES = Makefile.in | ||
2 | |||
3 | AM_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 | |||
16 | lib_LTLIBRARIES = libecore_con.la | ||
17 | includes_HEADERS = Ecore_Con.h | ||
18 | includesdir = $(includedir)/ecore-@VMAJ@ | ||
19 | |||
20 | libecore_con_la_SOURCES = \ | ||
21 | ecore_con.c \ | ||
22 | ecore_con_ssl.c \ | ||
23 | ecore_con_url.c \ | ||
24 | ecore_con_alloc.c | ||
25 | |||
26 | if ECORE_HAVE_WIN32 | ||
27 | libecore_con_la_SOURCES += ecore_con_local_win32.c | ||
28 | else | ||
29 | libecore_con_la_SOURCES += ecore_con_local.c | ||
30 | endif | ||
31 | |||
32 | if HAVE_CARES | ||
33 | libecore_con_la_SOURCES += ecore_con_ares.c | ||
34 | else | ||
35 | libecore_con_la_SOURCES += ecore_con_info.c | ||
36 | endif | ||
37 | |||
38 | libecore_con_la_CFLAGS = @WIN32_CFLAGS@ | ||
39 | libecore_con_la_LIBADD = \ | ||
40 | $(top_builddir)/src/lib/ecore/libecore.la \ | ||
41 | @SSL_LIBS@ @CURL_LIBS@ @EINA_LIBS@ @TLS_LIBS@ @CARES_LIBS@ @WIN32_LIBS@ | ||
42 | |||
43 | libecore_con_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ | ||
44 | |||
45 | EXTRA_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 new file mode 100644 index 0000000..5940a83 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/Makefile.in | |||
@@ -0,0 +1,909 @@ | |||
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 | |||
19 | VPATH = @srcdir@ | ||
20 | pkgdatadir = $(datadir)/@PACKAGE@ | ||
21 | pkgincludedir = $(includedir)/@PACKAGE@ | ||
22 | pkglibdir = $(libdir)/@PACKAGE@ | ||
23 | pkglibexecdir = $(libexecdir)/@PACKAGE@ | ||
24 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd | ||
25 | install_sh_DATA = $(install_sh) -c -m 644 | ||
26 | install_sh_PROGRAM = $(install_sh) -c | ||
27 | install_sh_SCRIPT = $(install_sh) -c | ||
28 | INSTALL_HEADER = $(INSTALL_DATA) | ||
29 | transform = $(program_transform_name) | ||
30 | NORMAL_INSTALL = : | ||
31 | PRE_INSTALL = : | ||
32 | POST_INSTALL = : | ||
33 | NORMAL_UNINSTALL = : | ||
34 | PRE_UNINSTALL = : | ||
35 | POST_UNINSTALL = : | ||
36 | build_triplet = @build@ | ||
37 | host_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 | ||
42 | subdir = src/lib/ecore_con | ||
43 | DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \ | ||
44 | $(srcdir)/Makefile.in | ||
45 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ||
46 | am__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/isc-posix.m4 $(top_srcdir)/m4/lib-ld.m4 \ | ||
58 | $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ | ||
59 | $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ | ||
60 | $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ | ||
61 | $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ | ||
62 | $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ | ||
63 | $(top_srcdir)/configure.ac | ||
64 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ | ||
65 | $(ACLOCAL_M4) | ||
66 | mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs | ||
67 | CONFIG_HEADER = $(top_builddir)/config.h | ||
68 | CONFIG_CLEAN_FILES = | ||
69 | CONFIG_CLEAN_VPATH_FILES = | ||
70 | am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; | ||
71 | am__vpath_adj = case $$p in \ | ||
72 | $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ | ||
73 | *) f=$$p;; \ | ||
74 | esac; | ||
75 | am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; | ||
76 | am__install_max = 40 | ||
77 | am__nobase_strip_setup = \ | ||
78 | srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` | ||
79 | am__nobase_strip = \ | ||
80 | for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" | ||
81 | am__nobase_list = $(am__nobase_strip_setup); \ | ||
82 | for p in $$list; do echo "$$p $$p"; done | \ | ||
83 | sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ | ||
84 | $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ | ||
85 | if (++n[$$2] == $(am__install_max)) \ | ||
86 | { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ | ||
87 | END { for (dir in files) print dir, files[dir] }' | ||
88 | am__base_list = \ | ||
89 | sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ | ||
90 | sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | ||
91 | am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)" | ||
92 | LTLIBRARIES = $(lib_LTLIBRARIES) | ||
93 | libecore_con_la_DEPENDENCIES = \ | ||
94 | $(top_builddir)/src/lib/ecore/libecore.la | ||
95 | am__libecore_con_la_SOURCES_DIST = ecore_con.c ecore_con_ssl.c \ | ||
96 | ecore_con_url.c ecore_con_alloc.c ecore_con_local_win32.c \ | ||
97 | ecore_con_local.c ecore_con_ares.c 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 | ||
103 | am_libecore_con_la_OBJECTS = libecore_con_la-ecore_con.lo \ | ||
104 | libecore_con_la-ecore_con_ssl.lo \ | ||
105 | libecore_con_la-ecore_con_url.lo \ | ||
106 | libecore_con_la-ecore_con_alloc.lo $(am__objects_1) \ | ||
107 | $(am__objects_2) $(am__objects_3) $(am__objects_4) | ||
108 | libecore_con_la_OBJECTS = $(am_libecore_con_la_OBJECTS) | ||
109 | AM_V_lt = $(am__v_lt_$(V)) | ||
110 | am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) | ||
111 | am__v_lt_0 = --silent | ||
112 | libecore_con_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ | ||
113 | $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ | ||
114 | $(libecore_con_la_CFLAGS) $(CFLAGS) $(libecore_con_la_LDFLAGS) \ | ||
115 | $(LDFLAGS) -o $@ | ||
116 | DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) | ||
117 | depcomp = $(SHELL) $(top_srcdir)/depcomp | ||
118 | am__depfiles_maybe = depfiles | ||
119 | am__mv = mv -f | ||
120 | COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ | ||
121 | $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||
122 | LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
123 | $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ | ||
124 | $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ | ||
125 | $(AM_CFLAGS) $(CFLAGS) | ||
126 | AM_V_CC = $(am__v_CC_$(V)) | ||
127 | am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) | ||
128 | am__v_CC_0 = @echo " CC " $@; | ||
129 | AM_V_at = $(am__v_at_$(V)) | ||
130 | am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) | ||
131 | am__v_at_0 = @ | ||
132 | CCLD = $(CC) | ||
133 | LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
134 | $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ | ||
135 | $(AM_LDFLAGS) $(LDFLAGS) -o $@ | ||
136 | AM_V_CCLD = $(am__v_CCLD_$(V)) | ||
137 | am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) | ||
138 | am__v_CCLD_0 = @echo " CCLD " $@; | ||
139 | AM_V_GEN = $(am__v_GEN_$(V)) | ||
140 | am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) | ||
141 | am__v_GEN_0 = @echo " GEN " $@; | ||
142 | SOURCES = $(libecore_con_la_SOURCES) | ||
143 | DIST_SOURCES = $(am__libecore_con_la_SOURCES_DIST) | ||
144 | HEADERS = $(includes_HEADERS) | ||
145 | ETAGS = etags | ||
146 | CTAGS = ctags | ||
147 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) | ||
148 | ACLOCAL = @ACLOCAL@ | ||
149 | ALLOCA = @ALLOCA@ | ||
150 | AMTAR = @AMTAR@ | ||
151 | AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ | ||
152 | AR = @AR@ | ||
153 | AS = @AS@ | ||
154 | AUTOCONF = @AUTOCONF@ | ||
155 | AUTOHEADER = @AUTOHEADER@ | ||
156 | AUTOMAKE = @AUTOMAKE@ | ||
157 | AWK = @AWK@ | ||
158 | CARES_CFLAGS = @CARES_CFLAGS@ | ||
159 | CARES_LIBS = @CARES_LIBS@ | ||
160 | CC = @CC@ | ||
161 | CCDEPMODE = @CCDEPMODE@ | ||
162 | CFLAGS = @CFLAGS@ | ||
163 | CHECK_CFLAGS = @CHECK_CFLAGS@ | ||
164 | CHECK_LIBS = @CHECK_LIBS@ | ||
165 | CPP = @CPP@ | ||
166 | CPPFLAGS = @CPPFLAGS@ | ||
167 | CURL_CFLAGS = @CURL_CFLAGS@ | ||
168 | CURL_LIBS = @CURL_LIBS@ | ||
169 | CXX = @CXX@ | ||
170 | CXXCPP = @CXXCPP@ | ||
171 | CXXDEPMODE = @CXXDEPMODE@ | ||
172 | CXXFLAGS = @CXXFLAGS@ | ||
173 | CYGPATH_W = @CYGPATH_W@ | ||
174 | DEFS = @DEFS@ | ||
175 | DEPDIR = @DEPDIR@ | ||
176 | DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@ | ||
177 | DIRECTFB_LIBS = @DIRECTFB_LIBS@ | ||
178 | DLLTOOL = @DLLTOOL@ | ||
179 | DSYMUTIL = @DSYMUTIL@ | ||
180 | DUMPBIN = @DUMPBIN@ | ||
181 | ECHO_C = @ECHO_C@ | ||
182 | ECHO_N = @ECHO_N@ | ||
183 | ECHO_T = @ECHO_T@ | ||
184 | ECORE_XCB_CFLAGS = @ECORE_XCB_CFLAGS@ | ||
185 | ECORE_XCB_LIBS = @ECORE_XCB_LIBS@ | ||
186 | EFL_ECORE_BUILD = @EFL_ECORE_BUILD@ | ||
187 | EFL_ECORE_CON_BUILD = @EFL_ECORE_CON_BUILD@ | ||
188 | EFL_ECORE_EVAS_BUILD = @EFL_ECORE_EVAS_BUILD@ | ||
189 | EFL_ECORE_FILE_BUILD = @EFL_ECORE_FILE_BUILD@ | ||
190 | EFL_ECORE_IMF_BUILD = @EFL_ECORE_IMF_BUILD@ | ||
191 | EFL_ECORE_IMF_EVAS_BUILD = @EFL_ECORE_IMF_EVAS_BUILD@ | ||
192 | EFL_ECORE_INPUT_BUILD = @EFL_ECORE_INPUT_BUILD@ | ||
193 | EFL_ECORE_INPUT_EVAS_BUILD = @EFL_ECORE_INPUT_EVAS_BUILD@ | ||
194 | EFL_ECORE_IPC_BUILD = @EFL_ECORE_IPC_BUILD@ | ||
195 | EFL_ECORE_PSL1GHT_BUILD = @EFL_ECORE_PSL1GHT_BUILD@ | ||
196 | EFL_ECORE_SDL_BUILD = @EFL_ECORE_SDL_BUILD@ | ||
197 | EFL_ECORE_WIN32_BUILD = @EFL_ECORE_WIN32_BUILD@ | ||
198 | EFL_ECORE_WINCE_BUILD = @EFL_ECORE_WINCE_BUILD@ | ||
199 | EFL_PTHREAD_CFLAGS = @EFL_PTHREAD_CFLAGS@ | ||
200 | EFL_PTHREAD_LIBS = @EFL_PTHREAD_LIBS@ | ||
201 | EGREP = @EGREP@ | ||
202 | EINA_CFLAGS = @EINA_CFLAGS@ | ||
203 | EINA_LIBS = @EINA_LIBS@ | ||
204 | ESCAPE_CFLAGS = @ESCAPE_CFLAGS@ | ||
205 | ESCAPE_LIBS = @ESCAPE_LIBS@ | ||
206 | EVAS_CFLAGS = @EVAS_CFLAGS@ | ||
207 | EVAS_LIBS = @EVAS_LIBS@ | ||
208 | EVIL_CFLAGS = @EVIL_CFLAGS@ | ||
209 | EVIL_LIBS = @EVIL_LIBS@ | ||
210 | EXEEXT = @EXEEXT@ | ||
211 | FGREP = @FGREP@ | ||
212 | GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ | ||
213 | GLIB_CFLAGS = @GLIB_CFLAGS@ | ||
214 | GLIB_LIBS = @GLIB_LIBS@ | ||
215 | GMSGFMT = @GMSGFMT@ | ||
216 | GMSGFMT_015 = @GMSGFMT_015@ | ||
217 | GREP = @GREP@ | ||
218 | INSTALL = @INSTALL@ | ||
219 | INSTALL_DATA = @INSTALL_DATA@ | ||
220 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ | ||
221 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ | ||
222 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ | ||
223 | INTLLIBS = @INTLLIBS@ | ||
224 | INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ | ||
225 | KEYSYMDEFS = @KEYSYMDEFS@ | ||
226 | LD = @LD@ | ||
227 | LDFLAGS = @LDFLAGS@ | ||
228 | LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ | ||
229 | LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ | ||
230 | LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ | ||
231 | LIBICONV = @LIBICONV@ | ||
232 | LIBINTL = @LIBINTL@ | ||
233 | LIBOBJS = @LIBOBJS@ | ||
234 | LIBS = @LIBS@ | ||
235 | LIBTOOL = @LIBTOOL@ | ||
236 | LIPO = @LIPO@ | ||
237 | LN_S = @LN_S@ | ||
238 | LTLIBICONV = @LTLIBICONV@ | ||
239 | LTLIBINTL = @LTLIBINTL@ | ||
240 | LTLIBOBJS = @LTLIBOBJS@ | ||
241 | MAKEINFO = @MAKEINFO@ | ||
242 | MKDIR_P = @MKDIR_P@ | ||
243 | MSGFMT = @MSGFMT@ | ||
244 | MSGFMT_015 = @MSGFMT_015@ | ||
245 | MSGMERGE = @MSGMERGE@ | ||
246 | NM = @NM@ | ||
247 | NMEDIT = @NMEDIT@ | ||
248 | OBJC = @OBJC@ | ||
249 | OBJCDEPMODE = @OBJCDEPMODE@ | ||
250 | OBJCFLAGS = @OBJCFLAGS@ | ||
251 | OBJDUMP = @OBJDUMP@ | ||
252 | OBJEXT = @OBJEXT@ | ||
253 | OTOOL = @OTOOL@ | ||
254 | OTOOL64 = @OTOOL64@ | ||
255 | PACKAGE = @PACKAGE@ | ||
256 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ | ||
257 | PACKAGE_NAME = @PACKAGE_NAME@ | ||
258 | PACKAGE_STRING = @PACKAGE_STRING@ | ||
259 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ | ||
260 | PACKAGE_URL = @PACKAGE_URL@ | ||
261 | PACKAGE_VERSION = @PACKAGE_VERSION@ | ||
262 | PATH_SEPARATOR = @PATH_SEPARATOR@ | ||
263 | PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ | ||
264 | PIXMAN_LIBS = @PIXMAN_LIBS@ | ||
265 | PKG_CONFIG = @PKG_CONFIG@ | ||
266 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ | ||
267 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ | ||
268 | POSUB = @POSUB@ | ||
269 | RANLIB = @RANLIB@ | ||
270 | SDL_CFLAGS = @SDL_CFLAGS@ | ||
271 | SDL_CONFIG = @SDL_CONFIG@ | ||
272 | SDL_LIBS = @SDL_LIBS@ | ||
273 | SED = @SED@ | ||
274 | SET_MAKE = @SET_MAKE@ | ||
275 | SHELL = @SHELL@ | ||
276 | SSL_CFLAGS = @SSL_CFLAGS@ | ||
277 | SSL_LIBS = @SSL_LIBS@ | ||
278 | STRIP = @STRIP@ | ||
279 | TLS2_CFLAGS = @TLS2_CFLAGS@ | ||
280 | TLS2_LIBS = @TLS2_LIBS@ | ||
281 | TLS_CFLAGS = @TLS_CFLAGS@ | ||
282 | TLS_LIBS = @TLS_LIBS@ | ||
283 | TSLIB_CFLAGS = @TSLIB_CFLAGS@ | ||
284 | TSLIB_LIBS = @TSLIB_LIBS@ | ||
285 | USE_NLS = @USE_NLS@ | ||
286 | VERSION = @VERSION@ | ||
287 | VMAJ = @VMAJ@ | ||
288 | WIN32_CFLAGS = @WIN32_CFLAGS@ | ||
289 | WIN32_CPPFLAGS = @WIN32_CPPFLAGS@ | ||
290 | WIN32_LIBS = @WIN32_LIBS@ | ||
291 | XCB_COMPOSITE_CFLAGS = @XCB_COMPOSITE_CFLAGS@ | ||
292 | XCB_COMPOSITE_LIBS = @XCB_COMPOSITE_LIBS@ | ||
293 | XCB_CURSOR_CFLAGS = @XCB_CURSOR_CFLAGS@ | ||
294 | XCB_CURSOR_LIBS = @XCB_CURSOR_LIBS@ | ||
295 | XCB_DAMAGE_CFLAGS = @XCB_DAMAGE_CFLAGS@ | ||
296 | XCB_DAMAGE_LIBS = @XCB_DAMAGE_LIBS@ | ||
297 | XCB_DPMS_CFLAGS = @XCB_DPMS_CFLAGS@ | ||
298 | XCB_DPMS_LIBS = @XCB_DPMS_LIBS@ | ||
299 | XCB_RANDR_CFLAGS = @XCB_RANDR_CFLAGS@ | ||
300 | XCB_RANDR_LIBS = @XCB_RANDR_LIBS@ | ||
301 | XCB_RENDER_CFLAGS = @XCB_RENDER_CFLAGS@ | ||
302 | XCB_RENDER_LIBS = @XCB_RENDER_LIBS@ | ||
303 | XCB_SCREENSAVER_CFLAGS = @XCB_SCREENSAVER_CFLAGS@ | ||
304 | XCB_SCREENSAVER_LIBS = @XCB_SCREENSAVER_LIBS@ | ||
305 | XCB_SHAPE_CFLAGS = @XCB_SHAPE_CFLAGS@ | ||
306 | XCB_SHAPE_LIBS = @XCB_SHAPE_LIBS@ | ||
307 | XCB_SYNC_CFLAGS = @XCB_SYNC_CFLAGS@ | ||
308 | XCB_SYNC_LIBS = @XCB_SYNC_LIBS@ | ||
309 | XCB_X11_CFLAGS = @XCB_X11_CFLAGS@ | ||
310 | XCB_X11_LIBS = @XCB_X11_LIBS@ | ||
311 | XCB_XFIXES_CFLAGS = @XCB_XFIXES_CFLAGS@ | ||
312 | XCB_XFIXES_LIBS = @XCB_XFIXES_LIBS@ | ||
313 | XCB_XGESTURE_CFLAGS = @XCB_XGESTURE_CFLAGS@ | ||
314 | XCB_XGESTURE_LIBS = @XCB_XGESTURE_LIBS@ | ||
315 | XCB_XINERAMA_CFLAGS = @XCB_XINERAMA_CFLAGS@ | ||
316 | XCB_XINERAMA_LIBS = @XCB_XINERAMA_LIBS@ | ||
317 | XCB_XINPUT_CFLAGS = @XCB_XINPUT_CFLAGS@ | ||
318 | XCB_XINPUT_LIBS = @XCB_XINPUT_LIBS@ | ||
319 | XCB_XPRINT_CFLAGS = @XCB_XPRINT_CFLAGS@ | ||
320 | XCB_XPRINT_LIBS = @XCB_XPRINT_LIBS@ | ||
321 | XCB_XTEST_CFLAGS = @XCB_XTEST_CFLAGS@ | ||
322 | XCB_XTEST_LIBS = @XCB_XTEST_LIBS@ | ||
323 | XCOMPOSITE_CFLAGS = @XCOMPOSITE_CFLAGS@ | ||
324 | XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ | ||
325 | XDAMAGE_CFLAGS = @XDAMAGE_CFLAGS@ | ||
326 | XDAMAGE_LIBS = @XDAMAGE_LIBS@ | ||
327 | XDPMS_CFLAGS = @XDPMS_CFLAGS@ | ||
328 | XDPMS_LIBS = @XDPMS_LIBS@ | ||
329 | XFIXES_CFLAGS = @XFIXES_CFLAGS@ | ||
330 | XFIXES_LIBS = @XFIXES_LIBS@ | ||
331 | XGESTURE_CFLAGS = @XGESTURE_CFLAGS@ | ||
332 | XGESTURE_LIBS = @XGESTURE_LIBS@ | ||
333 | XGETTEXT = @XGETTEXT@ | ||
334 | XGETTEXT_015 = @XGETTEXT_015@ | ||
335 | XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ | ||
336 | XI2_CFLAGS = @XI2_CFLAGS@ | ||
337 | XI2_LIBS = @XI2_LIBS@ | ||
338 | XINERAMA_CFLAGS = @XINERAMA_CFLAGS@ | ||
339 | XINERAMA_LIBS = @XINERAMA_LIBS@ | ||
340 | XKB_CFLAGS = @XKB_CFLAGS@ | ||
341 | XKB_LIBS = @XKB_LIBS@ | ||
342 | XMKMF = @XMKMF@ | ||
343 | XPRINT_CFLAGS = @XPRINT_CFLAGS@ | ||
344 | XPRINT_LIBS = @XPRINT_LIBS@ | ||
345 | XRANDR_CFLAGS = @XRANDR_CFLAGS@ | ||
346 | XRANDR_LIBS = @XRANDR_LIBS@ | ||
347 | XRENDER_CFLAGS = @XRENDER_CFLAGS@ | ||
348 | XRENDER_LIBS = @XRENDER_LIBS@ | ||
349 | XSS_CFLAGS = @XSS_CFLAGS@ | ||
350 | XSS_LIBS = @XSS_LIBS@ | ||
351 | XTEST_CFLAGS = @XTEST_CFLAGS@ | ||
352 | XTEST_LIBS = @XTEST_LIBS@ | ||
353 | X_CFLAGS = @X_CFLAGS@ | ||
354 | X_EXTRA_LIBS = @X_EXTRA_LIBS@ | ||
355 | X_LIBS = @X_LIBS@ | ||
356 | X_PRE_LIBS = @X_PRE_LIBS@ | ||
357 | Xcursor_cflags = @Xcursor_cflags@ | ||
358 | Xcursor_libs = @Xcursor_libs@ | ||
359 | abs_builddir = @abs_builddir@ | ||
360 | abs_srcdir = @abs_srcdir@ | ||
361 | abs_top_builddir = @abs_top_builddir@ | ||
362 | abs_top_srcdir = @abs_top_srcdir@ | ||
363 | ac_ct_CC = @ac_ct_CC@ | ||
364 | ac_ct_CXX = @ac_ct_CXX@ | ||
365 | ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ | ||
366 | ac_ct_OBJC = @ac_ct_OBJC@ | ||
367 | am__include = @am__include@ | ||
368 | am__leading_dot = @am__leading_dot@ | ||
369 | am__quote = @am__quote@ | ||
370 | am__tar = @am__tar@ | ||
371 | am__untar = @am__untar@ | ||
372 | bindir = @bindir@ | ||
373 | build = @build@ | ||
374 | build_alias = @build_alias@ | ||
375 | build_cpu = @build_cpu@ | ||
376 | build_os = @build_os@ | ||
377 | build_vendor = @build_vendor@ | ||
378 | builddir = @builddir@ | ||
379 | cocoa_ldflags = @cocoa_ldflags@ | ||
380 | datadir = @datadir@ | ||
381 | datarootdir = @datarootdir@ | ||
382 | dlopen_libs = @dlopen_libs@ | ||
383 | docdir = @docdir@ | ||
384 | dvidir = @dvidir@ | ||
385 | ecore_cocoa_cflags = @ecore_cocoa_cflags@ | ||
386 | ecore_cocoa_libs = @ecore_cocoa_libs@ | ||
387 | ecore_con_cflags = @ecore_con_cflags@ | ||
388 | ecore_con_libs = @ecore_con_libs@ | ||
389 | ecore_directfb_cflags = @ecore_directfb_cflags@ | ||
390 | ecore_directfb_libs = @ecore_directfb_libs@ | ||
391 | ecore_evas_cflags = @ecore_evas_cflags@ | ||
392 | ecore_evas_libs = @ecore_evas_libs@ | ||
393 | ecore_fb_cflags = @ecore_fb_cflags@ | ||
394 | ecore_fb_libs = @ecore_fb_libs@ | ||
395 | ecore_file_cflags = @ecore_file_cflags@ | ||
396 | ecore_file_libs = @ecore_file_libs@ | ||
397 | ecore_imf_cflags = @ecore_imf_cflags@ | ||
398 | ecore_imf_evas_cflags = @ecore_imf_evas_cflags@ | ||
399 | ecore_imf_evas_libs = @ecore_imf_evas_libs@ | ||
400 | ecore_imf_libs = @ecore_imf_libs@ | ||
401 | ecore_imf_xim_cflags = @ecore_imf_xim_cflags@ | ||
402 | ecore_imf_xim_libs = @ecore_imf_xim_libs@ | ||
403 | ecore_input_cflags = @ecore_input_cflags@ | ||
404 | ecore_input_evas_cflags = @ecore_input_evas_cflags@ | ||
405 | ecore_input_evas_libs = @ecore_input_evas_libs@ | ||
406 | ecore_input_libs = @ecore_input_libs@ | ||
407 | ecore_ipc_cflags = @ecore_ipc_cflags@ | ||
408 | ecore_ipc_libs = @ecore_ipc_libs@ | ||
409 | ecore_psl1ght_cflags = @ecore_psl1ght_cflags@ | ||
410 | ecore_psl1ght_libs = @ecore_psl1ght_libs@ | ||
411 | ecore_sdl_cflags = @ecore_sdl_cflags@ | ||
412 | ecore_sdl_libs = @ecore_sdl_libs@ | ||
413 | ecore_win32_cflags = @ecore_win32_cflags@ | ||
414 | ecore_win32_libs = @ecore_win32_libs@ | ||
415 | ecore_wince_cflags = @ecore_wince_cflags@ | ||
416 | ecore_wince_libs = @ecore_wince_libs@ | ||
417 | ecore_x_cflags = @ecore_x_cflags@ | ||
418 | ecore_x_libs = @ecore_x_libs@ | ||
419 | ecore_x_libs_private = @ecore_x_libs_private@ | ||
420 | efl_doxygen = @efl_doxygen@ | ||
421 | efl_have_doxygen = @efl_have_doxygen@ | ||
422 | exec_prefix = @exec_prefix@ | ||
423 | have_ecore_x_xcb_define = @have_ecore_x_xcb_define@ | ||
424 | host = @host@ | ||
425 | host_alias = @host_alias@ | ||
426 | host_cpu = @host_cpu@ | ||
427 | host_os = @host_os@ | ||
428 | host_vendor = @host_vendor@ | ||
429 | htmldir = @htmldir@ | ||
430 | includedir = @includedir@ | ||
431 | infodir = @infodir@ | ||
432 | install_sh = @install_sh@ | ||
433 | libdir = @libdir@ | ||
434 | libexecdir = @libexecdir@ | ||
435 | localedir = @localedir@ | ||
436 | localstatedir = @localstatedir@ | ||
437 | lt_ECHO = @lt_ECHO@ | ||
438 | lt_enable_auto_import = @lt_enable_auto_import@ | ||
439 | mandir = @mandir@ | ||
440 | mkdir_p = @mkdir_p@ | ||
441 | oldincludedir = @oldincludedir@ | ||
442 | pdfdir = @pdfdir@ | ||
443 | pkgconfig_requires_private = @pkgconfig_requires_private@ | ||
444 | prefix = @prefix@ | ||
445 | program_transform_name = @program_transform_name@ | ||
446 | psdir = @psdir@ | ||
447 | release_info = @release_info@ | ||
448 | requirements_ecore = @requirements_ecore@ | ||
449 | requirements_ecore_cocoa = @requirements_ecore_cocoa@ | ||
450 | requirements_ecore_con = @requirements_ecore_con@ | ||
451 | requirements_ecore_directfb = @requirements_ecore_directfb@ | ||
452 | requirements_ecore_evas = @requirements_ecore_evas@ | ||
453 | requirements_ecore_fb = @requirements_ecore_fb@ | ||
454 | requirements_ecore_file = @requirements_ecore_file@ | ||
455 | requirements_ecore_imf = @requirements_ecore_imf@ | ||
456 | requirements_ecore_imf_evas = @requirements_ecore_imf_evas@ | ||
457 | requirements_ecore_imf_xim = @requirements_ecore_imf_xim@ | ||
458 | requirements_ecore_input = @requirements_ecore_input@ | ||
459 | requirements_ecore_input_evas = @requirements_ecore_input_evas@ | ||
460 | requirements_ecore_ipc = @requirements_ecore_ipc@ | ||
461 | requirements_ecore_psl1ght = @requirements_ecore_psl1ght@ | ||
462 | requirements_ecore_sdl = @requirements_ecore_sdl@ | ||
463 | requirements_ecore_win32 = @requirements_ecore_win32@ | ||
464 | requirements_ecore_wince = @requirements_ecore_wince@ | ||
465 | requirements_ecore_x = @requirements_ecore_x@ | ||
466 | rt_libs = @rt_libs@ | ||
467 | sbindir = @sbindir@ | ||
468 | sharedstatedir = @sharedstatedir@ | ||
469 | srcdir = @srcdir@ | ||
470 | sysconfdir = @sysconfdir@ | ||
471 | target_alias = @target_alias@ | ||
472 | top_build_prefix = @top_build_prefix@ | ||
473 | top_builddir = @top_builddir@ | ||
474 | top_srcdir = @top_srcdir@ | ||
475 | version_info = @version_info@ | ||
476 | x_cflags = @x_cflags@ | ||
477 | x_includes = @x_includes@ | ||
478 | x_libs = @x_libs@ | ||
479 | MAINTAINERCLEANFILES = Makefile.in | ||
480 | AM_CPPFLAGS = \ | ||
481 | -I$(top_builddir)/src/lib/ecore \ | ||
482 | -I$(top_builddir)/src/lib/ecore_con \ | ||
483 | -I$(top_srcdir)/src/lib/ecore \ | ||
484 | -I$(top_srcdir)/src/lib/ecore_con \ | ||
485 | @EFL_ECORE_CON_BUILD@ \ | ||
486 | @SSL_CFLAGS@ \ | ||
487 | @CURL_CFLAGS@ \ | ||
488 | @EINA_CFLAGS@ \ | ||
489 | @TLS_CFLAGS@ \ | ||
490 | @CARES_CFLAGS@ \ | ||
491 | @WIN32_CPPFLAGS@ | ||
492 | |||
493 | lib_LTLIBRARIES = libecore_con.la | ||
494 | includes_HEADERS = Ecore_Con.h | ||
495 | includesdir = $(includedir)/ecore-@VMAJ@ | ||
496 | libecore_con_la_SOURCES = ecore_con.c ecore_con_ssl.c ecore_con_url.c \ | ||
497 | ecore_con_alloc.c $(am__append_1) $(am__append_2) \ | ||
498 | $(am__append_3) $(am__append_4) | ||
499 | libecore_con_la_CFLAGS = @WIN32_CFLAGS@ | ||
500 | libecore_con_la_LIBADD = \ | ||
501 | $(top_builddir)/src/lib/ecore/libecore.la \ | ||
502 | @SSL_LIBS@ @CURL_LIBS@ @EINA_LIBS@ @TLS_LIBS@ @CARES_LIBS@ @WIN32_LIBS@ | ||
503 | |||
504 | libecore_con_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ | ||
505 | EXTRA_DIST = ecore_con_private.h | ||
506 | all: all-am | ||
507 | |||
508 | .SUFFIXES: | ||
509 | .SUFFIXES: .c .lo .o .obj | ||
510 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) | ||
511 | @for dep in $?; do \ | ||
512 | case '$(am__configure_deps)' in \ | ||
513 | *$$dep*) \ | ||
514 | ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ | ||
515 | && { if test -f $@; then exit 0; else break; fi; }; \ | ||
516 | exit 1;; \ | ||
517 | esac; \ | ||
518 | done; \ | ||
519 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lib/ecore_con/Makefile'; \ | ||
520 | $(am__cd) $(top_srcdir) && \ | ||
521 | $(AUTOMAKE) --gnu src/lib/ecore_con/Makefile | ||
522 | .PRECIOUS: Makefile | ||
523 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status | ||
524 | @case '$?' in \ | ||
525 | *config.status*) \ | ||
526 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ | ||
527 | *) \ | ||
528 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ | ||
529 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ | ||
530 | esac; | ||
531 | |||
532 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) | ||
533 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
534 | |||
535 | $(top_srcdir)/configure: $(am__configure_deps) | ||
536 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
537 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) | ||
538 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
539 | $(am__aclocal_m4_deps): | ||
540 | install-libLTLIBRARIES: $(lib_LTLIBRARIES) | ||
541 | @$(NORMAL_INSTALL) | ||
542 | test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" | ||
543 | @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ | ||
544 | list2=; for p in $$list; do \ | ||
545 | if test -f $$p; then \ | ||
546 | list2="$$list2 $$p"; \ | ||
547 | else :; fi; \ | ||
548 | done; \ | ||
549 | test -z "$$list2" || { \ | ||
550 | echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ | ||
551 | $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ | ||
552 | } | ||
553 | |||
554 | uninstall-libLTLIBRARIES: | ||
555 | @$(NORMAL_UNINSTALL) | ||
556 | @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ | ||
557 | for p in $$list; do \ | ||
558 | $(am__strip_dir) \ | ||
559 | echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ | ||
560 | $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ | ||
561 | done | ||
562 | |||
563 | clean-libLTLIBRARIES: | ||
564 | -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) | ||
565 | @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ | ||
566 | dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ | ||
567 | test "$$dir" != "$$p" || dir=.; \ | ||
568 | echo "rm -f \"$${dir}/so_locations\""; \ | ||
569 | rm -f "$${dir}/so_locations"; \ | ||
570 | done | ||
571 | libecore_con.la: $(libecore_con_la_OBJECTS) $(libecore_con_la_DEPENDENCIES) | ||
572 | $(AM_V_CCLD)$(libecore_con_la_LINK) -rpath $(libdir) $(libecore_con_la_OBJECTS) $(libecore_con_la_LIBADD) $(LIBS) | ||
573 | |||
574 | mostlyclean-compile: | ||
575 | -rm -f *.$(OBJEXT) | ||
576 | |||
577 | distclean-compile: | ||
578 | -rm -f *.tab.c | ||
579 | |||
580 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con.Plo@am__quote@ | ||
581 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_alloc.Plo@am__quote@ | ||
582 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_ares.Plo@am__quote@ | ||
583 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_info.Plo@am__quote@ | ||
584 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_local.Plo@am__quote@ | ||
585 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_local_win32.Plo@am__quote@ | ||
586 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_ssl.Plo@am__quote@ | ||
587 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_url.Plo@am__quote@ | ||
588 | |||
589 | .c.o: | ||
590 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | ||
591 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
592 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
593 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
594 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
595 | @am__fastdepCC_FALSE@ $(COMPILE) -c $< | ||
596 | |||
597 | .c.obj: | ||
598 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` | ||
599 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
600 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
601 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
602 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
603 | @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` | ||
604 | |||
605 | .c.lo: | ||
606 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | ||
607 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo | ||
608 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
609 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ | ||
610 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
611 | @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< | ||
612 | |||
613 | libecore_con_la-ecore_con.lo: ecore_con.c | ||
614 | @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 | ||
615 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con.Tpo $(DEPDIR)/libecore_con_la-ecore_con.Plo | ||
616 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
617 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con.c' object='libecore_con_la-ecore_con.lo' libtool=yes @AMDEPBACKSLASH@ | ||
618 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
619 | @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 | ||
620 | |||
621 | libecore_con_la-ecore_con_ssl.lo: ecore_con_ssl.c | ||
622 | @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 | ||
623 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_ssl.Tpo $(DEPDIR)/libecore_con_la-ecore_con_ssl.Plo | ||
624 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
625 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_ssl.c' object='libecore_con_la-ecore_con_ssl.lo' libtool=yes @AMDEPBACKSLASH@ | ||
626 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
627 | @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 | ||
628 | |||
629 | libecore_con_la-ecore_con_url.lo: ecore_con_url.c | ||
630 | @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 | ||
631 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_url.Tpo $(DEPDIR)/libecore_con_la-ecore_con_url.Plo | ||
632 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
633 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_url.c' object='libecore_con_la-ecore_con_url.lo' libtool=yes @AMDEPBACKSLASH@ | ||
634 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
635 | @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 | ||
636 | |||
637 | libecore_con_la-ecore_con_alloc.lo: ecore_con_alloc.c | ||
638 | @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 | ||
639 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_alloc.Tpo $(DEPDIR)/libecore_con_la-ecore_con_alloc.Plo | ||
640 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
641 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_alloc.c' object='libecore_con_la-ecore_con_alloc.lo' libtool=yes @AMDEPBACKSLASH@ | ||
642 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
643 | @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 | ||
644 | |||
645 | libecore_con_la-ecore_con_local_win32.lo: ecore_con_local_win32.c | ||
646 | @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 | ||
647 | @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 | ||
648 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
649 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_local_win32.c' object='libecore_con_la-ecore_con_local_win32.lo' libtool=yes @AMDEPBACKSLASH@ | ||
650 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
651 | @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 | ||
652 | |||
653 | libecore_con_la-ecore_con_local.lo: ecore_con_local.c | ||
654 | @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 | ||
655 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_local.Tpo $(DEPDIR)/libecore_con_la-ecore_con_local.Plo | ||
656 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
657 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_local.c' object='libecore_con_la-ecore_con_local.lo' libtool=yes @AMDEPBACKSLASH@ | ||
658 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
659 | @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 | ||
660 | |||
661 | libecore_con_la-ecore_con_ares.lo: ecore_con_ares.c | ||
662 | @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 | ||
663 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_ares.Tpo $(DEPDIR)/libecore_con_la-ecore_con_ares.Plo | ||
664 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
665 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_ares.c' object='libecore_con_la-ecore_con_ares.lo' libtool=yes @AMDEPBACKSLASH@ | ||
666 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
667 | @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 | ||
668 | |||
669 | libecore_con_la-ecore_con_info.lo: ecore_con_info.c | ||
670 | @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 | ||
671 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_info.Tpo $(DEPDIR)/libecore_con_la-ecore_con_info.Plo | ||
672 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
673 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_info.c' object='libecore_con_la-ecore_con_info.lo' libtool=yes @AMDEPBACKSLASH@ | ||
674 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
675 | @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 | ||
676 | |||
677 | mostlyclean-libtool: | ||
678 | -rm -f *.lo | ||
679 | |||
680 | clean-libtool: | ||
681 | -rm -rf .libs _libs | ||
682 | install-includesHEADERS: $(includes_HEADERS) | ||
683 | @$(NORMAL_INSTALL) | ||
684 | test -z "$(includesdir)" || $(MKDIR_P) "$(DESTDIR)$(includesdir)" | ||
685 | @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \ | ||
686 | for p in $$list; do \ | ||
687 | if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ | ||
688 | echo "$$d$$p"; \ | ||
689 | done | $(am__base_list) | \ | ||
690 | while read files; do \ | ||
691 | echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includesdir)'"; \ | ||
692 | $(INSTALL_HEADER) $$files "$(DESTDIR)$(includesdir)" || exit $$?; \ | ||
693 | done | ||
694 | |||
695 | uninstall-includesHEADERS: | ||
696 | @$(NORMAL_UNINSTALL) | ||
697 | @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \ | ||
698 | files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ | ||
699 | test -n "$$files" || exit 0; \ | ||
700 | echo " ( cd '$(DESTDIR)$(includesdir)' && rm -f" $$files ")"; \ | ||
701 | cd "$(DESTDIR)$(includesdir)" && rm -f $$files | ||
702 | |||
703 | ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) | ||
704 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
705 | unique=`for i in $$list; do \ | ||
706 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
707 | done | \ | ||
708 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
709 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
710 | mkid -fID $$unique | ||
711 | tags: TAGS | ||
712 | |||
713 | TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
714 | $(TAGS_FILES) $(LISP) | ||
715 | set x; \ | ||
716 | here=`pwd`; \ | ||
717 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
718 | unique=`for i in $$list; do \ | ||
719 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
720 | done | \ | ||
721 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
722 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
723 | shift; \ | ||
724 | if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ | ||
725 | test -n "$$unique" || unique=$$empty_fix; \ | ||
726 | if test $$# -gt 0; then \ | ||
727 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ | ||
728 | "$$@" $$unique; \ | ||
729 | else \ | ||
730 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ | ||
731 | $$unique; \ | ||
732 | fi; \ | ||
733 | fi | ||
734 | ctags: CTAGS | ||
735 | CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
736 | $(TAGS_FILES) $(LISP) | ||
737 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
738 | unique=`for i in $$list; do \ | ||
739 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
740 | done | \ | ||
741 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
742 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
743 | test -z "$(CTAGS_ARGS)$$unique" \ | ||
744 | || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ | ||
745 | $$unique | ||
746 | |||
747 | GTAGS: | ||
748 | here=`$(am__cd) $(top_builddir) && pwd` \ | ||
749 | && $(am__cd) $(top_srcdir) \ | ||
750 | && gtags -i $(GTAGS_ARGS) "$$here" | ||
751 | |||
752 | distclean-tags: | ||
753 | -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags | ||
754 | |||
755 | distdir: $(DISTFILES) | ||
756 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
757 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
758 | list='$(DISTFILES)'; \ | ||
759 | dist_files=`for file in $$list; do echo $$file; done | \ | ||
760 | sed -e "s|^$$srcdirstrip/||;t" \ | ||
761 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ | ||
762 | case $$dist_files in \ | ||
763 | */*) $(MKDIR_P) `echo "$$dist_files" | \ | ||
764 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ | ||
765 | sort -u` ;; \ | ||
766 | esac; \ | ||
767 | for file in $$dist_files; do \ | ||
768 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ | ||
769 | if test -d $$d/$$file; then \ | ||
770 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ | ||
771 | if test -d "$(distdir)/$$file"; then \ | ||
772 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | ||
773 | fi; \ | ||
774 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ | ||
775 | cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ | ||
776 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | ||
777 | fi; \ | ||
778 | cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ | ||
779 | else \ | ||
780 | test -f "$(distdir)/$$file" \ | ||
781 | || cp -p $$d/$$file "$(distdir)/$$file" \ | ||
782 | || exit 1; \ | ||
783 | fi; \ | ||
784 | done | ||
785 | check-am: all-am | ||
786 | check: check-am | ||
787 | all-am: Makefile $(LTLIBRARIES) $(HEADERS) | ||
788 | installdirs: | ||
789 | for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"; do \ | ||
790 | test -z "$$dir" || $(MKDIR_P) "$$dir"; \ | ||
791 | done | ||
792 | install: install-am | ||
793 | install-exec: install-exec-am | ||
794 | install-data: install-data-am | ||
795 | uninstall: uninstall-am | ||
796 | |||
797 | install-am: all-am | ||
798 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | ||
799 | |||
800 | installcheck: installcheck-am | ||
801 | install-strip: | ||
802 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ | ||
803 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ | ||
804 | `test -z '$(STRIP)' || \ | ||
805 | echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install | ||
806 | mostlyclean-generic: | ||
807 | |||
808 | clean-generic: | ||
809 | |||
810 | distclean-generic: | ||
811 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) | ||
812 | -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) | ||
813 | |||
814 | maintainer-clean-generic: | ||
815 | @echo "This command is intended for maintainers to use" | ||
816 | @echo "it deletes files that may require special tools to rebuild." | ||
817 | -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) | ||
818 | clean: clean-am | ||
819 | |||
820 | clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ | ||
821 | mostlyclean-am | ||
822 | |||
823 | distclean: distclean-am | ||
824 | -rm -rf ./$(DEPDIR) | ||
825 | -rm -f Makefile | ||
826 | distclean-am: clean-am distclean-compile distclean-generic \ | ||
827 | distclean-tags | ||
828 | |||
829 | dvi: dvi-am | ||
830 | |||
831 | dvi-am: | ||
832 | |||
833 | html: html-am | ||
834 | |||
835 | html-am: | ||
836 | |||
837 | info: info-am | ||
838 | |||
839 | info-am: | ||
840 | |||
841 | install-data-am: install-includesHEADERS | ||
842 | |||
843 | install-dvi: install-dvi-am | ||
844 | |||
845 | install-dvi-am: | ||
846 | |||
847 | install-exec-am: install-libLTLIBRARIES | ||
848 | |||
849 | install-html: install-html-am | ||
850 | |||
851 | install-html-am: | ||
852 | |||
853 | install-info: install-info-am | ||
854 | |||
855 | install-info-am: | ||
856 | |||
857 | install-man: | ||
858 | |||
859 | install-pdf: install-pdf-am | ||
860 | |||
861 | install-pdf-am: | ||
862 | |||
863 | install-ps: install-ps-am | ||
864 | |||
865 | install-ps-am: | ||
866 | |||
867 | installcheck-am: | ||
868 | |||
869 | maintainer-clean: maintainer-clean-am | ||
870 | -rm -rf ./$(DEPDIR) | ||
871 | -rm -f Makefile | ||
872 | maintainer-clean-am: distclean-am maintainer-clean-generic | ||
873 | |||
874 | mostlyclean: mostlyclean-am | ||
875 | |||
876 | mostlyclean-am: mostlyclean-compile mostlyclean-generic \ | ||
877 | mostlyclean-libtool | ||
878 | |||
879 | pdf: pdf-am | ||
880 | |||
881 | pdf-am: | ||
882 | |||
883 | ps: ps-am | ||
884 | |||
885 | ps-am: | ||
886 | |||
887 | uninstall-am: uninstall-includesHEADERS uninstall-libLTLIBRARIES | ||
888 | |||
889 | .MAKE: install-am install-strip | ||
890 | |||
891 | .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ | ||
892 | clean-libLTLIBRARIES clean-libtool ctags distclean \ | ||
893 | distclean-compile distclean-generic distclean-libtool \ | ||
894 | distclean-tags distdir dvi dvi-am html html-am info info-am \ | ||
895 | install install-am install-data install-data-am install-dvi \ | ||
896 | install-dvi-am install-exec install-exec-am install-html \ | ||
897 | install-html-am install-includesHEADERS install-info \ | ||
898 | install-info-am install-libLTLIBRARIES install-man install-pdf \ | ||
899 | install-pdf-am install-ps install-ps-am install-strip \ | ||
900 | installcheck installcheck-am installdirs maintainer-clean \ | ||
901 | maintainer-clean-generic mostlyclean mostlyclean-compile \ | ||
902 | mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ | ||
903 | tags uninstall uninstall-am uninstall-includesHEADERS \ | ||
904 | uninstall-libLTLIBRARIES | ||
905 | |||
906 | |||
907 | # Tell versions [3.59,3.63) of GNU make to not export all variables. | ||
908 | # Otherwise a system limit (for SysV at least) may be exceeded. | ||
909 | .NOEXPORT: | ||
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con.c b/libraries/ecore/src/lib/ecore_con/ecore_con.c new file mode 100644 index 0000000..7bd0358 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con.c | |||
@@ -0,0 +1,2600 @@ | |||
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 | |||
46 | static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl); | ||
47 | static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl); | ||
48 | |||
49 | static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr); | ||
50 | static void _ecore_con_server_timer_update(Ecore_Con_Server *svr); | ||
51 | |||
52 | static void _ecore_con_cb_tcp_connect(void *data, | ||
53 | Ecore_Con_Info *info); | ||
54 | static void _ecore_con_cb_udp_connect(void *data, | ||
55 | Ecore_Con_Info *info); | ||
56 | static void _ecore_con_cb_tcp_listen(void *data, | ||
57 | Ecore_Con_Info *info); | ||
58 | static void _ecore_con_cb_udp_listen(void *data, | ||
59 | Ecore_Con_Info *info); | ||
60 | |||
61 | static void _ecore_con_server_free(Ecore_Con_Server *svr); | ||
62 | static void _ecore_con_client_free(Ecore_Con_Client *cl); | ||
63 | |||
64 | static void _ecore_con_cl_read(Ecore_Con_Server *svr); | ||
65 | static Eina_Bool _ecore_con_svr_tcp_handler(void *data, | ||
66 | Ecore_Fd_Handler *fd_handler); | ||
67 | static Eina_Bool _ecore_con_cl_handler(void *data, | ||
68 | Ecore_Fd_Handler *fd_handler); | ||
69 | static Eina_Bool _ecore_con_cl_udp_handler(void *data, | ||
70 | Ecore_Fd_Handler *fd_handler); | ||
71 | static Eina_Bool _ecore_con_svr_udp_handler(void *data, | ||
72 | Ecore_Fd_Handler *fd_handler); | ||
73 | |||
74 | static void _ecore_con_svr_cl_read(Ecore_Con_Client *cl); | ||
75 | static Eina_Bool _ecore_con_svr_cl_handler(void *data, | ||
76 | Ecore_Fd_Handler *fd_handler); | ||
77 | |||
78 | static void _ecore_con_server_flush(Ecore_Con_Server *svr); | ||
79 | static void _ecore_con_client_flush(Ecore_Con_Client *cl); | ||
80 | |||
81 | static void _ecore_con_event_client_add_free(Ecore_Con_Server *svr, | ||
82 | void *ev); | ||
83 | static void _ecore_con_event_client_del_free(Ecore_Con_Server *svr, | ||
84 | void *ev); | ||
85 | static void _ecore_con_event_client_data_free(Ecore_Con_Server *svr, | ||
86 | void *ev); | ||
87 | static void _ecore_con_event_server_add_free(void *data, | ||
88 | void *ev); | ||
89 | static void _ecore_con_event_server_del_free(void *data, | ||
90 | void *ev); | ||
91 | static void _ecore_con_event_server_data_free(void *data, | ||
92 | void *ev); | ||
93 | static void _ecore_con_event_server_error_free(void *data, | ||
94 | Ecore_Con_Event_Server_Error *e); | ||
95 | static void _ecore_con_event_client_error_free(Ecore_Con_Server *svr, | ||
96 | Ecore_Con_Event_Client_Error *e); | ||
97 | static void _ecore_con_event_server_write_free(void *data, | ||
98 | Ecore_Con_Event_Server_Write *e); | ||
99 | static void _ecore_con_event_client_write_free(Ecore_Con_Server *svr, | ||
100 | Ecore_Con_Event_Client_Write *e); | ||
101 | |||
102 | static void _ecore_con_lookup_done(void *data, | ||
103 | Ecore_Con_Info *infos); | ||
104 | |||
105 | static const char * _ecore_con_pretty_ip(struct sockaddr *client_addr); | ||
106 | |||
107 | EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0; | ||
108 | EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0; | ||
109 | EAPI int ECORE_CON_EVENT_SERVER_ADD = 0; | ||
110 | EAPI int ECORE_CON_EVENT_SERVER_DEL = 0; | ||
111 | EAPI int ECORE_CON_EVENT_CLIENT_DATA = 0; | ||
112 | EAPI int ECORE_CON_EVENT_SERVER_DATA = 0; | ||
113 | EAPI int ECORE_CON_EVENT_CLIENT_WRITE = 0; | ||
114 | EAPI int ECORE_CON_EVENT_SERVER_WRITE = 0; | ||
115 | EAPI int ECORE_CON_EVENT_CLIENT_ERROR = 0; | ||
116 | EAPI int ECORE_CON_EVENT_SERVER_ERROR = 0; | ||
117 | |||
118 | static Eina_List *servers = NULL; | ||
119 | static int _ecore_con_init_count = 0; | ||
120 | static int _ecore_con_event_count = 0; | ||
121 | int _ecore_con_log_dom = -1; | ||
122 | |||
123 | EAPI int | ||
124 | ecore_con_init(void) | ||
125 | { | ||
126 | if (++_ecore_con_init_count != 1) | ||
127 | return _ecore_con_init_count; | ||
128 | |||
129 | #ifdef HAVE_EVIL | ||
130 | if (!evil_init()) | ||
131 | return --_ecore_con_init_count; | ||
132 | |||
133 | #endif | ||
134 | |||
135 | if (!ecore_init()) | ||
136 | return --_ecore_con_init_count; | ||
137 | |||
138 | _ecore_con_log_dom = eina_log_domain_register | ||
139 | ("ecore_con", ECORE_CON_DEFAULT_LOG_COLOR); | ||
140 | if (_ecore_con_log_dom < 0) | ||
141 | { | ||
142 | EINA_LOG_ERR("Impossible to create a log domain for Ecore Con."); | ||
143 | ecore_shutdown(); | ||
144 | return --_ecore_con_init_count; | ||
145 | } | ||
146 | |||
147 | ecore_con_mempool_init(); | ||
148 | |||
149 | ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new(); | ||
150 | ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new(); | ||
151 | ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new(); | ||
152 | ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new(); | ||
153 | ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new(); | ||
154 | ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new(); | ||
155 | ECORE_CON_EVENT_CLIENT_WRITE = ecore_event_type_new(); | ||
156 | ECORE_CON_EVENT_SERVER_WRITE = ecore_event_type_new(); | ||
157 | ECORE_CON_EVENT_CLIENT_ERROR = ecore_event_type_new(); | ||
158 | ECORE_CON_EVENT_SERVER_ERROR = ecore_event_type_new(); | ||
159 | |||
160 | |||
161 | eina_magic_string_set(ECORE_MAGIC_CON_SERVER, "Ecore_Con_Server"); | ||
162 | eina_magic_string_set(ECORE_MAGIC_CON_CLIENT, "Ecore_Con_Server"); | ||
163 | eina_magic_string_set(ECORE_MAGIC_CON_URL, "Ecore_Con_Url"); | ||
164 | |||
165 | /* TODO Remember return value, if it fails, use gethostbyname() */ | ||
166 | ecore_con_ssl_init(); | ||
167 | ecore_con_info_init(); | ||
168 | |||
169 | return _ecore_con_init_count; | ||
170 | } | ||
171 | |||
172 | EAPI int | ||
173 | ecore_con_shutdown(void) | ||
174 | { | ||
175 | Eina_List *l, *l2; | ||
176 | Ecore_Con_Server *svr; | ||
177 | |||
178 | if (--_ecore_con_init_count != 0) | ||
179 | return _ecore_con_init_count; | ||
180 | |||
181 | EINA_LIST_FOREACH_SAFE(servers, l, l2, svr) | ||
182 | { | ||
183 | Ecore_Con_Event_Server_Add *ev; | ||
184 | |||
185 | svr->delete_me = svr->dead = EINA_TRUE; | ||
186 | /* some pointer hacks here to prevent double frees if people are being stupid */ | ||
187 | EINA_LIST_FREE(svr->event_count, ev) | ||
188 | ev->server = NULL; | ||
189 | _ecore_con_server_free(svr); | ||
190 | } | ||
191 | |||
192 | if (!_ecore_con_event_count) ecore_con_mempool_shutdown(); | ||
193 | |||
194 | ecore_con_info_shutdown(); | ||
195 | ecore_con_ssl_shutdown(); | ||
196 | eina_log_domain_unregister(_ecore_con_log_dom); | ||
197 | _ecore_con_log_dom = -1; | ||
198 | ecore_shutdown(); | ||
199 | #ifdef HAVE_EVIL | ||
200 | evil_shutdown(); | ||
201 | #endif | ||
202 | |||
203 | return _ecore_con_init_count; | ||
204 | } | ||
205 | |||
206 | EAPI Eina_Bool | ||
207 | ecore_con_lookup(const char *name, | ||
208 | Ecore_Con_Dns_Cb done_cb, | ||
209 | const void *data) | ||
210 | { | ||
211 | Ecore_Con_Server *svr; | ||
212 | Ecore_Con_Lookup *lk; | ||
213 | struct addrinfo hints; | ||
214 | |||
215 | if (!name || !done_cb) | ||
216 | return EINA_FALSE; | ||
217 | |||
218 | svr = calloc(1, sizeof(Ecore_Con_Server)); | ||
219 | if (!svr) | ||
220 | return EINA_FALSE; | ||
221 | |||
222 | lk = malloc(sizeof (Ecore_Con_Lookup)); | ||
223 | if (!lk) | ||
224 | { | ||
225 | free(svr); | ||
226 | return EINA_FALSE; | ||
227 | } | ||
228 | |||
229 | lk->done_cb = done_cb; | ||
230 | lk->data = data; | ||
231 | |||
232 | svr->name = strdup(name); | ||
233 | if (!svr->name) | ||
234 | goto on_error; | ||
235 | |||
236 | svr->type = ECORE_CON_REMOTE_TCP; | ||
237 | svr->port = 1025; | ||
238 | svr->data = lk; | ||
239 | svr->created = EINA_TRUE; | ||
240 | svr->reject_excess_clients = EINA_FALSE; | ||
241 | svr->client_limit = -1; | ||
242 | svr->clients = NULL; | ||
243 | svr->ppid = getpid(); | ||
244 | |||
245 | memset(&hints, 0, sizeof(struct addrinfo)); | ||
246 | hints.ai_family = AF_UNSPEC; | ||
247 | hints.ai_socktype = SOCK_STREAM; | ||
248 | hints.ai_flags = AI_CANONNAME; | ||
249 | hints.ai_protocol = IPPROTO_TCP; | ||
250 | hints.ai_canonname = NULL; | ||
251 | hints.ai_next = NULL; | ||
252 | hints.ai_addr = NULL; | ||
253 | |||
254 | if (ecore_con_info_get(svr, _ecore_con_lookup_done, svr, | ||
255 | &hints)) | ||
256 | return EINA_TRUE; | ||
257 | |||
258 | free(svr->name); | ||
259 | on_error: | ||
260 | free(lk); | ||
261 | free(svr); | ||
262 | return EINA_FALSE; | ||
263 | } | ||
264 | |||
265 | /** | ||
266 | * @addtogroup Ecore_Con_Server_Group Ecore Connection Server Functions | ||
267 | * | ||
268 | * Functions that operate on Ecore server objects. | ||
269 | * | ||
270 | * @{ | ||
271 | */ | ||
272 | |||
273 | /** | ||
274 | * @example ecore_con_server_example.c | ||
275 | * Shows how to write a simple server using the Ecore_Con library. | ||
276 | */ | ||
277 | |||
278 | EAPI Ecore_Con_Server * | ||
279 | ecore_con_server_add(Ecore_Con_Type compl_type, | ||
280 | const char *name, | ||
281 | int port, | ||
282 | const void *data) | ||
283 | { | ||
284 | Ecore_Con_Server *svr; | ||
285 | Ecore_Con_Type type; | ||
286 | |||
287 | if (port < 0 || !name) | ||
288 | return NULL; /* local user socket: FILE: ~/.ecore/[name]/[port] */ | ||
289 | |||
290 | /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */ | ||
291 | /* remote system socket: TCP/IP: [name]:[port] */ | ||
292 | svr = calloc(1, sizeof(Ecore_Con_Server)); | ||
293 | if (!svr) | ||
294 | return NULL; | ||
295 | |||
296 | svr->name = strdup(name); | ||
297 | if (!svr->name) | ||
298 | goto error; | ||
299 | |||
300 | svr->type = compl_type; | ||
301 | svr->port = port; | ||
302 | svr->data = (void *)data; | ||
303 | svr->created = EINA_TRUE; | ||
304 | if (compl_type & ECORE_CON_LOAD_CERT) | ||
305 | svr->use_cert = EINA_TRUE; | ||
306 | svr->reject_excess_clients = EINA_FALSE; | ||
307 | svr->client_limit = -1; | ||
308 | svr->clients = NULL; | ||
309 | svr->ppid = getpid(); | ||
310 | if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL)) | ||
311 | goto error; | ||
312 | |||
313 | type = compl_type & ECORE_CON_TYPE; | ||
314 | |||
315 | if ((type == ECORE_CON_LOCAL_USER) || | ||
316 | (type == ECORE_CON_LOCAL_SYSTEM) || | ||
317 | (type == ECORE_CON_LOCAL_ABSTRACT)) | ||
318 | /* Local */ | ||
319 | #ifdef _WIN32 | ||
320 | if (!ecore_con_local_listen(svr)) | ||
321 | goto error; | ||
322 | #else | ||
323 | if (!ecore_con_local_listen(svr, _ecore_con_svr_tcp_handler, svr)) | ||
324 | goto error; | ||
325 | #endif | ||
326 | |||
327 | if ((type == ECORE_CON_REMOTE_TCP) || | ||
328 | (type == ECORE_CON_REMOTE_NODELAY)) | ||
329 | { | ||
330 | /* TCP */ | ||
331 | if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen, | ||
332 | svr)) | ||
333 | goto error; | ||
334 | } | ||
335 | else if ((type == ECORE_CON_REMOTE_MCAST) || | ||
336 | (type == ECORE_CON_REMOTE_UDP)) | ||
337 | /* UDP and MCAST */ | ||
338 | if (!ecore_con_info_udp_listen(svr, _ecore_con_cb_udp_listen, | ||
339 | svr)) | ||
340 | goto error; | ||
341 | |||
342 | servers = eina_list_append(servers, svr); | ||
343 | ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER); | ||
344 | |||
345 | return svr; | ||
346 | |||
347 | error: | ||
348 | if (svr->name) | ||
349 | free(svr->name); | ||
350 | |||
351 | if (svr->path) | ||
352 | free(svr->path); | ||
353 | |||
354 | |||
355 | if (svr->fd_handler) | ||
356 | ecore_main_fd_handler_del(svr->fd_handler); | ||
357 | |||
358 | if (svr->fd > 0) | ||
359 | close(svr->fd); | ||
360 | |||
361 | if (svr->buf) | ||
362 | eina_binbuf_free(svr->buf); | ||
363 | |||
364 | if (svr->ip) | ||
365 | eina_stringshare_del(svr->ip); | ||
366 | |||
367 | ecore_con_ssl_server_shutdown(svr); | ||
368 | free(svr); | ||
369 | return NULL; | ||
370 | } | ||
371 | |||
372 | EAPI Ecore_Con_Server * | ||
373 | ecore_con_server_connect(Ecore_Con_Type compl_type, | ||
374 | const char *name, | ||
375 | int port, | ||
376 | const void *data) | ||
377 | { | ||
378 | Ecore_Con_Server *svr; | ||
379 | Ecore_Con_Type type; | ||
380 | |||
381 | if ((!name) || (!name[0])) | ||
382 | return NULL; | ||
383 | /* local user socket: FILE: ~/.ecore/[name]/[port] */ | ||
384 | /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */ | ||
385 | /* remote system socket: TCP/IP: [name]:[port] */ | ||
386 | svr = calloc(1, sizeof(Ecore_Con_Server)); | ||
387 | if (!svr) | ||
388 | return NULL; | ||
389 | |||
390 | svr->name = strdup(name); | ||
391 | if (!svr->name) | ||
392 | goto error; | ||
393 | |||
394 | svr->type = compl_type; | ||
395 | svr->port = port; | ||
396 | svr->data = (void *)data; | ||
397 | svr->created = EINA_FALSE; | ||
398 | svr->use_cert = (compl_type & ECORE_CON_LOAD_CERT); | ||
399 | svr->reject_excess_clients = EINA_FALSE; | ||
400 | svr->clients = NULL; | ||
401 | svr->client_limit = -1; | ||
402 | if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL)) | ||
403 | goto error; | ||
404 | |||
405 | type = compl_type & ECORE_CON_TYPE; | ||
406 | |||
407 | if (((type == ECORE_CON_REMOTE_TCP) || | ||
408 | (type == ECORE_CON_REMOTE_NODELAY) || | ||
409 | (type == ECORE_CON_REMOTE_UDP) || | ||
410 | (type == ECORE_CON_REMOTE_BROADCAST)) && | ||
411 | (port < 0)) | ||
412 | goto error; | ||
413 | |||
414 | if ((type == ECORE_CON_LOCAL_USER) || | ||
415 | (type == ECORE_CON_LOCAL_SYSTEM) || | ||
416 | (type == ECORE_CON_LOCAL_ABSTRACT)) | ||
417 | /* Local */ | ||
418 | #ifdef _WIN32 | ||
419 | if (!ecore_con_local_connect(svr, _ecore_con_cl_handler)) | ||
420 | goto error; | ||
421 | #else | ||
422 | if (!ecore_con_local_connect(svr, _ecore_con_cl_handler, svr)) | ||
423 | goto error; | ||
424 | #endif | ||
425 | |||
426 | if ((type == ECORE_CON_REMOTE_TCP) || | ||
427 | (type == ECORE_CON_REMOTE_NODELAY)) | ||
428 | { | ||
429 | /* TCP */ | ||
430 | if (!ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect, | ||
431 | svr)) | ||
432 | goto error; | ||
433 | } | ||
434 | else if ((type == ECORE_CON_REMOTE_UDP) || | ||
435 | (type == ECORE_CON_REMOTE_BROADCAST)) | ||
436 | /* UDP and MCAST */ | ||
437 | if (!ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect, | ||
438 | svr)) | ||
439 | goto error; | ||
440 | |||
441 | servers = eina_list_append(servers, svr); | ||
442 | ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER); | ||
443 | |||
444 | return svr; | ||
445 | |||
446 | error: | ||
447 | if (svr->name) | ||
448 | free(svr->name); | ||
449 | |||
450 | if (svr->path) | ||
451 | free(svr->path); | ||
452 | |||
453 | if (svr->fd_handler) | ||
454 | ecore_main_fd_handler_del(svr->fd_handler); | ||
455 | |||
456 | if (svr->fd > 0) | ||
457 | close(svr->fd); | ||
458 | |||
459 | ecore_con_ssl_server_shutdown(svr); | ||
460 | free(svr); | ||
461 | return NULL; | ||
462 | } | ||
463 | |||
464 | EAPI void | ||
465 | ecore_con_server_timeout_set(Ecore_Con_Server *svr, | ||
466 | double timeout) | ||
467 | { | ||
468 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
469 | { | ||
470 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_timeout_set"); | ||
471 | return; | ||
472 | } | ||
473 | |||
474 | if (svr->created) | ||
475 | svr->client_disconnect_time = timeout; | ||
476 | else | ||
477 | svr->disconnect_time = timeout; | ||
478 | } | ||
479 | |||
480 | EAPI double | ||
481 | ecore_con_server_timeout_get(Ecore_Con_Server *svr) | ||
482 | { | ||
483 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
484 | { | ||
485 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_timeout_get"); | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | return svr->created ? svr->client_disconnect_time : svr->disconnect_time; | ||
490 | } | ||
491 | |||
492 | EAPI void * | ||
493 | ecore_con_server_del(Ecore_Con_Server *svr) | ||
494 | { | ||
495 | void *data; | ||
496 | |||
497 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
498 | { | ||
499 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del"); | ||
500 | return NULL; | ||
501 | } | ||
502 | |||
503 | if (svr->delete_me) | ||
504 | return NULL; | ||
505 | |||
506 | data = svr->data; | ||
507 | svr->delete_me = EINA_TRUE; | ||
508 | if (svr->event_count) | ||
509 | { | ||
510 | if (svr->fd_handler) | ||
511 | { | ||
512 | ecore_main_fd_handler_del(svr->fd_handler); | ||
513 | svr->fd_handler = NULL; | ||
514 | } | ||
515 | } | ||
516 | else | ||
517 | _ecore_con_server_free(svr); | ||
518 | |||
519 | return data; | ||
520 | } | ||
521 | |||
522 | EAPI void * | ||
523 | ecore_con_server_data_get(Ecore_Con_Server *svr) | ||
524 | { | ||
525 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
526 | { | ||
527 | ECORE_MAGIC_FAIL(svr, | ||
528 | ECORE_MAGIC_CON_SERVER, | ||
529 | "ecore_con_server_data_get"); | ||
530 | return NULL; | ||
531 | } | ||
532 | |||
533 | return svr->data; | ||
534 | } | ||
535 | |||
536 | EAPI void * | ||
537 | ecore_con_server_data_set(Ecore_Con_Server *svr, | ||
538 | void *data) | ||
539 | { | ||
540 | void *ret = NULL; | ||
541 | |||
542 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
543 | { | ||
544 | ECORE_MAGIC_FAIL(svr, | ||
545 | ECORE_MAGIC_CON_SERVER, | ||
546 | "ecore_con_server_data_get"); | ||
547 | return NULL; | ||
548 | } | ||
549 | |||
550 | ret = svr->data; | ||
551 | svr->data = data; | ||
552 | return ret; | ||
553 | } | ||
554 | |||
555 | EAPI Eina_Bool | ||
556 | ecore_con_server_connected_get(Ecore_Con_Server *svr) | ||
557 | { | ||
558 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
559 | { | ||
560 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, | ||
561 | "ecore_con_server_connected_get"); | ||
562 | return EINA_FALSE; | ||
563 | } | ||
564 | |||
565 | if (svr->connecting) | ||
566 | return EINA_FALSE; | ||
567 | |||
568 | return EINA_TRUE; | ||
569 | } | ||
570 | |||
571 | EAPI const Eina_List * | ||
572 | ecore_con_server_clients_get(Ecore_Con_Server *svr) | ||
573 | { | ||
574 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
575 | { | ||
576 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, | ||
577 | "ecore_con_server_clients_get"); | ||
578 | return NULL; | ||
579 | } | ||
580 | |||
581 | return svr->clients; | ||
582 | } | ||
583 | |||
584 | EAPI const char * | ||
585 | ecore_con_server_name_get(Ecore_Con_Server *svr) | ||
586 | { | ||
587 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
588 | { | ||
589 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, | ||
590 | "ecore_con_server_name_get"); | ||
591 | return NULL; | ||
592 | } | ||
593 | |||
594 | return svr->name; | ||
595 | } | ||
596 | |||
597 | EAPI int | ||
598 | ecore_con_server_port_get(Ecore_Con_Server *svr) | ||
599 | { | ||
600 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
601 | { | ||
602 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, | ||
603 | "ecore_con_server_port_get"); | ||
604 | return -1; | ||
605 | } | ||
606 | return svr->port; | ||
607 | } | ||
608 | |||
609 | EAPI int | ||
610 | ecore_con_server_send(Ecore_Con_Server *svr, | ||
611 | const void *data, | ||
612 | int size) | ||
613 | { | ||
614 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
615 | { | ||
616 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_send"); | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | EINA_SAFETY_ON_TRUE_RETURN_VAL(svr->dead, 0); | ||
621 | |||
622 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); | ||
623 | |||
624 | EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0); | ||
625 | |||
626 | if (svr->fd_handler) | ||
627 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); | ||
628 | |||
629 | if (!svr->buf) | ||
630 | { | ||
631 | svr->buf = eina_binbuf_new(); | ||
632 | EINA_SAFETY_ON_NULL_RETURN_VAL(svr->buf, 0); | ||
633 | } | ||
634 | eina_binbuf_append_length(svr->buf, data, size); | ||
635 | |||
636 | return size; | ||
637 | } | ||
638 | |||
639 | EAPI void | ||
640 | ecore_con_server_client_limit_set(Ecore_Con_Server *svr, | ||
641 | int client_limit, | ||
642 | char reject_excess_clients) | ||
643 | { | ||
644 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
645 | { | ||
646 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, | ||
647 | "ecore_con_server_client_limit_set"); | ||
648 | return; | ||
649 | } | ||
650 | |||
651 | svr->client_limit = client_limit; | ||
652 | svr->reject_excess_clients = reject_excess_clients; | ||
653 | } | ||
654 | |||
655 | EAPI const char * | ||
656 | ecore_con_server_ip_get(Ecore_Con_Server *svr) | ||
657 | { | ||
658 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
659 | { | ||
660 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_ip_get"); | ||
661 | return NULL; | ||
662 | } | ||
663 | |||
664 | return svr->ip; | ||
665 | } | ||
666 | |||
667 | EAPI double | ||
668 | ecore_con_server_uptime_get(Ecore_Con_Server *svr) | ||
669 | { | ||
670 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
671 | { | ||
672 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_uptime_get"); | ||
673 | return -1; | ||
674 | } | ||
675 | |||
676 | return ecore_time_get() - svr->start_time; | ||
677 | } | ||
678 | |||
679 | EAPI void | ||
680 | ecore_con_server_flush(Ecore_Con_Server *svr) | ||
681 | { | ||
682 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
683 | { | ||
684 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_flush"); | ||
685 | return; | ||
686 | } | ||
687 | |||
688 | _ecore_con_server_flush(svr); | ||
689 | } | ||
690 | |||
691 | /** | ||
692 | * @} | ||
693 | */ | ||
694 | |||
695 | /** | ||
696 | * @addtogroup Ecore_Con_Client_Group Ecore Connection Client Functions | ||
697 | * | ||
698 | * Functions that operate on Ecore connection client objects. | ||
699 | * | ||
700 | * @{ | ||
701 | */ | ||
702 | |||
703 | /** | ||
704 | * @example ecore_con_client_example.c | ||
705 | * Shows how to write a simple client that connects to the example server. | ||
706 | */ | ||
707 | |||
708 | EAPI int | ||
709 | ecore_con_client_send(Ecore_Con_Client *cl, | ||
710 | const void *data, | ||
711 | int size) | ||
712 | { | ||
713 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
714 | { | ||
715 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_send"); | ||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | EINA_SAFETY_ON_TRUE_RETURN_VAL(cl->dead, 0); | ||
720 | |||
721 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); | ||
722 | |||
723 | EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0); | ||
724 | |||
725 | if (cl->fd_handler) | ||
726 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); | ||
727 | |||
728 | if (cl->host_server && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP)) | ||
729 | sendto(cl->host_server->fd, data, size, 0, (struct sockaddr *)cl->client_addr, | ||
730 | cl->client_addr_len); | ||
731 | else if (!cl->buf) | ||
732 | { | ||
733 | cl->buf = eina_binbuf_new(); | ||
734 | EINA_SAFETY_ON_NULL_RETURN_VAL(cl->buf, 0); | ||
735 | } | ||
736 | eina_binbuf_append_length(cl->buf, data, size); | ||
737 | |||
738 | return size; | ||
739 | } | ||
740 | |||
741 | EAPI Ecore_Con_Server * | ||
742 | ecore_con_client_server_get(Ecore_Con_Client *cl) | ||
743 | { | ||
744 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
745 | { | ||
746 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, | ||
747 | "ecore_con_client_server_get"); | ||
748 | return NULL; | ||
749 | } | ||
750 | |||
751 | return cl->host_server; | ||
752 | } | ||
753 | |||
754 | EAPI Eina_Bool | ||
755 | ecore_con_client_connected_get(Ecore_Con_Client *cl) | ||
756 | { | ||
757 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
758 | { | ||
759 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, | ||
760 | "ecore_con_client_connected_get"); | ||
761 | return EINA_FALSE; | ||
762 | } | ||
763 | |||
764 | return !cl->dead; | ||
765 | } | ||
766 | |||
767 | EAPI void | ||
768 | ecore_con_client_timeout_set(Ecore_Con_Client *cl, | ||
769 | double timeout) | ||
770 | { | ||
771 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
772 | { | ||
773 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, | ||
774 | "ecore_con_client_timeout_set"); | ||
775 | return; | ||
776 | } | ||
777 | |||
778 | cl->disconnect_time = timeout; | ||
779 | |||
780 | _ecore_con_cl_timer_update(cl); | ||
781 | } | ||
782 | |||
783 | EAPI double | ||
784 | ecore_con_client_timeout_get(Ecore_Con_Client *cl) | ||
785 | { | ||
786 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
787 | { | ||
788 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_timeout_get"); | ||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | return cl->disconnect_time; | ||
793 | } | ||
794 | |||
795 | EAPI void * | ||
796 | ecore_con_client_del(Ecore_Con_Client *cl) | ||
797 | { | ||
798 | void *data = NULL; | ||
799 | |||
800 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
801 | { | ||
802 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del"); | ||
803 | return NULL; | ||
804 | } | ||
805 | |||
806 | data = cl->data; | ||
807 | cl->delete_me = EINA_TRUE; | ||
808 | if (cl->event_count) | ||
809 | { | ||
810 | if (cl->fd_handler) | ||
811 | { | ||
812 | ecore_main_fd_handler_del(cl->fd_handler); | ||
813 | cl->fd_handler = NULL; | ||
814 | } | ||
815 | } | ||
816 | else | ||
817 | { | ||
818 | if (cl->host_server) | ||
819 | { | ||
820 | cl->host_server->clients = eina_list_remove(cl->host_server->clients, cl); | ||
821 | --cl->host_server->client_count; | ||
822 | } | ||
823 | |||
824 | _ecore_con_client_free(cl); | ||
825 | } | ||
826 | |||
827 | return data; | ||
828 | } | ||
829 | |||
830 | EAPI void | ||
831 | ecore_con_client_data_set(Ecore_Con_Client *cl, | ||
832 | const void *data) | ||
833 | { | ||
834 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
835 | { | ||
836 | ECORE_MAGIC_FAIL(cl, | ||
837 | ECORE_MAGIC_CON_CLIENT, | ||
838 | "ecore_con_client_data_set"); | ||
839 | return; | ||
840 | } | ||
841 | |||
842 | cl->data = (void *)data; | ||
843 | } | ||
844 | |||
845 | EAPI void * | ||
846 | ecore_con_client_data_get(Ecore_Con_Client *cl) | ||
847 | { | ||
848 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
849 | { | ||
850 | ECORE_MAGIC_FAIL(cl, | ||
851 | ECORE_MAGIC_CON_CLIENT, | ||
852 | "ecore_con_client_data_get"); | ||
853 | return NULL; | ||
854 | } | ||
855 | |||
856 | return cl->data; | ||
857 | } | ||
858 | |||
859 | EAPI const char * | ||
860 | ecore_con_client_ip_get(Ecore_Con_Client *cl) | ||
861 | { | ||
862 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
863 | { | ||
864 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_ip_get"); | ||
865 | return NULL; | ||
866 | } | ||
867 | if (!cl->ip) | ||
868 | cl->ip = _ecore_con_pretty_ip(cl->client_addr); | ||
869 | |||
870 | return cl->ip; | ||
871 | } | ||
872 | |||
873 | EAPI int | ||
874 | ecore_con_client_port_get(Ecore_Con_Client *cl) | ||
875 | { | ||
876 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
877 | { | ||
878 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_port_get"); | ||
879 | return -1; | ||
880 | } | ||
881 | if (cl->client_addr->sa_family == AF_INET) | ||
882 | return ((struct sockaddr_in*)cl->client_addr)->sin_port; | ||
883 | #ifdef HAVE_IPV6 | ||
884 | return ((struct sockaddr_in6*)cl->client_addr)->sin6_port; | ||
885 | #else | ||
886 | return -1; | ||
887 | #endif | ||
888 | } | ||
889 | |||
890 | EAPI double | ||
891 | ecore_con_client_uptime_get(Ecore_Con_Client *cl) | ||
892 | { | ||
893 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
894 | { | ||
895 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_uptime_get"); | ||
896 | return -1; | ||
897 | } | ||
898 | |||
899 | return ecore_time_get() - cl->start_time; | ||
900 | } | ||
901 | |||
902 | EAPI void | ||
903 | ecore_con_client_flush(Ecore_Con_Client *cl) | ||
904 | { | ||
905 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
906 | { | ||
907 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_flush"); | ||
908 | return; | ||
909 | } | ||
910 | |||
911 | _ecore_con_client_flush(cl); | ||
912 | } | ||
913 | |||
914 | EAPI int | ||
915 | ecore_con_server_fd_get(Ecore_Con_Server *svr) | ||
916 | { | ||
917 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
918 | { | ||
919 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); | ||
920 | return -1; | ||
921 | } | ||
922 | if (svr->created) return -1; | ||
923 | return ecore_main_fd_handler_fd_get(svr->fd_handler); | ||
924 | } | ||
925 | |||
926 | EAPI int | ||
927 | ecore_con_client_fd_get(Ecore_Con_Client *cl) | ||
928 | { | ||
929 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
930 | { | ||
931 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__); | ||
932 | return -1; | ||
933 | } | ||
934 | return ecore_main_fd_handler_fd_get(cl->fd_handler); | ||
935 | } | ||
936 | |||
937 | /** | ||
938 | * @} | ||
939 | */ | ||
940 | |||
941 | void | ||
942 | ecore_con_event_server_add(Ecore_Con_Server *svr) | ||
943 | { | ||
944 | /* we got our server! */ | ||
945 | Ecore_Con_Event_Server_Add *e; | ||
946 | int ev = ECORE_CON_EVENT_SERVER_ADD; | ||
947 | |||
948 | e = ecore_con_event_server_add_alloc(); | ||
949 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
950 | |||
951 | svr->event_count = eina_list_append(svr->event_count, e); | ||
952 | _ecore_con_server_timer_update(svr); | ||
953 | e->server = svr; | ||
954 | if (svr->upgrade) ev = ECORE_CON_EVENT_SERVER_UPGRADE; | ||
955 | ecore_event_add(ev, e, | ||
956 | _ecore_con_event_server_add_free, NULL); | ||
957 | _ecore_con_event_count++; | ||
958 | } | ||
959 | |||
960 | void | ||
961 | ecore_con_event_server_del(Ecore_Con_Server *svr) | ||
962 | { | ||
963 | Ecore_Con_Event_Server_Del *e; | ||
964 | |||
965 | e = ecore_con_event_server_del_alloc(); | ||
966 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
967 | |||
968 | svr->event_count = eina_list_append(svr->event_count, e); | ||
969 | _ecore_con_server_timer_update(svr); | ||
970 | e->server = svr; | ||
971 | ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e, | ||
972 | _ecore_con_event_server_del_free, NULL); | ||
973 | _ecore_con_event_count++; | ||
974 | } | ||
975 | |||
976 | void | ||
977 | ecore_con_event_server_write(Ecore_Con_Server *svr, int num) | ||
978 | { | ||
979 | Ecore_Con_Event_Server_Write *e; | ||
980 | |||
981 | e = ecore_con_event_server_write_alloc(); | ||
982 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
983 | |||
984 | svr->event_count = eina_list_append(svr->event_count, e); | ||
985 | e->server = svr; | ||
986 | e->size = num; | ||
987 | ecore_event_add(ECORE_CON_EVENT_SERVER_WRITE, e, | ||
988 | (Ecore_End_Cb)_ecore_con_event_server_write_free, NULL); | ||
989 | _ecore_con_event_count++; | ||
990 | } | ||
991 | |||
992 | void | ||
993 | ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate) | ||
994 | { | ||
995 | Ecore_Con_Event_Server_Data *e; | ||
996 | |||
997 | e = ecore_con_event_server_data_alloc(); | ||
998 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
999 | |||
1000 | svr->event_count = eina_list_append(svr->event_count, e); | ||
1001 | _ecore_con_server_timer_update(svr); | ||
1002 | e->server = svr; | ||
1003 | if (duplicate) | ||
1004 | { | ||
1005 | e->data = malloc(num); | ||
1006 | if (!e->data) | ||
1007 | { | ||
1008 | ERR("server data allocation failure !"); | ||
1009 | _ecore_con_event_server_data_free(NULL, e); | ||
1010 | return; | ||
1011 | } | ||
1012 | memcpy(e->data, buf, num); | ||
1013 | } | ||
1014 | else | ||
1015 | e->data = buf; | ||
1016 | e->size = num; | ||
1017 | ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e, | ||
1018 | _ecore_con_event_server_data_free, NULL); | ||
1019 | _ecore_con_event_count++; | ||
1020 | } | ||
1021 | |||
1022 | void | ||
1023 | ecore_con_event_client_add(Ecore_Con_Client *cl) | ||
1024 | { | ||
1025 | Ecore_Con_Event_Client_Add *e; | ||
1026 | int ev = ECORE_CON_EVENT_CLIENT_ADD; | ||
1027 | |||
1028 | e = ecore_con_event_client_add_alloc(); | ||
1029 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1030 | |||
1031 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1032 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1033 | _ecore_con_cl_timer_update(cl); | ||
1034 | e->client = cl; | ||
1035 | if (cl->upgrade) ev = ECORE_CON_EVENT_CLIENT_UPGRADE; | ||
1036 | ecore_event_add(ev, e, | ||
1037 | (Ecore_End_Cb)_ecore_con_event_client_add_free, cl->host_server); | ||
1038 | _ecore_con_event_count++; | ||
1039 | } | ||
1040 | |||
1041 | void | ||
1042 | ecore_con_event_client_del(Ecore_Con_Client *cl) | ||
1043 | { | ||
1044 | Ecore_Con_Event_Client_Del *e; | ||
1045 | |||
1046 | if (!cl) return; | ||
1047 | e = ecore_con_event_client_del_alloc(); | ||
1048 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1049 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1050 | |||
1051 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1052 | _ecore_con_cl_timer_update(cl); | ||
1053 | e->client = cl; | ||
1054 | ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, | ||
1055 | (Ecore_End_Cb)_ecore_con_event_client_del_free, cl->host_server); | ||
1056 | _ecore_con_event_count++; | ||
1057 | } | ||
1058 | |||
1059 | void | ||
1060 | ecore_con_event_client_write(Ecore_Con_Client *cl, int num) | ||
1061 | { | ||
1062 | Ecore_Con_Event_Client_Write *e; | ||
1063 | |||
1064 | e = ecore_con_event_client_write_alloc(); | ||
1065 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1066 | |||
1067 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1068 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1069 | e->client = cl; | ||
1070 | e->size = num; | ||
1071 | ecore_event_add(ECORE_CON_EVENT_CLIENT_WRITE, e, | ||
1072 | (Ecore_End_Cb)_ecore_con_event_client_write_free, cl->host_server); | ||
1073 | _ecore_con_event_count++; | ||
1074 | } | ||
1075 | |||
1076 | void | ||
1077 | ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate) | ||
1078 | { | ||
1079 | Ecore_Con_Event_Client_Data *e; | ||
1080 | |||
1081 | e = ecore_con_event_client_data_alloc(); | ||
1082 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1083 | |||
1084 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1085 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1086 | _ecore_con_cl_timer_update(cl); | ||
1087 | e->client = cl; | ||
1088 | if (duplicate) | ||
1089 | { | ||
1090 | e->data = malloc(num); | ||
1091 | if (!e->data) | ||
1092 | { | ||
1093 | ERR("client data allocation failure !"); | ||
1094 | _ecore_con_event_client_data_free(cl->host_server, e); | ||
1095 | return; | ||
1096 | } | ||
1097 | memcpy(e->data, buf, num); | ||
1098 | } | ||
1099 | else | ||
1100 | e->data = buf; | ||
1101 | e->size = num; | ||
1102 | ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e, | ||
1103 | (Ecore_End_Cb)_ecore_con_event_client_data_free, cl->host_server); | ||
1104 | _ecore_con_event_count++; | ||
1105 | } | ||
1106 | |||
1107 | |||
1108 | void | ||
1109 | ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info) | ||
1110 | { | ||
1111 | svr->infos = eina_list_remove(svr->infos, info); | ||
1112 | } | ||
1113 | |||
1114 | void | ||
1115 | ecore_con_event_server_error(Ecore_Con_Server *svr, const char *error) | ||
1116 | { | ||
1117 | Ecore_Con_Event_Server_Error *e; | ||
1118 | |||
1119 | e = ecore_con_event_server_error_alloc(); | ||
1120 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1121 | |||
1122 | e->server = svr; | ||
1123 | e->error = strdup(error); | ||
1124 | ERR("%s", error); | ||
1125 | svr->event_count = eina_list_append(svr->event_count, e); | ||
1126 | ecore_event_add(ECORE_CON_EVENT_SERVER_ERROR, e, (Ecore_End_Cb)_ecore_con_event_server_error_free, NULL); | ||
1127 | _ecore_con_event_count++; | ||
1128 | } | ||
1129 | |||
1130 | void | ||
1131 | ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error) | ||
1132 | { | ||
1133 | Ecore_Con_Event_Client_Error *e; | ||
1134 | |||
1135 | e = ecore_con_event_client_error_alloc(); | ||
1136 | EINA_SAFETY_ON_NULL_RETURN(e); | ||
1137 | |||
1138 | e->client = cl; | ||
1139 | e->error = strdup(error); | ||
1140 | ERR("%s", error); | ||
1141 | cl->event_count = eina_list_append(cl->event_count, e); | ||
1142 | cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); | ||
1143 | ecore_event_add(ECORE_CON_EVENT_CLIENT_ERROR, e, (Ecore_End_Cb)_ecore_con_event_client_error_free, cl->host_server); | ||
1144 | _ecore_con_event_count++; | ||
1145 | } | ||
1146 | |||
1147 | static void | ||
1148 | _ecore_con_server_free(Ecore_Con_Server *svr) | ||
1149 | { | ||
1150 | Ecore_Con_Client *cl; | ||
1151 | double t_start, t; | ||
1152 | |||
1153 | if (svr->event_count) return; | ||
1154 | |||
1155 | while (svr->infos) | ||
1156 | { | ||
1157 | ecore_con_info_data_clear(svr->infos->data); | ||
1158 | svr->infos = eina_list_remove_list(svr->infos, svr->infos); | ||
1159 | } | ||
1160 | if ((!svr->buf) && svr->delete_me && (!svr->dead) && (!svr->event_count)) | ||
1161 | { | ||
1162 | /* this is a catch-all for cases when a server is not properly killed. */ | ||
1163 | svr->dead = EINA_TRUE; | ||
1164 | ecore_con_event_server_del(svr); | ||
1165 | return; | ||
1166 | } | ||
1167 | |||
1168 | t_start = ecore_time_get(); | ||
1169 | while (svr->buf && (!svr->dead)) | ||
1170 | { | ||
1171 | _ecore_con_server_flush(svr); | ||
1172 | t = ecore_time_get(); | ||
1173 | if ((t - t_start) > 0.5) | ||
1174 | { | ||
1175 | WRN("ECORE_CON: EEK - stuck in _ecore_con_server_free() trying\n" | ||
1176 | " to flush data out from the server, and have been for\n" | ||
1177 | " %1.1f seconds. This is taking too long. Aborting flush.", | ||
1178 | (t - t_start)); | ||
1179 | break; | ||
1180 | } | ||
1181 | } | ||
1182 | |||
1183 | #ifdef _WIN32 | ||
1184 | ecore_con_local_win32_server_del(svr); | ||
1185 | #endif | ||
1186 | if (svr->event_count) return; | ||
1187 | ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE); | ||
1188 | |||
1189 | if (svr->buf) | ||
1190 | eina_binbuf_free(svr->buf); | ||
1191 | |||
1192 | EINA_LIST_FREE(svr->clients, cl) | ||
1193 | { | ||
1194 | Ecore_Con_Event_Server_Add *ev; | ||
1195 | |||
1196 | /* some pointer hacks here to prevent double frees if people are being stupid */ | ||
1197 | EINA_LIST_FREE(cl->event_count, ev) | ||
1198 | ev->server = NULL; | ||
1199 | cl->delete_me = cl->dead = EINA_TRUE; | ||
1200 | _ecore_con_client_free(cl); | ||
1201 | } | ||
1202 | if ((svr->created) && (svr->path) && (svr->ppid == getpid())) | ||
1203 | unlink(svr->path); | ||
1204 | |||
1205 | ecore_con_ssl_server_shutdown(svr); | ||
1206 | free(svr->name); | ||
1207 | |||
1208 | free(svr->path); | ||
1209 | |||
1210 | eina_stringshare_del(svr->ip); | ||
1211 | |||
1212 | if (svr->fd_handler) | ||
1213 | ecore_main_fd_handler_del(svr->fd_handler); | ||
1214 | |||
1215 | if (svr->fd > 0) | ||
1216 | close(svr->fd); | ||
1217 | |||
1218 | if (svr->until_deletion) | ||
1219 | ecore_timer_del(svr->until_deletion); | ||
1220 | |||
1221 | servers = eina_list_remove(servers, svr); | ||
1222 | svr->data = NULL; | ||
1223 | free(svr); | ||
1224 | } | ||
1225 | |||
1226 | static void | ||
1227 | _ecore_con_client_free(Ecore_Con_Client *cl) | ||
1228 | { | ||
1229 | double t_start, t; | ||
1230 | |||
1231 | if (cl->event_count) return; | ||
1232 | |||
1233 | if (cl->delete_me && (!cl->dead) && (!cl->event_count)) | ||
1234 | { | ||
1235 | /* this is a catch-all for cases when a client is not properly killed. */ | ||
1236 | cl->dead = EINA_TRUE; | ||
1237 | ecore_con_event_client_del(cl); | ||
1238 | return; | ||
1239 | } | ||
1240 | |||
1241 | |||
1242 | t_start = ecore_time_get(); | ||
1243 | while ((cl->buf) && (!cl->dead)) | ||
1244 | { | ||
1245 | _ecore_con_client_flush(cl); | ||
1246 | t = ecore_time_get(); | ||
1247 | if ((t - t_start) > 0.5) | ||
1248 | { | ||
1249 | WRN("EEK - stuck in _ecore_con_client_free() trying\n" | ||
1250 | " to flush data out from the client, and have been for\n" | ||
1251 | " %1.1f seconds. This is taking too long. Aborting flush.", | ||
1252 | (t - t_start)); | ||
1253 | break; | ||
1254 | } | ||
1255 | } | ||
1256 | |||
1257 | #ifdef _WIN32 | ||
1258 | ecore_con_local_win32_client_del(cl); | ||
1259 | #endif | ||
1260 | |||
1261 | if (cl->event_count) return; | ||
1262 | ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE); | ||
1263 | |||
1264 | free(cl->buf); | ||
1265 | |||
1266 | if (cl->host_server->type & ECORE_CON_SSL) | ||
1267 | ecore_con_ssl_client_shutdown(cl); | ||
1268 | |||
1269 | if (cl->fd_handler) | ||
1270 | ecore_main_fd_handler_del(cl->fd_handler); | ||
1271 | |||
1272 | if (cl->fd > 0) | ||
1273 | close(cl->fd); | ||
1274 | |||
1275 | free(cl->client_addr); | ||
1276 | cl->client_addr = NULL; | ||
1277 | |||
1278 | if (cl->until_deletion) | ||
1279 | ecore_timer_del(cl->until_deletion); | ||
1280 | |||
1281 | eina_stringshare_del(cl->ip); | ||
1282 | cl->data = NULL; | ||
1283 | free(cl); | ||
1284 | return; | ||
1285 | } | ||
1286 | |||
1287 | static void | ||
1288 | _ecore_con_server_kill(Ecore_Con_Server *svr) | ||
1289 | { | ||
1290 | if (!svr->delete_me) | ||
1291 | ecore_con_event_server_del(svr); | ||
1292 | |||
1293 | svr->dead = EINA_TRUE; | ||
1294 | if (svr->fd_handler) | ||
1295 | ecore_main_fd_handler_del(svr->fd_handler); | ||
1296 | |||
1297 | svr->fd_handler = NULL; | ||
1298 | } | ||
1299 | |||
1300 | static Eina_Bool | ||
1301 | _ecore_con_server_timer(Ecore_Con_Server *svr) | ||
1302 | { | ||
1303 | ecore_con_server_del(svr); | ||
1304 | |||
1305 | svr->until_deletion = NULL; | ||
1306 | return ECORE_CALLBACK_CANCEL; | ||
1307 | } | ||
1308 | |||
1309 | static void | ||
1310 | _ecore_con_server_timer_update(Ecore_Con_Server *svr) | ||
1311 | { | ||
1312 | if (svr->disconnect_time) | ||
1313 | { | ||
1314 | if (svr->disconnect_time > 0) | ||
1315 | { | ||
1316 | if (svr->until_deletion) | ||
1317 | ecore_timer_interval_set(svr->until_deletion, svr->disconnect_time); | ||
1318 | else | ||
1319 | svr->until_deletion = ecore_timer_add(svr->disconnect_time, (Ecore_Task_Cb)_ecore_con_server_timer, svr); | ||
1320 | } | ||
1321 | else if (svr->until_deletion) | ||
1322 | { | ||
1323 | ecore_timer_del(svr->until_deletion); | ||
1324 | svr->until_deletion = NULL; | ||
1325 | } | ||
1326 | } | ||
1327 | else | ||
1328 | { | ||
1329 | if (svr->until_deletion) | ||
1330 | { | ||
1331 | ecore_timer_del(svr->until_deletion); | ||
1332 | svr->until_deletion = NULL; | ||
1333 | } | ||
1334 | } | ||
1335 | } | ||
1336 | |||
1337 | static Eina_Bool | ||
1338 | _ecore_con_client_timer(Ecore_Con_Client *cl) | ||
1339 | { | ||
1340 | ecore_con_client_del(cl); | ||
1341 | |||
1342 | cl->until_deletion = NULL; | ||
1343 | return ECORE_CALLBACK_CANCEL; | ||
1344 | } | ||
1345 | |||
1346 | static void | ||
1347 | _ecore_con_cl_timer_update(Ecore_Con_Client *cl) | ||
1348 | { | ||
1349 | if (cl->disconnect_time) | ||
1350 | { | ||
1351 | if (cl->disconnect_time > 0) | ||
1352 | { | ||
1353 | if (cl->until_deletion) | ||
1354 | ecore_timer_interval_set(cl->until_deletion, cl->disconnect_time); | ||
1355 | else | ||
1356 | cl->until_deletion = ecore_timer_add(cl->disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl); | ||
1357 | } | ||
1358 | else if (cl->until_deletion) | ||
1359 | { | ||
1360 | ecore_timer_del(cl->until_deletion); | ||
1361 | cl->until_deletion = NULL; | ||
1362 | } | ||
1363 | } | ||
1364 | else | ||
1365 | { | ||
1366 | if (cl->host_server->client_disconnect_time > 0) | ||
1367 | { | ||
1368 | if (cl->until_deletion) | ||
1369 | ecore_timer_interval_set(cl->until_deletion, cl->host_server->client_disconnect_time); | ||
1370 | else | ||
1371 | cl->until_deletion = ecore_timer_add(cl->host_server->client_disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl); | ||
1372 | } | ||
1373 | else if (cl->until_deletion) | ||
1374 | { | ||
1375 | ecore_timer_del(cl->until_deletion); | ||
1376 | cl->until_deletion = NULL; | ||
1377 | } | ||
1378 | } | ||
1379 | } | ||
1380 | |||
1381 | static void | ||
1382 | _ecore_con_cb_tcp_listen(void *data, | ||
1383 | Ecore_Con_Info *net_info) | ||
1384 | { | ||
1385 | Ecore_Con_Server *svr; | ||
1386 | struct linger lin; | ||
1387 | |||
1388 | svr = data; | ||
1389 | |||
1390 | if (!net_info) /* error message has already been handled */ | ||
1391 | goto error; | ||
1392 | |||
1393 | svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, | ||
1394 | net_info->info.ai_protocol); | ||
1395 | if (svr->fd < 0) | ||
1396 | { | ||
1397 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1398 | goto error; | ||
1399 | } | ||
1400 | |||
1401 | if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) | ||
1402 | { | ||
1403 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1404 | goto error; | ||
1405 | } | ||
1406 | |||
1407 | if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) | ||
1408 | { | ||
1409 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1410 | goto error; | ||
1411 | } | ||
1412 | |||
1413 | lin.l_onoff = 1; | ||
1414 | lin.l_linger = 0; | ||
1415 | if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin, | ||
1416 | sizeof(struct linger)) < 0) | ||
1417 | { | ||
1418 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1419 | goto error; | ||
1420 | } | ||
1421 | |||
1422 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY) | ||
1423 | { | ||
1424 | #ifdef HAVE_NETINET_TCP_H | ||
1425 | int flag = 1; | ||
1426 | |||
1427 | if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, | ||
1428 | sizeof(int)) < 0) | ||
1429 | #endif | ||
1430 | { | ||
1431 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1432 | goto error; | ||
1433 | } | ||
1434 | } | ||
1435 | |||
1436 | if (bind(svr->fd, net_info->info.ai_addr, | ||
1437 | net_info->info.ai_addrlen) < 0) | ||
1438 | { | ||
1439 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1440 | goto error; | ||
1441 | } | ||
1442 | if (listen(svr->fd, 4096) < 0) | ||
1443 | { | ||
1444 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1445 | goto error; | ||
1446 | } | ||
1447 | |||
1448 | svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, | ||
1449 | _ecore_con_svr_tcp_handler, svr, NULL, NULL); | ||
1450 | if (!svr->fd_handler) | ||
1451 | { | ||
1452 | ecore_con_event_server_error(svr, "Memory allocation failure"); | ||
1453 | goto error; | ||
1454 | } | ||
1455 | |||
1456 | return; | ||
1457 | |||
1458 | error: | ||
1459 | ecore_con_ssl_server_shutdown(svr); | ||
1460 | _ecore_con_server_kill(svr); | ||
1461 | } | ||
1462 | |||
1463 | static void | ||
1464 | _ecore_con_cb_udp_listen(void *data, | ||
1465 | Ecore_Con_Info *net_info) | ||
1466 | { | ||
1467 | Ecore_Con_Server *svr; | ||
1468 | Ecore_Con_Type type; | ||
1469 | struct ip_mreq mreq; | ||
1470 | #ifdef HAVE_IPV6 | ||
1471 | struct ipv6_mreq mreq6; | ||
1472 | #endif | ||
1473 | const int on = 1; | ||
1474 | |||
1475 | svr = data; | ||
1476 | type = svr->type; | ||
1477 | type &= ECORE_CON_TYPE; | ||
1478 | |||
1479 | if (!net_info) /* error message has already been handled */ | ||
1480 | goto error; | ||
1481 | |||
1482 | svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, | ||
1483 | net_info->info.ai_protocol); | ||
1484 | if (svr->fd < 0) | ||
1485 | { | ||
1486 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1487 | goto error; | ||
1488 | } | ||
1489 | |||
1490 | if (type == ECORE_CON_REMOTE_MCAST) | ||
1491 | { | ||
1492 | if (net_info->info.ai_family == AF_INET) | ||
1493 | { | ||
1494 | if (!inet_pton(net_info->info.ai_family, net_info->ip, | ||
1495 | &mreq.imr_multiaddr)) | ||
1496 | { | ||
1497 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1498 | goto error; | ||
1499 | } | ||
1500 | |||
1501 | mreq.imr_interface.s_addr = htonl(INADDR_ANY); | ||
1502 | if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, | ||
1503 | (const void *)&mreq, sizeof(mreq)) != 0) | ||
1504 | { | ||
1505 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1506 | goto error; | ||
1507 | } | ||
1508 | } | ||
1509 | #ifdef HAVE_IPV6 | ||
1510 | else if (net_info->info.ai_family == AF_INET6) | ||
1511 | { | ||
1512 | if (!inet_pton(net_info->info.ai_family, net_info->ip, | ||
1513 | &mreq6.ipv6mr_multiaddr)) | ||
1514 | { | ||
1515 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1516 | goto error; | ||
1517 | } | ||
1518 | mreq6.ipv6mr_interface = htonl(INADDR_ANY); | ||
1519 | if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, | ||
1520 | (const void *)&mreq6, sizeof(mreq6)) != 0) | ||
1521 | { | ||
1522 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1523 | goto error; | ||
1524 | } | ||
1525 | } | ||
1526 | #endif | ||
1527 | } | ||
1528 | |||
1529 | if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0) | ||
1530 | { | ||
1531 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1532 | goto error; | ||
1533 | } | ||
1534 | |||
1535 | if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) | ||
1536 | { | ||
1537 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1538 | goto error; | ||
1539 | } | ||
1540 | |||
1541 | if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) | ||
1542 | { | ||
1543 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1544 | goto error; | ||
1545 | } | ||
1546 | |||
1547 | if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) | ||
1548 | { | ||
1549 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1550 | goto error; | ||
1551 | } | ||
1552 | |||
1553 | svr->fd_handler = | ||
1554 | ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, | ||
1555 | _ecore_con_svr_udp_handler, svr, NULL, NULL); | ||
1556 | if (!svr->fd_handler) | ||
1557 | { | ||
1558 | ecore_con_event_server_error(svr, "Memory allocation failure"); | ||
1559 | goto error; | ||
1560 | } | ||
1561 | |||
1562 | svr->ip = eina_stringshare_add(net_info->ip); | ||
1563 | |||
1564 | return; | ||
1565 | |||
1566 | error: | ||
1567 | ecore_con_ssl_server_shutdown(svr); | ||
1568 | _ecore_con_server_kill(svr); | ||
1569 | } | ||
1570 | |||
1571 | static void | ||
1572 | _ecore_con_cb_tcp_connect(void *data, | ||
1573 | Ecore_Con_Info *net_info) | ||
1574 | { | ||
1575 | Ecore_Con_Server *svr; | ||
1576 | int res; | ||
1577 | int curstate = 0; | ||
1578 | |||
1579 | svr = data; | ||
1580 | |||
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) | ||
1587 | { | ||
1588 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1589 | goto error; | ||
1590 | } | ||
1591 | |||
1592 | if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) | ||
1593 | { | ||
1594 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1595 | goto error; | ||
1596 | } | ||
1597 | |||
1598 | if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) | ||
1599 | { | ||
1600 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1601 | goto error; | ||
1602 | } | ||
1603 | |||
1604 | if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0) | ||
1605 | { | ||
1606 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1607 | goto error; | ||
1608 | } | ||
1609 | |||
1610 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY) | ||
1611 | { | ||
1612 | #ifdef HAVE_NETINET_TCP_H | ||
1613 | int flag = 1; | ||
1614 | |||
1615 | if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0) | ||
1616 | #endif | ||
1617 | { | ||
1618 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1619 | goto error; | ||
1620 | } | ||
1621 | } | ||
1622 | |||
1623 | res = connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen); | ||
1624 | #ifdef _WIN32 | ||
1625 | if (res == SOCKET_ERROR) | ||
1626 | { | ||
1627 | if (WSAGetLastError() != WSAEINPROGRESS) | ||
1628 | goto error; /* FIXME: strerror on windows? */ | ||
1629 | |||
1630 | #else | ||
1631 | if (res < 0) | ||
1632 | { | ||
1633 | if (errno != EINPROGRESS) | ||
1634 | { | ||
1635 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1636 | goto error; | ||
1637 | } | ||
1638 | |||
1639 | #endif | ||
1640 | svr->connecting = EINA_TRUE; | ||
1641 | svr->fd_handler = | ||
1642 | ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE, | ||
1643 | _ecore_con_cl_handler, svr, NULL, NULL); | ||
1644 | } | ||
1645 | else | ||
1646 | svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, | ||
1647 | _ecore_con_cl_handler, svr, NULL, NULL); | ||
1648 | |||
1649 | if (svr->type & ECORE_CON_SSL) | ||
1650 | { | ||
1651 | svr->handshaking = EINA_TRUE; | ||
1652 | svr->ssl_state = ECORE_CON_SSL_STATE_INIT; | ||
1653 | DBG("beginning ssl handshake"); | ||
1654 | if (ecore_con_ssl_server_init(svr)) | ||
1655 | goto error; | ||
1656 | } | ||
1657 | |||
1658 | if (!svr->fd_handler) | ||
1659 | { | ||
1660 | ecore_con_event_server_error(svr, "Memory allocation failure"); | ||
1661 | goto error; | ||
1662 | } | ||
1663 | |||
1664 | svr->ip = eina_stringshare_add(net_info->ip); | ||
1665 | |||
1666 | return; | ||
1667 | |||
1668 | error: | ||
1669 | ecore_con_ssl_server_shutdown(svr); | ||
1670 | _ecore_con_server_kill(svr); | ||
1671 | } | ||
1672 | |||
1673 | static void | ||
1674 | _ecore_con_cb_udp_connect(void *data, | ||
1675 | Ecore_Con_Info *net_info) | ||
1676 | { | ||
1677 | Ecore_Con_Server *svr; | ||
1678 | int curstate = 0; | ||
1679 | int broadcast = 1; | ||
1680 | svr = data; | ||
1681 | |||
1682 | if (!net_info) /* error message has already been handled */ | ||
1683 | goto error; | ||
1684 | |||
1685 | svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, | ||
1686 | net_info->info.ai_protocol); | ||
1687 | if (svr->fd < 0) | ||
1688 | { | ||
1689 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1690 | goto error; | ||
1691 | } | ||
1692 | |||
1693 | if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) | ||
1694 | { | ||
1695 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1696 | goto error; | ||
1697 | } | ||
1698 | |||
1699 | if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) | ||
1700 | { | ||
1701 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1702 | goto error; | ||
1703 | } | ||
1704 | |||
1705 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_BROADCAST) | ||
1706 | { | ||
1707 | if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST, | ||
1708 | (const void *)&broadcast, | ||
1709 | sizeof(broadcast)) < 0) | ||
1710 | { | ||
1711 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1712 | goto error; | ||
1713 | } | ||
1714 | } | ||
1715 | else if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, | ||
1716 | (const void *)&curstate, sizeof(curstate)) < 0) | ||
1717 | { | ||
1718 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1719 | goto error; | ||
1720 | } | ||
1721 | |||
1722 | if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) | ||
1723 | { | ||
1724 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1725 | goto error; | ||
1726 | } | ||
1727 | |||
1728 | svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE, | ||
1729 | _ecore_con_cl_udp_handler, svr, NULL, NULL); | ||
1730 | |||
1731 | if (!svr->fd_handler) | ||
1732 | { | ||
1733 | ecore_con_event_server_error(svr, "Memory allocation failure"); | ||
1734 | goto error; | ||
1735 | } | ||
1736 | |||
1737 | svr->ip = eina_stringshare_add(net_info->ip); | ||
1738 | |||
1739 | return; | ||
1740 | |||
1741 | error: | ||
1742 | ecore_con_ssl_server_shutdown(svr); | ||
1743 | _ecore_con_server_kill(svr); | ||
1744 | } | ||
1745 | |||
1746 | static Ecore_Con_State | ||
1747 | svr_try_connect_plain(Ecore_Con_Server *svr) | ||
1748 | { | ||
1749 | int res; | ||
1750 | int so_err = 0; | ||
1751 | socklen_t size = sizeof(int); | ||
1752 | |||
1753 | res = getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, (void *)&so_err, &size); | ||
1754 | #ifdef _WIN32 | ||
1755 | if (res == SOCKET_ERROR) | ||
1756 | so_err = WSAGetLastError(); | ||
1757 | |||
1758 | if ((so_err == WSAEINPROGRESS) && !svr->dead) | ||
1759 | return ECORE_CON_INPROGRESS; | ||
1760 | |||
1761 | #else | ||
1762 | if (res < 0) | ||
1763 | so_err = errno; | ||
1764 | |||
1765 | if ((so_err == EINPROGRESS) && !svr->dead) | ||
1766 | return ECORE_CON_INPROGRESS; | ||
1767 | |||
1768 | #endif | ||
1769 | |||
1770 | if (so_err) | ||
1771 | { | ||
1772 | /* we lost our server! */ | ||
1773 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1774 | ERR("Connection lost: %s", strerror(so_err)); | ||
1775 | _ecore_con_server_kill(svr); | ||
1776 | return ECORE_CON_DISCONNECTED; | ||
1777 | } | ||
1778 | |||
1779 | if ((!svr->delete_me) && (!svr->handshaking) && svr->connecting) | ||
1780 | { | ||
1781 | svr->connecting = EINA_FALSE; | ||
1782 | svr->start_time = ecore_time_get(); | ||
1783 | ecore_con_event_server_add(svr); | ||
1784 | } | ||
1785 | |||
1786 | if (svr->fd_handler && (!svr->buf)) | ||
1787 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
1788 | |||
1789 | if (!svr->dead) | ||
1790 | return ECORE_CON_CONNECTED; | ||
1791 | else | ||
1792 | return ECORE_CON_DISCONNECTED; | ||
1793 | } | ||
1794 | |||
1795 | static const char * | ||
1796 | _ecore_con_pretty_ip(struct sockaddr *client_addr) | ||
1797 | { | ||
1798 | #ifndef HAVE_IPV6 | ||
1799 | char ipbuf[INET_ADDRSTRLEN + 1]; | ||
1800 | #else | ||
1801 | char ipbuf[INET6_ADDRSTRLEN + 1]; | ||
1802 | #endif | ||
1803 | int family = client_addr->sa_family; | ||
1804 | void *src; | ||
1805 | |||
1806 | switch(family) | ||
1807 | { | ||
1808 | case AF_INET: | ||
1809 | src = &(((struct sockaddr_in *)client_addr)->sin_addr); | ||
1810 | break; | ||
1811 | #ifdef HAVE_IPV6 | ||
1812 | case AF_INET6: | ||
1813 | src = &(((struct sockaddr_in6 *)client_addr)->sin6_addr); | ||
1814 | |||
1815 | if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)) | ||
1816 | { | ||
1817 | family = AF_INET; | ||
1818 | src = (char*)src + 12; | ||
1819 | } | ||
1820 | break; | ||
1821 | #endif | ||
1822 | default: | ||
1823 | return eina_stringshare_add("0.0.0.0"); | ||
1824 | } | ||
1825 | |||
1826 | if (!inet_ntop(family, src, ipbuf, sizeof(ipbuf))) | ||
1827 | return eina_stringshare_add("0.0.0.0"); | ||
1828 | |||
1829 | ipbuf[sizeof(ipbuf) - 1] = 0; | ||
1830 | return eina_stringshare_add(ipbuf); | ||
1831 | } | ||
1832 | |||
1833 | static Eina_Bool | ||
1834 | _ecore_con_svr_tcp_handler(void *data, | ||
1835 | Ecore_Fd_Handler *fd_handler __UNUSED__) | ||
1836 | { | ||
1837 | Ecore_Con_Server *svr; | ||
1838 | Ecore_Con_Client *cl = NULL; | ||
1839 | unsigned char client_addr[256]; | ||
1840 | unsigned int client_addr_len; | ||
1841 | |||
1842 | svr = data; | ||
1843 | if (svr->dead) | ||
1844 | return ECORE_CALLBACK_RENEW; | ||
1845 | |||
1846 | if (svr->delete_me) | ||
1847 | return ECORE_CALLBACK_RENEW; | ||
1848 | |||
1849 | if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) && | ||
1850 | (svr->client_count >= (unsigned int)svr->client_limit)) | ||
1851 | return ECORE_CALLBACK_RENEW; | ||
1852 | |||
1853 | /* a new client */ | ||
1854 | |||
1855 | cl = calloc(1, sizeof(Ecore_Con_Client)); | ||
1856 | if (!cl) | ||
1857 | { | ||
1858 | ecore_con_event_server_error(svr, "Memory allocation failure when attempting to add a new client"); | ||
1859 | return ECORE_CALLBACK_RENEW; | ||
1860 | } | ||
1861 | cl->host_server = svr; | ||
1862 | |||
1863 | client_addr_len = sizeof(client_addr); | ||
1864 | memset(&client_addr, 0, client_addr_len); | ||
1865 | cl->fd = accept(svr->fd, (struct sockaddr *)&client_addr, (socklen_t *)&client_addr_len); | ||
1866 | if (cl->fd < 0) | ||
1867 | { | ||
1868 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1869 | goto free_cl; | ||
1870 | } | ||
1871 | |||
1872 | if ((svr->client_limit >= 0) && (svr->reject_excess_clients) && | ||
1873 | (svr->client_count >= (unsigned int)svr->client_limit)) | ||
1874 | { | ||
1875 | ecore_con_event_server_error(svr, "Maximum client limit reached"); | ||
1876 | goto close_fd; | ||
1877 | } | ||
1878 | |||
1879 | if (fcntl(cl->fd, F_SETFL, O_NONBLOCK) < 0) | ||
1880 | { | ||
1881 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1882 | goto close_fd; | ||
1883 | } | ||
1884 | if (fcntl(cl->fd, F_SETFD, FD_CLOEXEC) < 0) | ||
1885 | { | ||
1886 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1887 | goto close_fd; | ||
1888 | } | ||
1889 | cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ, | ||
1890 | _ecore_con_svr_cl_handler, cl, NULL, NULL); | ||
1891 | if (!cl->fd_handler) | ||
1892 | goto close_fd; | ||
1893 | |||
1894 | ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); | ||
1895 | |||
1896 | if ((!svr->upgrade) && (svr->type & ECORE_CON_SSL)) | ||
1897 | { | ||
1898 | cl->handshaking = EINA_TRUE; | ||
1899 | cl->ssl_state = ECORE_CON_SSL_STATE_INIT; | ||
1900 | if (ecore_con_ssl_client_init(cl)) | ||
1901 | goto del_handler; | ||
1902 | } | ||
1903 | |||
1904 | cl->client_addr = malloc(client_addr_len); | ||
1905 | if (!cl->client_addr) | ||
1906 | { | ||
1907 | ecore_con_event_server_error(svr, "Memory allocation failure when attempting to add a new client"); | ||
1908 | goto del_handler; | ||
1909 | } | ||
1910 | cl->client_addr_len = client_addr_len; | ||
1911 | memcpy(cl->client_addr, &client_addr, client_addr_len); | ||
1912 | |||
1913 | svr->clients = eina_list_append(svr->clients, cl); | ||
1914 | svr->client_count++; | ||
1915 | |||
1916 | if ((!cl->delete_me) && (!cl->handshaking)) | ||
1917 | ecore_con_event_client_add(cl); | ||
1918 | |||
1919 | return ECORE_CALLBACK_RENEW; | ||
1920 | |||
1921 | del_handler: | ||
1922 | ecore_main_fd_handler_del(cl->fd_handler); | ||
1923 | close_fd: | ||
1924 | close(cl->fd); | ||
1925 | free_cl: | ||
1926 | free(cl); | ||
1927 | |||
1928 | return ECORE_CALLBACK_RENEW; | ||
1929 | } | ||
1930 | |||
1931 | static void | ||
1932 | _ecore_con_cl_read(Ecore_Con_Server *svr) | ||
1933 | { | ||
1934 | DBG("svr=%p", svr); | ||
1935 | int num = 0; | ||
1936 | Eina_Bool lost_server = EINA_TRUE; | ||
1937 | unsigned char buf[READBUFSIZ]; | ||
1938 | |||
1939 | /* only possible with non-ssl connections */ | ||
1940 | if (svr->connecting && (svr_try_connect_plain(svr) != ECORE_CON_CONNECTED)) | ||
1941 | return; | ||
1942 | |||
1943 | if (svr->handshaking) | ||
1944 | { | ||
1945 | DBG("Continuing ssl handshake"); | ||
1946 | if (!ecore_con_ssl_server_init(svr)) | ||
1947 | lost_server = EINA_FALSE; | ||
1948 | _ecore_con_server_timer_update(svr); | ||
1949 | } | ||
1950 | |||
1951 | if (!(svr->type & ECORE_CON_SSL)) | ||
1952 | { | ||
1953 | num = read(svr->fd, buf, sizeof(buf)); | ||
1954 | /* 0 is not a valid return value for a tcp socket */ | ||
1955 | if ((num > 0) || ((num < 0) && (errno == EAGAIN))) | ||
1956 | lost_server = EINA_FALSE; | ||
1957 | else if (num < 0) | ||
1958 | ecore_con_event_server_error(svr, strerror(errno)); | ||
1959 | } | ||
1960 | else | ||
1961 | { | ||
1962 | num = ecore_con_ssl_server_read(svr, buf, sizeof(buf)); | ||
1963 | /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */ | ||
1964 | if (num >= 0) | ||
1965 | lost_server = EINA_FALSE; | ||
1966 | } | ||
1967 | |||
1968 | if ((!svr->delete_me) && (num > 0)) | ||
1969 | ecore_con_event_server_data(svr, buf, num, EINA_TRUE); | ||
1970 | |||
1971 | if (lost_server) | ||
1972 | _ecore_con_server_kill(svr); | ||
1973 | } | ||
1974 | |||
1975 | static Eina_Bool | ||
1976 | _ecore_con_cl_handler(void *data, | ||
1977 | Ecore_Fd_Handler *fd_handler) | ||
1978 | { | ||
1979 | Ecore_Con_Server *svr; | ||
1980 | Eina_Bool want_read, want_write; | ||
1981 | |||
1982 | svr = data; | ||
1983 | if (svr->dead) | ||
1984 | return ECORE_CALLBACK_RENEW; | ||
1985 | |||
1986 | if (svr->delete_me) | ||
1987 | return ECORE_CALLBACK_RENEW; | ||
1988 | |||
1989 | want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); | ||
1990 | want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); | ||
1991 | |||
1992 | if (svr->handshaking && (want_read || want_write)) | ||
1993 | { | ||
1994 | DBG("Continuing ssl handshake: preparing to %s...", want_read ? "read" : "write"); | ||
1995 | #ifdef ISCOMFITOR | ||
1996 | if (want_read) | ||
1997 | { | ||
1998 | char buf[READBUFSIZ]; | ||
1999 | ssize_t len; | ||
2000 | len = recv(svr->fd, buf, sizeof(buf), MSG_DONTWAIT | MSG_PEEK); | ||
2001 | DBG("%zu bytes in buffer", len); | ||
2002 | } | ||
2003 | #endif | ||
2004 | if (ecore_con_ssl_server_init(svr)) | ||
2005 | { | ||
2006 | ERR("ssl handshaking failed!"); | ||
2007 | svr->handshaking = EINA_FALSE; | ||
2008 | |||
2009 | } | ||
2010 | else if (!svr->ssl_state) | ||
2011 | { | ||
2012 | svr->connecting = EINA_FALSE; | ||
2013 | svr->start_time = ecore_time_get(); | ||
2014 | ecore_con_event_server_add(svr); | ||
2015 | } | ||
2016 | } | ||
2017 | else if (want_read) | ||
2018 | _ecore_con_cl_read(svr); | ||
2019 | else if (want_write) /* only possible with non-ssl connections */ | ||
2020 | { | ||
2021 | if (svr->connecting && (!svr_try_connect_plain(svr))) | ||
2022 | return ECORE_CALLBACK_RENEW; | ||
2023 | |||
2024 | _ecore_con_server_flush(svr); | ||
2025 | } | ||
2026 | |||
2027 | return ECORE_CALLBACK_RENEW; | ||
2028 | } | ||
2029 | |||
2030 | static Eina_Bool | ||
2031 | _ecore_con_cl_udp_handler(void *data, | ||
2032 | Ecore_Fd_Handler *fd_handler) | ||
2033 | { | ||
2034 | unsigned char buf[READBUFSIZ]; | ||
2035 | int num; | ||
2036 | Ecore_Con_Server *svr; | ||
2037 | Eina_Bool want_read, want_write; | ||
2038 | |||
2039 | want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); | ||
2040 | want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); | ||
2041 | |||
2042 | svr = data; | ||
2043 | if (svr->dead || svr->delete_me || ((!want_read) && (!want_write))) | ||
2044 | return ECORE_CALLBACK_RENEW; | ||
2045 | |||
2046 | if (want_write) | ||
2047 | { | ||
2048 | _ecore_con_server_flush(svr); | ||
2049 | return ECORE_CALLBACK_RENEW; | ||
2050 | } | ||
2051 | |||
2052 | num = read(svr->fd, buf, READBUFSIZ); | ||
2053 | |||
2054 | if ((!svr->delete_me) && (num > 0)) | ||
2055 | ecore_con_event_server_data(svr, buf, num, EINA_TRUE); | ||
2056 | |||
2057 | if (num < 0 && (errno != EAGAIN) && (errno != EINTR)) | ||
2058 | { | ||
2059 | ecore_con_event_server_error(svr, strerror(errno)); | ||
2060 | _ecore_con_server_kill(svr); | ||
2061 | } | ||
2062 | |||
2063 | return ECORE_CALLBACK_RENEW; | ||
2064 | } | ||
2065 | |||
2066 | static Eina_Bool | ||
2067 | _ecore_con_svr_udp_handler(void *data, | ||
2068 | Ecore_Fd_Handler *fd_handler) | ||
2069 | { | ||
2070 | unsigned char buf[READBUFSIZ]; | ||
2071 | unsigned char client_addr[256]; | ||
2072 | socklen_t client_addr_len = sizeof(client_addr); | ||
2073 | int num; | ||
2074 | Ecore_Con_Server *svr; | ||
2075 | Ecore_Con_Client *cl = NULL; | ||
2076 | |||
2077 | svr = data; | ||
2078 | |||
2079 | if (svr->delete_me || svr->dead) | ||
2080 | return ECORE_CALLBACK_RENEW; | ||
2081 | |||
2082 | if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) | ||
2083 | { | ||
2084 | _ecore_con_client_flush(cl); | ||
2085 | return ECORE_CALLBACK_RENEW; | ||
2086 | } | ||
2087 | |||
2088 | if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) | ||
2089 | return ECORE_CALLBACK_RENEW; | ||
2090 | |||
2091 | #ifdef _WIN32 | ||
2092 | num = fcntl(svr->fd, F_SETFL, O_NONBLOCK); | ||
2093 | if (num >= 0) | ||
2094 | num = recvfrom(svr->fd, (char *)buf, sizeof(buf), 0, | ||
2095 | (struct sockaddr *)&client_addr, | ||
2096 | &client_addr_len); | ||
2097 | |||
2098 | #else | ||
2099 | num = recvfrom(svr->fd, buf, sizeof(buf), MSG_DONTWAIT, | ||
2100 | (struct sockaddr *)&client_addr, | ||
2101 | &client_addr_len); | ||
2102 | #endif | ||
2103 | |||
2104 | if (num < 0 && (errno != EAGAIN) && (errno != EINTR)) | ||
2105 | { | ||
2106 | ecore_con_event_server_error(svr, strerror(errno)); | ||
2107 | if (!svr->delete_me) | ||
2108 | ecore_con_event_client_del(NULL); | ||
2109 | |||
2110 | svr->dead = EINA_TRUE; | ||
2111 | svr->fd_handler = NULL; | ||
2112 | return ECORE_CALLBACK_CANCEL; | ||
2113 | } | ||
2114 | |||
2115 | |||
2116 | /* Create a new client for use in the client data event */ | ||
2117 | cl = calloc(1, sizeof(Ecore_Con_Client)); | ||
2118 | EINA_SAFETY_ON_NULL_RETURN_VAL(cl, ECORE_CALLBACK_RENEW); | ||
2119 | |||
2120 | cl->host_server = svr; | ||
2121 | cl->client_addr = malloc(client_addr_len); | ||
2122 | if (!cl->client_addr) | ||
2123 | { | ||
2124 | free(cl); | ||
2125 | return ECORE_CALLBACK_RENEW; | ||
2126 | } | ||
2127 | cl->client_addr_len = client_addr_len; | ||
2128 | |||
2129 | memcpy(cl->client_addr, &client_addr, client_addr_len); | ||
2130 | ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); | ||
2131 | svr->clients = eina_list_append(svr->clients, cl); | ||
2132 | svr->client_count++; | ||
2133 | |||
2134 | ecore_con_event_client_add(cl); | ||
2135 | ecore_con_event_client_data(cl, buf, num, EINA_TRUE); | ||
2136 | |||
2137 | return ECORE_CALLBACK_RENEW; | ||
2138 | } | ||
2139 | |||
2140 | static void | ||
2141 | _ecore_con_svr_cl_read(Ecore_Con_Client *cl) | ||
2142 | { | ||
2143 | int num = 0; | ||
2144 | Eina_Bool lost_client = EINA_TRUE; | ||
2145 | unsigned char buf[READBUFSIZ]; | ||
2146 | |||
2147 | DBG("cl=%p", cl); | ||
2148 | |||
2149 | if (cl->handshaking) | ||
2150 | { | ||
2151 | /* add an extra handshake attempt just before read, even though | ||
2152 | * read also attempts to handshake, to try to finish sooner | ||
2153 | */ | ||
2154 | if (ecore_con_ssl_client_init(cl)) | ||
2155 | lost_client = EINA_FALSE; | ||
2156 | |||
2157 | _ecore_con_cl_timer_update(cl); | ||
2158 | } | ||
2159 | |||
2160 | if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade)) | ||
2161 | { | ||
2162 | num = read(cl->fd, buf, sizeof(buf)); | ||
2163 | /* 0 is not a valid return value for a tcp socket */ | ||
2164 | if ((num > 0) || ((num < 0) && ((errno == EAGAIN) || (errno == EINTR)))) | ||
2165 | lost_client = EINA_FALSE; | ||
2166 | else if (num < 0) | ||
2167 | ecore_con_event_client_error(cl, strerror(errno)); | ||
2168 | } | ||
2169 | else | ||
2170 | { | ||
2171 | num = ecore_con_ssl_client_read(cl, buf, sizeof(buf)); | ||
2172 | /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */ | ||
2173 | if (num >= 0) | ||
2174 | lost_client = EINA_FALSE; | ||
2175 | } | ||
2176 | |||
2177 | if ((!cl->delete_me) && (num > 0)) | ||
2178 | ecore_con_event_client_data(cl, buf, num, EINA_TRUE); | ||
2179 | |||
2180 | if (lost_client) | ||
2181 | { | ||
2182 | if (!cl->delete_me) | ||
2183 | ecore_con_event_client_del(cl); | ||
2184 | INF("Lost client %s", (cl->ip) ? cl->ip : ""); | ||
2185 | cl->dead = EINA_TRUE; | ||
2186 | if (cl->fd_handler) | ||
2187 | ecore_main_fd_handler_del(cl->fd_handler); | ||
2188 | |||
2189 | cl->fd_handler = NULL; | ||
2190 | return; | ||
2191 | } | ||
2192 | } | ||
2193 | |||
2194 | static Eina_Bool | ||
2195 | _ecore_con_svr_cl_handler(void *data, | ||
2196 | Ecore_Fd_Handler *fd_handler) | ||
2197 | { | ||
2198 | Ecore_Con_Client *cl; | ||
2199 | |||
2200 | cl = data; | ||
2201 | if (cl->dead) | ||
2202 | return ECORE_CALLBACK_RENEW; | ||
2203 | |||
2204 | if (cl->delete_me) | ||
2205 | return ECORE_CALLBACK_RENEW; | ||
2206 | |||
2207 | if (cl->handshaking && ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ | ECORE_FD_WRITE)) | ||
2208 | { | ||
2209 | if (ecore_con_ssl_client_init(cl)) | ||
2210 | { | ||
2211 | ERR("ssl handshaking failed!"); | ||
2212 | cl->handshaking = EINA_FALSE; | ||
2213 | cl->dead = EINA_TRUE; | ||
2214 | INF("Lost client %s", (cl->ip) ? cl->ip : ""); | ||
2215 | ecore_con_event_client_del(cl); | ||
2216 | } | ||
2217 | else if (!cl->ssl_state) | ||
2218 | ecore_con_event_client_add(cl); | ||
2219 | } | ||
2220 | else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) | ||
2221 | _ecore_con_svr_cl_read(cl); | ||
2222 | |||
2223 | else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) | ||
2224 | _ecore_con_client_flush(cl); | ||
2225 | |||
2226 | return ECORE_CALLBACK_RENEW; | ||
2227 | } | ||
2228 | |||
2229 | static void | ||
2230 | _ecore_con_server_flush(Ecore_Con_Server *svr) | ||
2231 | { | ||
2232 | int count, num; | ||
2233 | |||
2234 | #ifdef _WIN32 | ||
2235 | if (ecore_con_local_win32_server_flush(svr)) | ||
2236 | return; | ||
2237 | #endif | ||
2238 | |||
2239 | if ((!svr->buf) && svr->fd_handler) | ||
2240 | { | ||
2241 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
2242 | return; | ||
2243 | } | ||
2244 | |||
2245 | num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset; | ||
2246 | |||
2247 | /* check whether we need to write anything at all. | ||
2248 | * we must not write zero bytes with SSL_write() since it | ||
2249 | * causes undefined behaviour | ||
2250 | */ | ||
2251 | /* we thank Tommy[D] for needing to check negative buffer sizes | ||
2252 | * here because his system is amazing. | ||
2253 | */ | ||
2254 | if (num <= 0) return; | ||
2255 | |||
2256 | if (svr->handshaking) | ||
2257 | { | ||
2258 | DBG("Continuing ssl handshake"); | ||
2259 | if (ecore_con_ssl_server_init(svr)) | ||
2260 | _ecore_con_server_kill(svr); | ||
2261 | _ecore_con_server_timer_update(svr); | ||
2262 | return; | ||
2263 | } | ||
2264 | |||
2265 | if (!(svr->type & ECORE_CON_SSL)) | ||
2266 | count = write(svr->fd, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num); | ||
2267 | else | ||
2268 | count = ecore_con_ssl_server_write(svr, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num); | ||
2269 | |||
2270 | if (count < 0) | ||
2271 | { | ||
2272 | if ((errno != EAGAIN) && (errno != EINTR)) | ||
2273 | { | ||
2274 | ecore_con_event_server_error(svr, strerror(errno)); | ||
2275 | _ecore_con_server_kill(svr); | ||
2276 | } | ||
2277 | return; | ||
2278 | } | ||
2279 | |||
2280 | if (count) ecore_con_event_server_write(svr, count); | ||
2281 | svr->write_buf_offset += count; | ||
2282 | if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf)) | ||
2283 | { | ||
2284 | svr->write_buf_offset = 0; | ||
2285 | eina_binbuf_free(svr->buf); | ||
2286 | svr->buf = NULL; | ||
2287 | if (svr->fd_handler) | ||
2288 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
2289 | } | ||
2290 | else if ((count < num) && svr->fd_handler) | ||
2291 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); | ||
2292 | } | ||
2293 | |||
2294 | static void | ||
2295 | _ecore_con_client_flush(Ecore_Con_Client *cl) | ||
2296 | { | ||
2297 | int num, count = 0; | ||
2298 | |||
2299 | #ifdef _WIN32 | ||
2300 | if (ecore_con_local_win32_client_flush(cl)) | ||
2301 | return; | ||
2302 | #endif | ||
2303 | |||
2304 | if (!cl->buf && cl->fd_handler) | ||
2305 | { | ||
2306 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); | ||
2307 | return; | ||
2308 | } | ||
2309 | |||
2310 | if (cl->handshaking) | ||
2311 | { | ||
2312 | if (ecore_con_ssl_client_init(cl)) | ||
2313 | count = -1; | ||
2314 | |||
2315 | _ecore_con_cl_timer_update(cl); | ||
2316 | } | ||
2317 | |||
2318 | if (!count) | ||
2319 | { | ||
2320 | num = eina_binbuf_length_get(cl->buf) - cl->buf_offset; | ||
2321 | if (num <= 0) return; | ||
2322 | if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade)) | ||
2323 | count = write(cl->fd, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); | ||
2324 | else | ||
2325 | count = ecore_con_ssl_client_write(cl, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); | ||
2326 | } | ||
2327 | |||
2328 | if (count < 0) | ||
2329 | { | ||
2330 | if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me)) | ||
2331 | { | ||
2332 | ecore_con_event_client_error(cl, strerror(errno)); | ||
2333 | ecore_con_event_client_del(cl); | ||
2334 | cl->dead = EINA_TRUE; | ||
2335 | INF("Lost client %s", (cl->ip) ? cl->ip : ""); | ||
2336 | if (cl->fd_handler) | ||
2337 | ecore_main_fd_handler_del(cl->fd_handler); | ||
2338 | |||
2339 | cl->fd_handler = NULL; | ||
2340 | } | ||
2341 | |||
2342 | return; | ||
2343 | } | ||
2344 | |||
2345 | if (count) ecore_con_event_client_write(cl, count); | ||
2346 | cl->buf_offset += count; | ||
2347 | if (cl->buf_offset >= eina_binbuf_length_get(cl->buf)) | ||
2348 | { | ||
2349 | cl->buf_offset = 0; | ||
2350 | eina_binbuf_free(cl->buf); | ||
2351 | cl->buf = NULL; | ||
2352 | if (cl->fd_handler) | ||
2353 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); | ||
2354 | } | ||
2355 | else if ((count < num) && cl->fd_handler) | ||
2356 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); | ||
2357 | } | ||
2358 | |||
2359 | static void | ||
2360 | _ecore_con_event_client_add_free(Ecore_Con_Server *svr, | ||
2361 | void *ev) | ||
2362 | { | ||
2363 | Ecore_Con_Event_Client_Add *e; | ||
2364 | |||
2365 | e = ev; | ||
2366 | if (e->client) | ||
2367 | { | ||
2368 | e->client->event_count = eina_list_remove(e->client->event_count, e); | ||
2369 | if (e->client->host_server) | ||
2370 | { | ||
2371 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); | ||
2372 | if ((!svr->event_count) && (svr->delete_me)) | ||
2373 | _ecore_con_server_free(svr); | ||
2374 | } | ||
2375 | if ((!e->client->event_count) && (e->client->delete_me)) | ||
2376 | ecore_con_client_del(e->client); | ||
2377 | } | ||
2378 | |||
2379 | ecore_con_event_client_add_free(e); | ||
2380 | _ecore_con_event_count--; | ||
2381 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2382 | ecore_con_mempool_shutdown(); | ||
2383 | } | ||
2384 | |||
2385 | static void | ||
2386 | _ecore_con_event_client_del_free(Ecore_Con_Server *svr, | ||
2387 | void *ev) | ||
2388 | { | ||
2389 | Ecore_Con_Event_Client_Del *e; | ||
2390 | |||
2391 | e = ev; | ||
2392 | if (e->client) | ||
2393 | { | ||
2394 | e->client->event_count = eina_list_remove(e->client->event_count, e); | ||
2395 | if (e->client->host_server) | ||
2396 | { | ||
2397 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); | ||
2398 | if ((!svr->event_count) && (svr->delete_me)) | ||
2399 | _ecore_con_server_free(svr); | ||
2400 | } | ||
2401 | if ((!e->client->event_count) && (e->client->delete_me)) | ||
2402 | ecore_con_client_del(e->client); | ||
2403 | } | ||
2404 | ecore_con_event_client_del_free(e); | ||
2405 | _ecore_con_event_count--; | ||
2406 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2407 | ecore_con_mempool_shutdown(); | ||
2408 | } | ||
2409 | |||
2410 | static void | ||
2411 | _ecore_con_event_client_write_free(Ecore_Con_Server *svr, | ||
2412 | Ecore_Con_Event_Client_Write *e) | ||
2413 | { | ||
2414 | if (e->client) | ||
2415 | { | ||
2416 | e->client->event_count = eina_list_remove(e->client->event_count, e); | ||
2417 | if (e->client->host_server) | ||
2418 | { | ||
2419 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); | ||
2420 | if ((!svr->event_count) && (svr->delete_me)) | ||
2421 | _ecore_con_server_free(svr); | ||
2422 | } | ||
2423 | if (((!e->client->event_count) && (e->client->delete_me)) || | ||
2424 | ((e->client->host_server && | ||
2425 | ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || | ||
2426 | (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) | ||
2427 | ecore_con_client_del(e->client); | ||
2428 | } | ||
2429 | ecore_con_event_client_write_free(e); | ||
2430 | _ecore_con_event_count--; | ||
2431 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2432 | ecore_con_mempool_shutdown(); | ||
2433 | } | ||
2434 | |||
2435 | static void | ||
2436 | _ecore_con_event_client_data_free(Ecore_Con_Server *svr, | ||
2437 | void *ev) | ||
2438 | { | ||
2439 | Ecore_Con_Event_Client_Data *e; | ||
2440 | |||
2441 | e = ev; | ||
2442 | if (e->client) | ||
2443 | { | ||
2444 | e->client->event_count = eina_list_remove(e->client->event_count, e); | ||
2445 | if (e->client->host_server) | ||
2446 | { | ||
2447 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); | ||
2448 | } | ||
2449 | if ((!svr->event_count) && (svr->delete_me)) | ||
2450 | _ecore_con_server_free(svr); | ||
2451 | if (((!e->client->event_count) && (e->client->delete_me)) || | ||
2452 | ((e->client->host_server && | ||
2453 | ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || | ||
2454 | (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) | ||
2455 | ecore_con_client_del(e->client); | ||
2456 | } | ||
2457 | free(e->data); | ||
2458 | ecore_con_event_client_data_free(e); | ||
2459 | _ecore_con_event_count--; | ||
2460 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2461 | ecore_con_mempool_shutdown(); | ||
2462 | } | ||
2463 | |||
2464 | static void | ||
2465 | _ecore_con_event_server_add_free(void *data __UNUSED__, | ||
2466 | void *ev) | ||
2467 | { | ||
2468 | Ecore_Con_Event_Server_Add *e; | ||
2469 | |||
2470 | e = ev; | ||
2471 | if (e->server) | ||
2472 | { | ||
2473 | e->server->event_count = eina_list_remove(e->server->event_count, ev); | ||
2474 | if ((!e->server->event_count) && (e->server->delete_me)) | ||
2475 | _ecore_con_server_free(e->server); | ||
2476 | } | ||
2477 | ecore_con_event_server_add_free(e); | ||
2478 | _ecore_con_event_count--; | ||
2479 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2480 | ecore_con_mempool_shutdown(); | ||
2481 | } | ||
2482 | |||
2483 | static void | ||
2484 | _ecore_con_event_server_del_free(void *data __UNUSED__, | ||
2485 | void *ev) | ||
2486 | { | ||
2487 | Ecore_Con_Event_Server_Del *e; | ||
2488 | |||
2489 | e = ev; | ||
2490 | if (e->server) | ||
2491 | { | ||
2492 | e->server->event_count = eina_list_remove(e->server->event_count, ev); | ||
2493 | if ((!e->server->event_count) && (e->server->delete_me)) | ||
2494 | _ecore_con_server_free(e->server); | ||
2495 | } | ||
2496 | ecore_con_event_server_del_free(e); | ||
2497 | _ecore_con_event_count--; | ||
2498 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2499 | ecore_con_mempool_shutdown(); | ||
2500 | } | ||
2501 | |||
2502 | static void | ||
2503 | _ecore_con_event_server_write_free(void *data __UNUSED__, | ||
2504 | Ecore_Con_Event_Server_Write *e) | ||
2505 | { | ||
2506 | if (e->server) | ||
2507 | { | ||
2508 | e->server->event_count = eina_list_remove(e->server->event_count, e); | ||
2509 | if ((!e->server->event_count) && (e->server->delete_me)) | ||
2510 | _ecore_con_server_free(e->server); | ||
2511 | } | ||
2512 | |||
2513 | ecore_con_event_server_write_free(e); | ||
2514 | _ecore_con_event_count--; | ||
2515 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2516 | ecore_con_mempool_shutdown(); | ||
2517 | } | ||
2518 | |||
2519 | static void | ||
2520 | _ecore_con_event_server_data_free(void *data __UNUSED__, | ||
2521 | void *ev) | ||
2522 | { | ||
2523 | Ecore_Con_Event_Server_Data *e; | ||
2524 | |||
2525 | e = ev; | ||
2526 | if (e->server) | ||
2527 | { | ||
2528 | e->server->event_count = eina_list_remove(e->server->event_count, ev); | ||
2529 | if ((!e->server->event_count) && (e->server->delete_me)) | ||
2530 | _ecore_con_server_free(e->server); | ||
2531 | } | ||
2532 | |||
2533 | free(e->data); | ||
2534 | ecore_con_event_server_data_free(e); | ||
2535 | _ecore_con_event_count--; | ||
2536 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2537 | ecore_con_mempool_shutdown(); | ||
2538 | } | ||
2539 | |||
2540 | |||
2541 | static void | ||
2542 | _ecore_con_event_server_error_free(void *data __UNUSED__, Ecore_Con_Event_Server_Error *e) | ||
2543 | { | ||
2544 | if (e->server) | ||
2545 | { | ||
2546 | e->server->event_count = eina_list_remove(e->server->event_count, e); | ||
2547 | if ((!e->server->event_count) && (e->server->delete_me)) | ||
2548 | _ecore_con_server_free(e->server); | ||
2549 | } | ||
2550 | free(e->error); | ||
2551 | ecore_con_event_server_error_free(e); | ||
2552 | _ecore_con_event_count--; | ||
2553 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2554 | ecore_con_mempool_shutdown(); | ||
2555 | } | ||
2556 | |||
2557 | static void | ||
2558 | _ecore_con_event_client_error_free(Ecore_Con_Server *svr, Ecore_Con_Event_Client_Error *e) | ||
2559 | { | ||
2560 | if (e->client) | ||
2561 | { | ||
2562 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); | ||
2563 | if ((!e->client->event_count) && (e->client->delete_me)) | ||
2564 | _ecore_con_client_free(e->client); | ||
2565 | if (e->client->host_server) | ||
2566 | { | ||
2567 | e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); | ||
2568 | if ((!svr->event_count) && (svr->delete_me)) | ||
2569 | _ecore_con_server_free(svr); | ||
2570 | } | ||
2571 | } | ||
2572 | free(e->error); | ||
2573 | ecore_con_event_client_error_free(e); | ||
2574 | _ecore_con_event_count--; | ||
2575 | if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) | ||
2576 | ecore_con_mempool_shutdown(); | ||
2577 | } | ||
2578 | |||
2579 | static void | ||
2580 | _ecore_con_lookup_done(void *data, | ||
2581 | Ecore_Con_Info *infos) | ||
2582 | { | ||
2583 | Ecore_Con_Server *svr; | ||
2584 | Ecore_Con_Lookup *lk; | ||
2585 | |||
2586 | svr = data; | ||
2587 | lk = svr->data; | ||
2588 | |||
2589 | if (infos) | ||
2590 | lk->done_cb(infos->info.ai_canonname, infos->ip, | ||
2591 | infos->info.ai_addr, infos->info.ai_addrlen, | ||
2592 | (void *)lk->data); | ||
2593 | else | ||
2594 | lk->done_cb(NULL, NULL, NULL, 0, (void *)lk->data); | ||
2595 | |||
2596 | free(svr->name); | ||
2597 | free(lk); | ||
2598 | free(svr); | ||
2599 | } | ||
2600 | |||
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c b/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c new file mode 100644 index 0000000..206948b --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c | |||
@@ -0,0 +1,99 @@ | |||
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 | |||
10 | typedef struct _Ecore_Con_Mempool Ecore_Con_Mempool; | ||
11 | struct _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 | |||
33 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Add, ecore_con_event_client_add); | ||
34 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Del, ecore_con_event_client_del); | ||
35 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Write, ecore_con_event_client_write); | ||
36 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Data, ecore_con_event_client_data); | ||
37 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Error, ecore_con_event_server_error); | ||
38 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Error, ecore_con_event_client_error); | ||
39 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Add, ecore_con_event_server_add); | ||
40 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); | ||
41 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); | ||
42 | GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); | ||
43 | |||
44 | static Ecore_Con_Mempool *mempool_array[] = { | ||
45 | &ecore_con_event_client_add_mp, | ||
46 | &ecore_con_event_client_del_mp, | ||
47 | &ecore_con_event_client_write_mp, | ||
48 | &ecore_con_event_client_data_mp, | ||
49 | &ecore_con_event_server_error_mp, | ||
50 | &ecore_con_event_client_error_mp, | ||
51 | &ecore_con_event_server_add_mp, | ||
52 | &ecore_con_event_server_del_mp, | ||
53 | &ecore_con_event_server_write_mp, | ||
54 | &ecore_con_event_server_data_mp | ||
55 | }; | ||
56 | |||
57 | void | ||
58 | ecore_con_mempool_init(void) | ||
59 | { | ||
60 | const char *choice; | ||
61 | unsigned int i; | ||
62 | |||
63 | choice = getenv("EINA_MEMPOOL"); | ||
64 | if (!choice || !choice[0]) | ||
65 | choice = "chained_mempool"; | ||
66 | |||
67 | for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) | ||
68 | { | ||
69 | retry: | ||
70 | mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 64); | ||
71 | if (!mempool_array[i]->mp) | ||
72 | { | ||
73 | if (strcmp(choice, "pass_through") != 0) | ||
74 | { | ||
75 | ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice); | ||
76 | choice = "pass_through"; | ||
77 | goto retry; | ||
78 | } | ||
79 | else | ||
80 | { | ||
81 | ERR("Impossible to allocate mempool '%s' !", choice); | ||
82 | return ; | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | |||
88 | void | ||
89 | ecore_con_mempool_shutdown(void) | ||
90 | { | ||
91 | unsigned int i; | ||
92 | |||
93 | for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) | ||
94 | { | ||
95 | eina_mempool_del(mempool_array[i]->mp); | ||
96 | mempool_array[i]->mp = NULL; | ||
97 | } | ||
98 | } | ||
99 | |||
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c b/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c new file mode 100644 index 0000000..dd5a212 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c | |||
@@ -0,0 +1,628 @@ | |||
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 | |||
29 | typedef struct _Ecore_Con_FD Ecore_Con_FD; | ||
30 | typedef struct _Ecore_Con_CAres Ecore_Con_CAres; | ||
31 | |||
32 | struct _Ecore_Con_FD | ||
33 | { | ||
34 | Ecore_Fd_Handler *handler; | ||
35 | Ecore_Timer *timer; | ||
36 | int fd; | ||
37 | }; | ||
38 | |||
39 | struct _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 | |||
58 | static ares_channel info_channel; | ||
59 | static int info_init = 0; | ||
60 | static Eina_List *info_fds = NULL; | ||
61 | |||
62 | static void _ecore_con_info_ares_nameinfo(Ecore_Con_CAres *arg, | ||
63 | int status, | ||
64 | int timeouts, | ||
65 | char *node, | ||
66 | char *service); | ||
67 | static void _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg, | ||
68 | int status, | ||
69 | int timeouts, | ||
70 | struct hostent *hostent); | ||
71 | static Eina_Bool _ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf, | ||
72 | Ecore_Fd_Handler *fd_handler); | ||
73 | static Eina_Bool _ecore_con_info_cares_timeout_cb(void *data); | ||
74 | |||
75 | static void | ||
76 | _ecore_con_info_cares_state_cb(void *data, | ||
77 | ares_socket_t fd, | ||
78 | int readable, | ||
79 | int writable); | ||
80 | static int | ||
81 | _ecore_con_info_fds_search(const Ecore_Con_FD *fd1, | ||
82 | const Ecore_Con_FD *fd2); | ||
83 | |||
84 | int | ||
85 | ecore_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 | |||
109 | int | ||
110 | ecore_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 | |||
126 | int | ||
127 | ecore_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 | |||
149 | int | ||
150 | ecore_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 | |||
172 | int | ||
173 | ecore_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 | |||
195 | int | ||
196 | ecore_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 | |||
218 | int | ||
219 | ecore_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 | |||
241 | static 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 | |||
285 | EAPI int | ||
286 | ecore_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->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->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->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 | |||
346 | void | ||
347 | ecore_con_info_data_clear(void *info) | ||
348 | { | ||
349 | Ecore_Con_CAres *cares = info; | ||
350 | if (cares) cares->data = NULL; | ||
351 | } | ||
352 | |||
353 | static 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 | |||
360 | static 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 | |||
378 | static 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 | |||
385 | static 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 | |||
428 | static 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->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->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->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->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 | |||
578 | on_mem_error: | ||
579 | ERR("Not enough memory"); | ||
580 | |||
581 | on_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 | |||
590 | static 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 new file mode 100644 index 0000000..4ece6b0 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con_info.c | |||
@@ -0,0 +1,450 @@ | |||
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 | ||
24 | extern "C" | ||
25 | # endif | ||
26 | void *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 | |||
63 | typedef struct _CB_Data CB_Data; | ||
64 | |||
65 | struct _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 | |||
76 | static void _ecore_con_info_readdata(CB_Data *cbdata); | ||
77 | static void _ecore_con_info_slave_free(CB_Data *cbdata); | ||
78 | static Eina_Bool _ecore_con_info_data_handler(void *data, | ||
79 | Ecore_Fd_Handler *fd_handler); | ||
80 | static Eina_Bool _ecore_con_info_exit_handler(void *data, | ||
81 | int type __UNUSED__, | ||
82 | void *event); | ||
83 | |||
84 | static int info_init = 0; | ||
85 | static CB_Data *info_slaves = NULL; | ||
86 | |||
87 | int | ||
88 | ecore_con_info_init(void) | ||
89 | { | ||
90 | info_init++; | ||
91 | return info_init; | ||
92 | } | ||
93 | |||
94 | int | ||
95 | ecore_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 | |||
104 | int | ||
105 | ecore_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 | |||
123 | int | ||
124 | ecore_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 | |||
142 | int | ||
143 | ecore_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 | |||
161 | int | ||
162 | ecore_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 | |||
180 | int | ||
181 | ecore_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 | |||
199 | EAPI int | ||
200 | ecore_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 | int err; | ||
248 | |||
249 | eina_convert_itoa(svr->port, service); | ||
250 | /* CHILD */ | ||
251 | if (!getaddrinfo(svr->name, service, hints, &result) && result) | ||
252 | { | ||
253 | if (result->ai_canonname) | ||
254 | canonname_len = strlen(result->ai_canonname) + 1; | ||
255 | |||
256 | tosend_len = sizeof(Ecore_Con_Info) + result->ai_addrlen + | ||
257 | canonname_len; | ||
258 | |||
259 | tosend = alloca(tosend_len); | ||
260 | memset(tosend, 0, tosend_len); | ||
261 | |||
262 | container = (Ecore_Con_Info *)tosend; | ||
263 | container->size = tosend_len; | ||
264 | |||
265 | memcpy(&container->info, | ||
266 | result, | ||
267 | sizeof(struct addrinfo)); | ||
268 | memcpy(tosend + sizeof(Ecore_Con_Info), | ||
269 | result->ai_addr, | ||
270 | result->ai_addrlen); | ||
271 | if (result->ai_canonname) /* FIXME: else... */ | ||
272 | memcpy(tosend + sizeof(Ecore_Con_Info) + result->ai_addrlen, | ||
273 | result->ai_canonname, | ||
274 | canonname_len); | ||
275 | |||
276 | if (!getnameinfo(result->ai_addr, result->ai_addrlen, | ||
277 | hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), | ||
278 | NI_NUMERICHOST | NI_NUMERICSERV)) | ||
279 | { | ||
280 | memcpy(container->ip, hbuf, sizeof(container->ip)); | ||
281 | memcpy(container->service, sbuf, sizeof(container->service)); | ||
282 | } | ||
283 | |||
284 | err = write(fd[1], tosend, tosend_len); | ||
285 | } | ||
286 | |||
287 | if (result) | ||
288 | freeaddrinfo(result); | ||
289 | |||
290 | err = write(fd[1], "", 1); | ||
291 | close(fd[1]); | ||
292 | #if defined(__USE_ISOC99) && !defined(__UCLIBC__) | ||
293 | _Exit(0); | ||
294 | #else | ||
295 | _exit(0); | ||
296 | #endif | ||
297 | } | ||
298 | |||
299 | /* PARENT */ | ||
300 | cbdata->handler = | ||
301 | ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _ecore_con_info_exit_handler, | ||
302 | cbdata); | ||
303 | close(fd[1]); | ||
304 | if (!cbdata->handler) | ||
305 | { | ||
306 | ecore_main_fd_handler_del(cbdata->fdh); | ||
307 | free(cbdata); | ||
308 | close(fd[0]); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | info_slaves = (CB_Data *)eina_inlist_append(EINA_INLIST_GET( | ||
313 | info_slaves), | ||
314 | EINA_INLIST_GET(cbdata)); | ||
315 | svr->infos = eina_list_append(svr->infos, cbdata); | ||
316 | return 1; | ||
317 | } | ||
318 | |||
319 | void | ||
320 | ecore_con_info_data_clear(void *info) | ||
321 | { | ||
322 | CB_Data *cbdata = info; | ||
323 | cbdata->data = NULL; | ||
324 | } | ||
325 | |||
326 | static void | ||
327 | _ecore_con_info_readdata(CB_Data *cbdata) | ||
328 | { | ||
329 | Ecore_Con_Info container; | ||
330 | Ecore_Con_Info *recv_info; | ||
331 | unsigned char *torecv; | ||
332 | int torecv_len; | ||
333 | |||
334 | ssize_t size; | ||
335 | |||
336 | size = read(ecore_main_fd_handler_fd_get(cbdata->fdh), &container, | ||
337 | sizeof(Ecore_Con_Info)); | ||
338 | if (size == sizeof(Ecore_Con_Info)) | ||
339 | { | ||
340 | torecv_len = container.size; | ||
341 | torecv = malloc(torecv_len); | ||
342 | |||
343 | memcpy(torecv, &container, sizeof(Ecore_Con_Info)); | ||
344 | |||
345 | size = read(ecore_main_fd_handler_fd_get(cbdata->fdh), | ||
346 | torecv + sizeof(Ecore_Con_Info), | ||
347 | torecv_len - sizeof(Ecore_Con_Info)); | ||
348 | if ((size > 0) && | ||
349 | ((size_t)size == torecv_len - sizeof(Ecore_Con_Info))) | ||
350 | { | ||
351 | recv_info = (Ecore_Con_Info *)torecv; | ||
352 | |||
353 | recv_info->info.ai_addr = | ||
354 | (struct sockaddr *)(torecv + sizeof(Ecore_Con_Info)); | ||
355 | if ((size_t)torecv_len != | ||
356 | (sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen)) | ||
357 | recv_info->info.ai_canonname = (char *) | ||
358 | (torecv + sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen); | ||
359 | else | ||
360 | recv_info->info.ai_canonname = NULL; | ||
361 | |||
362 | recv_info->info.ai_next = NULL; | ||
363 | |||
364 | if (cbdata->data) | ||
365 | { | ||
366 | cbdata->cb_done(cbdata->data, recv_info); | ||
367 | ecore_con_server_infos_del(cbdata->data, cbdata); | ||
368 | } | ||
369 | |||
370 | free(torecv); | ||
371 | } | ||
372 | else | ||
373 | { | ||
374 | if (cbdata->data) | ||
375 | { | ||
376 | cbdata->cb_done(cbdata->data, NULL); | ||
377 | ecore_con_server_infos_del(cbdata->data, cbdata); | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | else | ||
382 | { | ||
383 | if (cbdata->data) | ||
384 | { | ||
385 | ecore_con_event_server_error(cbdata->data, strerror(errno)); | ||
386 | cbdata->cb_done(cbdata->data, NULL); | ||
387 | ecore_con_server_infos_del(cbdata->data, cbdata); | ||
388 | } | ||
389 | } | ||
390 | |||
391 | cbdata->cb_done = NULL; | ||
392 | } | ||
393 | |||
394 | static void | ||
395 | _ecore_con_info_slave_free(CB_Data *cbdata) | ||
396 | { | ||
397 | info_slaves = (CB_Data *)eina_inlist_remove(EINA_INLIST_GET(info_slaves), | ||
398 | EINA_INLIST_GET(cbdata)); | ||
399 | ecore_main_fd_handler_del(cbdata->fdh); | ||
400 | ecore_event_handler_del(cbdata->handler); | ||
401 | close(ecore_main_fd_handler_fd_get(cbdata->fdh)); | ||
402 | if (cbdata->data) ecore_con_server_infos_del(cbdata->data, cbdata); | ||
403 | free(cbdata); | ||
404 | } | ||
405 | |||
406 | static Eina_Bool | ||
407 | _ecore_con_info_data_handler(void *data, | ||
408 | Ecore_Fd_Handler *fd_handler) | ||
409 | { | ||
410 | CB_Data *cbdata; | ||
411 | |||
412 | cbdata = data; | ||
413 | if (cbdata->cb_done) | ||
414 | { | ||
415 | if (ecore_main_fd_handler_active_get(fd_handler, | ||
416 | ECORE_FD_READ)) | ||
417 | _ecore_con_info_readdata(cbdata); | ||
418 | else | ||
419 | { | ||
420 | if (cbdata->data) | ||
421 | { | ||
422 | cbdata->cb_done(cbdata->data, NULL); | ||
423 | cbdata->cb_done = NULL; | ||
424 | ecore_con_server_infos_del(cbdata->data, cbdata); | ||
425 | } | ||
426 | } | ||
427 | } | ||
428 | |||
429 | _ecore_con_info_slave_free(cbdata); | ||
430 | return ECORE_CALLBACK_CANCEL; | ||
431 | } | ||
432 | |||
433 | static Eina_Bool | ||
434 | _ecore_con_info_exit_handler(void *data, | ||
435 | int type __UNUSED__, | ||
436 | void *event) | ||
437 | { | ||
438 | CB_Data *cbdata; | ||
439 | Ecore_Exe_Event_Del *ev; | ||
440 | |||
441 | ev = event; | ||
442 | cbdata = data; | ||
443 | if (cbdata->pid != ev->pid) | ||
444 | return ECORE_CALLBACK_RENEW; | ||
445 | |||
446 | return ECORE_CALLBACK_CANCEL; /* FIXME: Woot ??? */ | ||
447 | _ecore_con_info_slave_free(cbdata); | ||
448 | return ECORE_CALLBACK_CANCEL; | ||
449 | } | ||
450 | |||
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_local.c b/libraries/ecore/src/lib/ecore_con/ecore_con_local.c new file mode 100644 index 0000000..f02cc1f --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con_local.c | |||
@@ -0,0 +1,317 @@ | |||
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 | |||
37 | static int _ecore_con_local_init_count = 0; | ||
38 | |||
39 | int | ||
40 | ecore_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 | |||
48 | int | ||
49 | ecore_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 | |||
57 | int | ||
58 | ecore_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 | |||
167 | int | ||
168 | ecore_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); | ||
244 | start: | ||
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 | |||
311 | error_umask: | ||
312 | umask(pmode); | ||
313 | error: | ||
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 new file mode 100644 index 0000000..858daa5 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c | |||
@@ -0,0 +1,769 @@ | |||
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 | |||
16 | static int _ecore_con_local_init_count = 0; | ||
17 | |||
18 | int | ||
19 | ecore_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 | |||
27 | int | ||
28 | ecore_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 | |||
37 | static 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 | if (!cl->delete_me) | ||
79 | ecore_con_event_client_del(cl); | ||
80 | cl->dead = EINA_TRUE; | ||
81 | return ECORE_CALLBACK_CANCEL; | ||
82 | } | ||
83 | |||
84 | if (cl->host_server->want_write) | ||
85 | ecore_con_local_win32_client_flush(cl); | ||
86 | |||
87 | ecore_main_win32_handler_del(wh); | ||
88 | |||
89 | return ECORE_CALLBACK_DONE; | ||
90 | } | ||
91 | |||
92 | static Eina_Bool | ||
93 | _ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handler *wh) | ||
94 | { | ||
95 | Ecore_Con_Client *cl; | ||
96 | #if 0 | ||
97 | char *msg; | ||
98 | #endif | ||
99 | |||
100 | cl = (Ecore_Con_Client *)data; | ||
101 | |||
102 | if (!ResetEvent(cl->host_server->event_peek)) | ||
103 | return ECORE_CALLBACK_RENEW; | ||
104 | |||
105 | #if 0 | ||
106 | msg = evil_last_error_get(); | ||
107 | if (msg) | ||
108 | { | ||
109 | ecore_con_event_server_error(cl->host_server, msg); | ||
110 | free(msg); | ||
111 | } | ||
112 | #endif | ||
113 | if (!cl->host_server->delete_me) | ||
114 | ecore_con_event_server_del(cl->host_server); | ||
115 | cl->host_server->dead = EINA_TRUE; | ||
116 | return ECORE_CALLBACK_CANCEL; | ||
117 | |||
118 | ecore_main_win32_handler_del(wh); | ||
119 | |||
120 | return ECORE_CALLBACK_DONE; | ||
121 | } | ||
122 | |||
123 | static Eina_Bool | ||
124 | _ecore_con_local_win32_client_peek_server_handler(void *data, Ecore_Win32_Handler *wh) | ||
125 | { | ||
126 | Ecore_Con_Server *svr; | ||
127 | #if 0 | ||
128 | char *msg; | ||
129 | #endif | ||
130 | |||
131 | svr = (Ecore_Con_Server *)data; | ||
132 | |||
133 | if (!ResetEvent(svr->event_peek)) | ||
134 | return ECORE_CALLBACK_RENEW; | ||
135 | #if 0 | ||
136 | msg = evil_last_error_get(); | ||
137 | if (msg) | ||
138 | { | ||
139 | ecore_con_event_server_error(svr, msg); | ||
140 | free(msg); | ||
141 | } | ||
142 | #endif | ||
143 | if (!svr->delete_me) | ||
144 | ecore_con_event_server_del(svr); | ||
145 | svr->dead = EINA_TRUE; | ||
146 | return ECORE_CALLBACK_CANCEL; | ||
147 | |||
148 | ecore_main_win32_handler_del(wh); | ||
149 | |||
150 | return ECORE_CALLBACK_DONE; | ||
151 | } | ||
152 | |||
153 | static Eina_Bool | ||
154 | _ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handler *wh) | ||
155 | { | ||
156 | Ecore_Con_Server *svr; | ||
157 | void *buf; | ||
158 | DWORD n; | ||
159 | Eina_Bool broken_pipe = EINA_FALSE; | ||
160 | |||
161 | svr = (Ecore_Con_Server *)data; | ||
162 | |||
163 | if (!ResetEvent(svr->event_read)) | ||
164 | return ECORE_CALLBACK_RENEW; | ||
165 | |||
166 | buf = malloc(svr->nbr_bytes); | ||
167 | if (!buf) | ||
168 | return ECORE_CALLBACK_RENEW; | ||
169 | |||
170 | if (ReadFile(svr->pipe, buf, svr->nbr_bytes, &n, NULL)) | ||
171 | { | ||
172 | if (!svr->delete_me) | ||
173 | ecore_con_event_server_data(svr, buf, svr->nbr_bytes, EINA_FALSE); | ||
174 | svr->want_write = 1; | ||
175 | } | ||
176 | else | ||
177 | { | ||
178 | if (GetLastError() == ERROR_BROKEN_PIPE) | ||
179 | broken_pipe = EINA_TRUE; | ||
180 | } | ||
181 | |||
182 | if (broken_pipe) | ||
183 | { | ||
184 | #if 0 | ||
185 | char *msg; | ||
186 | |||
187 | msg = evil_last_error_get(); | ||
188 | if (msg) | ||
189 | { | ||
190 | ecore_con_event_server_error(svr, msg); | ||
191 | free(msg); | ||
192 | } | ||
193 | #endif | ||
194 | if (!svr->delete_me) | ||
195 | ecore_con_event_server_del(svr); | ||
196 | svr->dead = EINA_TRUE; | ||
197 | return ECORE_CALLBACK_CANCEL; | ||
198 | } | ||
199 | |||
200 | if (svr->want_write) | ||
201 | ecore_con_local_win32_server_flush(svr); | ||
202 | |||
203 | ecore_main_win32_handler_del(wh); | ||
204 | |||
205 | return ECORE_CALLBACK_DONE; | ||
206 | } | ||
207 | |||
208 | /* thread to read data sent by the server to the client */ | ||
209 | static unsigned int __stdcall | ||
210 | _ecore_con_local_win32_client_read_server_thread(void *data) | ||
211 | { | ||
212 | Ecore_Con_Server *svr; | ||
213 | DWORD nbr_bytes = 0; | ||
214 | |||
215 | svr = (Ecore_Con_Server *)data; | ||
216 | |||
217 | svr->read_stopped = EINA_FALSE; | ||
218 | |||
219 | while (!svr->read_stop) | ||
220 | { | ||
221 | if (PeekNamedPipe(svr->pipe, NULL, 0, NULL, &nbr_bytes, NULL)) | ||
222 | { | ||
223 | if (nbr_bytes <= 0) | ||
224 | continue; | ||
225 | |||
226 | svr->nbr_bytes = nbr_bytes; | ||
227 | if (!SetEvent(svr->event_read)) | ||
228 | continue; | ||
229 | } | ||
230 | else | ||
231 | { | ||
232 | if (GetLastError() == ERROR_BROKEN_PIPE) | ||
233 | { | ||
234 | if (!SetEvent(svr->event_peek)) | ||
235 | continue; | ||
236 | break; | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | |||
241 | printf(" ### %s\n", __FUNCTION__); | ||
242 | svr->read_stopped = EINA_TRUE; | ||
243 | _endthreadex(0); | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | /* thread to read data sent by the client to the server */ | ||
248 | static unsigned int __stdcall | ||
249 | _ecore_con_local_win32_server_read_client_thread(void *data) | ||
250 | { | ||
251 | Ecore_Con_Client *cl; | ||
252 | DWORD nbr_bytes = 0; | ||
253 | |||
254 | cl = (Ecore_Con_Client *)data; | ||
255 | |||
256 | cl->host_server->read_stopped = EINA_FALSE; | ||
257 | |||
258 | while (!cl->host_server->read_stop) | ||
259 | { | ||
260 | if (PeekNamedPipe(cl->host_server->pipe, NULL, 0, NULL, &nbr_bytes, NULL)) | ||
261 | { | ||
262 | if (nbr_bytes <= 0) | ||
263 | continue; | ||
264 | |||
265 | cl->host_server->nbr_bytes = nbr_bytes; | ||
266 | if (!SetEvent(cl->host_server->event_read)) | ||
267 | continue; | ||
268 | } | ||
269 | else | ||
270 | { | ||
271 | if (GetLastError() == ERROR_BROKEN_PIPE) | ||
272 | { | ||
273 | if (!SetEvent(cl->host_server->event_peek)) | ||
274 | continue; | ||
275 | break; | ||
276 | } | ||
277 | } | ||
278 | } | ||
279 | |||
280 | printf(" ### %s\n", __FUNCTION__); | ||
281 | cl->host_server->read_stopped = EINA_TRUE; | ||
282 | _endthreadex(0); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static Eina_Bool | ||
287 | _ecore_con_local_win32_client_add(void *data, Ecore_Win32_Handler *wh) | ||
288 | { | ||
289 | Ecore_Con_Client *cl = NULL; | ||
290 | Ecore_Con_Server *svr; | ||
291 | Ecore_Win32_Handler *handler_read; | ||
292 | Ecore_Win32_Handler *handler_peek; | ||
293 | |||
294 | svr = (Ecore_Con_Server *)data; | ||
295 | |||
296 | if (!svr->pipe) | ||
297 | return ECORE_CALLBACK_CANCEL; | ||
298 | |||
299 | if (svr->dead) | ||
300 | return ECORE_CALLBACK_CANCEL; | ||
301 | |||
302 | if (svr->delete_me) | ||
303 | return ECORE_CALLBACK_CANCEL; | ||
304 | |||
305 | if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) && | ||
306 | (svr->client_count >= (unsigned int)svr->client_limit)) | ||
307 | return ECORE_CALLBACK_CANCEL; | ||
308 | |||
309 | cl = calloc(1, sizeof(Ecore_Con_Client)); | ||
310 | if (!cl) | ||
311 | { | ||
312 | ERR("allocation failed"); | ||
313 | return ECORE_CALLBACK_CANCEL; | ||
314 | } | ||
315 | |||
316 | cl->host_server = svr; | ||
317 | ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); | ||
318 | |||
319 | cl->host_server->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); | ||
320 | if (!cl->host_server->event_read) | ||
321 | { | ||
322 | ERR("Can not create event read"); | ||
323 | goto free_cl; | ||
324 | } | ||
325 | |||
326 | handler_read = ecore_main_win32_handler_add(cl->host_server->event_read, | ||
327 | _ecore_con_local_win32_server_read_client_handler, | ||
328 | cl); | ||
329 | if (!handler_read) | ||
330 | { | ||
331 | ERR("Can not create handler read"); | ||
332 | goto close_event_read; | ||
333 | } | ||
334 | |||
335 | cl->host_server->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); | ||
336 | if (!cl->host_server->event_peek) | ||
337 | { | ||
338 | ERR("Can not create event peek"); | ||
339 | goto del_handler_read; | ||
340 | } | ||
341 | |||
342 | handler_peek = ecore_main_win32_handler_add(cl->host_server->event_peek, | ||
343 | _ecore_con_local_win32_server_peek_client_handler, | ||
344 | cl); | ||
345 | if (!handler_peek) | ||
346 | { | ||
347 | ERR("Can not create handler peek"); | ||
348 | goto close_event_peek; | ||
349 | } | ||
350 | |||
351 | cl->host_server->read_stopped = EINA_TRUE; | ||
352 | cl->host_server->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_server_read_client_thread, cl, CREATE_SUSPENDED, NULL); | ||
353 | if (!cl->host_server->thread_read) | ||
354 | { | ||
355 | ERR("Can not launch thread"); | ||
356 | goto del_handler_peek; | ||
357 | } | ||
358 | |||
359 | svr->clients = eina_list_append(svr->clients, cl); | ||
360 | svr->client_count++; | ||
361 | |||
362 | if (!cl->delete_me) | ||
363 | ecore_con_event_client_add(cl); | ||
364 | |||
365 | ecore_main_win32_handler_del(wh); | ||
366 | |||
367 | ResumeThread(cl->host_server->thread_read); | ||
368 | return ECORE_CALLBACK_DONE; | ||
369 | |||
370 | del_handler_peek: | ||
371 | ecore_main_win32_handler_del(handler_peek); | ||
372 | close_event_peek: | ||
373 | CloseHandle(cl->host_server->event_peek); | ||
374 | del_handler_read: | ||
375 | ecore_main_win32_handler_del(handler_read); | ||
376 | close_event_read: | ||
377 | CloseHandle(cl->host_server->event_read); | ||
378 | free_cl: | ||
379 | free(cl); | ||
380 | |||
381 | return ECORE_CALLBACK_CANCEL; | ||
382 | } | ||
383 | |||
384 | static unsigned int __stdcall | ||
385 | _ecore_con_local_win32_listening(void *data) | ||
386 | { | ||
387 | Ecore_Con_Server *svr; | ||
388 | BOOL res; | ||
389 | |||
390 | svr = (Ecore_Con_Server *)data; | ||
391 | |||
392 | while (1) | ||
393 | { | ||
394 | res = ConnectNamedPipe(svr->pipe, NULL); | ||
395 | if (!res) | ||
396 | { | ||
397 | ERR("Opening the connection to the client failed"); | ||
398 | CloseHandle(svr->pipe); | ||
399 | svr->pipe = NULL; | ||
400 | } | ||
401 | break; | ||
402 | } | ||
403 | |||
404 | DBG("Client connected"); | ||
405 | |||
406 | printf(" ### %s\n", __FUNCTION__); | ||
407 | _endthreadex(0); | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | Eina_Bool | ||
412 | ecore_con_local_listen(Ecore_Con_Server *svr) | ||
413 | { | ||
414 | char buf[256]; | ||
415 | HANDLE thread_listening; | ||
416 | Ecore_Win32_Handler *handler; | ||
417 | |||
418 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) | ||
419 | { | ||
420 | ERR("Your system does not support abstract sockets!"); | ||
421 | return EINA_FALSE; | ||
422 | } | ||
423 | |||
424 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) | ||
425 | snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); | ||
426 | else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) | ||
427 | { | ||
428 | const char *computername; | ||
429 | |||
430 | computername = getenv("CoMPUTERNAME"); | ||
431 | snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); | ||
432 | } | ||
433 | |||
434 | svr->path = strdup(buf); | ||
435 | if (!svr->path) | ||
436 | { | ||
437 | ERR("Allocation failed"); | ||
438 | return EINA_FALSE; | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * synchronuous | ||
443 | * block mode | ||
444 | * wait mode | ||
445 | */ | ||
446 | svr->pipe = CreateNamedPipe(svr->path, | ||
447 | PIPE_ACCESS_DUPLEX, | ||
448 | PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, | ||
449 | PIPE_UNLIMITED_INSTANCES, | ||
450 | BUFSIZE, | ||
451 | BUFSIZE, | ||
452 | 5000, | ||
453 | NULL); | ||
454 | if (svr->pipe == INVALID_HANDLE_VALUE) | ||
455 | { | ||
456 | ERR("Creation of the named pipe failed"); | ||
457 | goto free_path; | ||
458 | } | ||
459 | |||
460 | /* | ||
461 | * We use ConnectNamedPipe() to wait for a client to connect. | ||
462 | * As the function is blocking, to let the main loop continuing | ||
463 | * its iterations, we call ConnectNamedPipe() in a thread | ||
464 | */ | ||
465 | thread_listening = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_listening, svr, CREATE_SUSPENDED, NULL); | ||
466 | if (!thread_listening) | ||
467 | { | ||
468 | ERR("Creation of the listening thread failed"); | ||
469 | goto close_pipe; | ||
470 | } | ||
471 | |||
472 | handler = ecore_main_win32_handler_add(thread_listening, | ||
473 | _ecore_con_local_win32_client_add, | ||
474 | svr); | ||
475 | if (!handler) | ||
476 | { | ||
477 | ERR("Creation of the client add handler failed"); | ||
478 | goto del_handler; | ||
479 | } | ||
480 | |||
481 | svr->read_stopped = EINA_TRUE; | ||
482 | ResumeThread(thread_listening); | ||
483 | |||
484 | return EINA_TRUE; | ||
485 | |||
486 | del_handler: | ||
487 | ecore_main_win32_handler_del(handler); | ||
488 | close_pipe: | ||
489 | CloseHandle(svr->pipe); | ||
490 | free_path: | ||
491 | free(svr->path); | ||
492 | svr->path = NULL; | ||
493 | |||
494 | return EINA_FALSE; | ||
495 | } | ||
496 | |||
497 | void | ||
498 | ecore_con_local_win32_server_del(Ecore_Con_Server *svr) | ||
499 | { | ||
500 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) | ||
501 | return; | ||
502 | |||
503 | if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && | ||
504 | ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) | ||
505 | return; | ||
506 | |||
507 | svr->read_stop = 1; | ||
508 | while (!svr->read_stopped) | ||
509 | Sleep(100); | ||
510 | |||
511 | if (svr->event_peek) | ||
512 | CloseHandle(svr->event_peek); | ||
513 | svr->event_peek = NULL; | ||
514 | if (svr->event_read) | ||
515 | CloseHandle(svr->event_read); | ||
516 | svr->event_read = NULL; | ||
517 | free(svr->path); | ||
518 | svr->path = NULL; | ||
519 | if (svr->pipe) | ||
520 | CloseHandle(svr->pipe); | ||
521 | svr->pipe = NULL; | ||
522 | } | ||
523 | |||
524 | void | ||
525 | ecore_con_local_win32_client_del(Ecore_Con_Client *cl) | ||
526 | { | ||
527 | if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) | ||
528 | return; | ||
529 | |||
530 | if (((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && | ||
531 | ((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) | ||
532 | return; | ||
533 | |||
534 | cl->host_server->read_stop = 1; | ||
535 | while (!cl->host_server->read_stopped) | ||
536 | Sleep(100); | ||
537 | |||
538 | if (cl->host_server->event_peek) | ||
539 | CloseHandle(cl->host_server->event_peek); | ||
540 | cl->host_server->event_peek = NULL; | ||
541 | if (cl->host_server->event_read) | ||
542 | CloseHandle(cl->host_server->event_read); | ||
543 | cl->host_server->event_read = NULL; | ||
544 | free(cl->host_server->path); | ||
545 | cl->host_server->path = NULL; | ||
546 | if (cl->host_server->pipe) | ||
547 | CloseHandle(cl->host_server->pipe); | ||
548 | cl->host_server->pipe = NULL; | ||
549 | } | ||
550 | |||
551 | Eina_Bool | ||
552 | ecore_con_local_connect(Ecore_Con_Server *svr, | ||
553 | Eina_Bool (*cb_done)(void *data, | ||
554 | Ecore_Fd_Handler *fd_handler)) | ||
555 | { | ||
556 | char buf[256]; | ||
557 | Ecore_Win32_Handler *handler_read; | ||
558 | Ecore_Win32_Handler *handler_peek; | ||
559 | |||
560 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) | ||
561 | { | ||
562 | ERR("Your system does not support abstract sockets!"); | ||
563 | return EINA_FALSE; | ||
564 | } | ||
565 | |||
566 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) | ||
567 | snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); | ||
568 | else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) | ||
569 | { | ||
570 | const char *computername; | ||
571 | |||
572 | computername = getenv("COMPUTERNAME"); | ||
573 | snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); | ||
574 | } | ||
575 | |||
576 | while (1) | ||
577 | { | ||
578 | svr->pipe = CreateFile(buf, | ||
579 | GENERIC_READ | GENERIC_WRITE, | ||
580 | 0, | ||
581 | NULL, | ||
582 | OPEN_EXISTING, | ||
583 | 0, | ||
584 | NULL); | ||
585 | if (svr->pipe != INVALID_HANDLE_VALUE) | ||
586 | break; | ||
587 | |||
588 | /* if pipe not busy, we exit */ | ||
589 | if (GetLastError() != ERROR_PIPE_BUSY) | ||
590 | { | ||
591 | ERR("Connection to a server failed"); | ||
592 | return EINA_FALSE; | ||
593 | } | ||
594 | |||
595 | /* pipe busy, so we wait for it */ | ||
596 | if (!WaitNamedPipe(buf, NMPWAIT_WAIT_FOREVER)) | ||
597 | { | ||
598 | ERR("Can not wait for a server"); | ||
599 | goto close_pipe; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | svr->path = strdup(buf); | ||
604 | if (!svr->path) | ||
605 | { | ||
606 | ERR("Allocation failed"); | ||
607 | goto close_pipe; | ||
608 | } | ||
609 | |||
610 | svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); | ||
611 | if (!svr->event_read) | ||
612 | { | ||
613 | ERR("Can not create event read"); | ||
614 | goto free_path; | ||
615 | } | ||
616 | |||
617 | handler_read = ecore_main_win32_handler_add(svr->event_read, | ||
618 | _ecore_con_local_win32_client_read_server_handler, | ||
619 | svr); | ||
620 | if (!handler_read) | ||
621 | { | ||
622 | ERR("Can not create handler read"); | ||
623 | goto close_event_read; | ||
624 | } | ||
625 | |||
626 | svr->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); | ||
627 | if (!svr->event_peek) | ||
628 | { | ||
629 | ERR("Can not create event peek"); | ||
630 | goto del_handler_read; | ||
631 | } | ||
632 | |||
633 | handler_peek = ecore_main_win32_handler_add(svr->event_peek, | ||
634 | _ecore_con_local_win32_client_peek_server_handler, | ||
635 | svr); | ||
636 | if (!handler_peek) | ||
637 | { | ||
638 | ERR("Can not create handler peek"); | ||
639 | goto close_event_peek; | ||
640 | } | ||
641 | |||
642 | svr->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_client_read_server_thread, svr, CREATE_SUSPENDED, NULL); | ||
643 | if (!svr->thread_read) | ||
644 | { | ||
645 | ERR("Can not launch thread"); | ||
646 | goto del_handler_peek; | ||
647 | } | ||
648 | |||
649 | if (!svr->delete_me) ecore_con_event_server_add(svr); | ||
650 | |||
651 | ResumeThread(svr->thread_read); | ||
652 | |||
653 | return EINA_TRUE; | ||
654 | |||
655 | del_handler_peek: | ||
656 | ecore_main_win32_handler_del(handler_peek); | ||
657 | close_event_peek: | ||
658 | CloseHandle(svr->event_peek); | ||
659 | del_handler_read: | ||
660 | ecore_main_win32_handler_del(handler_read); | ||
661 | close_event_read: | ||
662 | CloseHandle(svr->event_read); | ||
663 | free_path: | ||
664 | free(svr->path); | ||
665 | svr->path = NULL; | ||
666 | close_pipe: | ||
667 | CloseHandle(svr->pipe); | ||
668 | |||
669 | return EINA_FALSE; | ||
670 | } | ||
671 | |||
672 | Eina_Bool | ||
673 | ecore_con_local_win32_server_flush(Ecore_Con_Server *svr) | ||
674 | { | ||
675 | int num; | ||
676 | BOOL res; | ||
677 | DWORD written; | ||
678 | |||
679 | /* This check should never be true */ | ||
680 | if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) | ||
681 | return EINA_TRUE; | ||
682 | |||
683 | if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && | ||
684 | ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) | ||
685 | return EINA_FALSE; | ||
686 | |||
687 | num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset; | ||
688 | if (num <= 0) return EINA_TRUE; | ||
689 | |||
690 | res = WriteFile(svr->pipe, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num, &written, NULL); | ||
691 | if (!res) | ||
692 | { | ||
693 | char *msg; | ||
694 | |||
695 | msg = evil_last_error_get(); | ||
696 | if (msg) | ||
697 | { | ||
698 | ecore_con_event_server_error(svr, msg); | ||
699 | free(msg); | ||
700 | } | ||
701 | if (!svr->delete_me) | ||
702 | ecore_con_event_server_del(svr); | ||
703 | svr->dead = EINA_TRUE; | ||
704 | } | ||
705 | |||
706 | svr->write_buf_offset += written; | ||
707 | if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf)) | ||
708 | { | ||
709 | svr->write_buf_offset = 0; | ||
710 | eina_binbuf_free(svr->buf); | ||
711 | svr->buf = NULL; | ||
712 | svr->want_write = 0; | ||
713 | } | ||
714 | else if (written < (DWORD)num) | ||
715 | svr->want_write = 1; | ||
716 | |||
717 | return EINA_TRUE; | ||
718 | } | ||
719 | |||
720 | Eina_Bool | ||
721 | ecore_con_local_win32_client_flush(Ecore_Con_Client *cl) | ||
722 | { | ||
723 | Ecore_Con_Type type; | ||
724 | int num; | ||
725 | BOOL res; | ||
726 | DWORD written; | ||
727 | |||
728 | type = cl->host_server->type & ECORE_CON_TYPE; | ||
729 | |||
730 | /* This check should never be true */ | ||
731 | if (type == ECORE_CON_LOCAL_ABSTRACT) | ||
732 | return EINA_TRUE; | ||
733 | |||
734 | if ((type != ECORE_CON_LOCAL_USER) && | ||
735 | (type != ECORE_CON_LOCAL_SYSTEM)) | ||
736 | return EINA_FALSE; | ||
737 | |||
738 | num = eina_binbuf_length_get(cl->buf) - cl->buf_offset; | ||
739 | if (num <= 0) return EINA_TRUE; | ||
740 | |||
741 | res = WriteFile(cl->host_server->pipe, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num, &written, NULL); | ||
742 | if (!res) | ||
743 | { | ||
744 | char *msg; | ||
745 | |||
746 | msg = evil_last_error_get(); | ||
747 | if (msg) | ||
748 | { | ||
749 | ecore_con_event_client_error(cl, msg); | ||
750 | free(msg); | ||
751 | } | ||
752 | if (!cl->delete_me) | ||
753 | ecore_con_event_client_del(cl); | ||
754 | cl->dead = EINA_TRUE; | ||
755 | } | ||
756 | |||
757 | cl->buf_offset += written; | ||
758 | if (cl->buf_offset >= eina_binbuf_length_get(cl->buf)) | ||
759 | { | ||
760 | cl->buf_offset = 0; | ||
761 | eina_binbuf_free(cl->buf); | ||
762 | cl->buf = NULL; | ||
763 | cl->host_server->want_write = 0; | ||
764 | } | ||
765 | else if (written < (DWORD)num) | ||
766 | cl->host_server->want_write = 1; | ||
767 | |||
768 | return EINA_TRUE; | ||
769 | } | ||
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_private.h b/libraries/ecore/src/lib/ecore_con/ecore_con_private.h new file mode 100644 index 0000000..f601465 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con_private.h | |||
@@ -0,0 +1,321 @@ | |||
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 | |||
25 | extern 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 | |||
57 | typedef struct _Ecore_Con_Lookup Ecore_Con_Lookup; | ||
58 | typedef struct _Ecore_Con_Info Ecore_Con_Info; | ||
59 | |||
60 | typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos); | ||
61 | |||
62 | typedef enum _Ecore_Con_State | ||
63 | { | ||
64 | ECORE_CON_CONNECTED, | ||
65 | ECORE_CON_DISCONNECTED, | ||
66 | ECORE_CON_INPROGRESS | ||
67 | } Ecore_Con_State; | ||
68 | |||
69 | typedef enum _Ecore_Con_Ssl_Error | ||
70 | { | ||
71 | ECORE_CON_SSL_ERROR_NONE = 0, | ||
72 | ECORE_CON_SSL_ERROR_NOT_SUPPORTED, | ||
73 | ECORE_CON_SSL_ERROR_INIT_FAILED, | ||
74 | ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED, | ||
75 | ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED | ||
76 | } Ecore_Con_Ssl_Error; | ||
77 | |||
78 | typedef enum _Ecore_Con_Ssl_Handshake | ||
79 | { | ||
80 | ECORE_CON_SSL_STATE_DONE = 0, | ||
81 | ECORE_CON_SSL_STATE_HANDSHAKING, | ||
82 | ECORE_CON_SSL_STATE_INIT | ||
83 | } Ecore_Con_Ssl_State; | ||
84 | |||
85 | struct _Ecore_Con_Client | ||
86 | { | ||
87 | ECORE_MAGIC; | ||
88 | int fd; | ||
89 | Ecore_Con_Server *host_server; | ||
90 | void *data; | ||
91 | Ecore_Fd_Handler *fd_handler; | ||
92 | unsigned int buf_offset; | ||
93 | Eina_Binbuf *buf; | ||
94 | const char *ip; | ||
95 | Eina_List *event_count; | ||
96 | struct sockaddr *client_addr; | ||
97 | int client_addr_len; | ||
98 | double start_time; | ||
99 | Ecore_Timer *until_deletion; | ||
100 | double disconnect_time; | ||
101 | #if USE_GNUTLS | ||
102 | gnutls_datum_t session_ticket; | ||
103 | gnutls_session_t session; | ||
104 | #elif USE_OPENSSL | ||
105 | SSL *ssl; | ||
106 | int ssl_err; | ||
107 | #endif | ||
108 | Ecore_Con_Ssl_State ssl_state; | ||
109 | Eina_Bool handshaking : 1; | ||
110 | Eina_Bool upgrade : 1; | ||
111 | Eina_Bool dead : 1; | ||
112 | Eina_Bool delete_me : 1; | ||
113 | }; | ||
114 | |||
115 | struct _Ecore_Con_Server | ||
116 | { | ||
117 | ECORE_MAGIC; | ||
118 | int fd; | ||
119 | Ecore_Con_Type type; | ||
120 | char *name; | ||
121 | int port; | ||
122 | char *path; | ||
123 | void *data; | ||
124 | Ecore_Fd_Handler *fd_handler; | ||
125 | Eina_List *clients; | ||
126 | unsigned int client_count; | ||
127 | Eina_Binbuf *buf; | ||
128 | unsigned int write_buf_offset; | ||
129 | Eina_List *infos; | ||
130 | Eina_List *event_count; | ||
131 | int client_limit; | ||
132 | pid_t ppid; | ||
133 | #if USE_GNUTLS | ||
134 | gnutls_session_t session; | ||
135 | gnutls_anon_client_credentials_t anoncred_c; | ||
136 | gnutls_anon_server_credentials_t anoncred_s; | ||
137 | gnutls_psk_client_credentials_t pskcred_c; | ||
138 | gnutls_psk_server_credentials_t pskcred_s; | ||
139 | gnutls_certificate_credentials_t cert; | ||
140 | char *cert_file; | ||
141 | gnutls_dh_params_t dh_params; | ||
142 | #elif USE_OPENSSL | ||
143 | SSL_CTX *ssl_ctx; | ||
144 | SSL *ssl; | ||
145 | int ssl_err; | ||
146 | #endif | ||
147 | double start_time; | ||
148 | Ecore_Timer *until_deletion; | ||
149 | double disconnect_time; | ||
150 | double client_disconnect_time; | ||
151 | const char *ip; | ||
152 | Eina_Bool dead : 1; | ||
153 | Eina_Bool created : 1; /* EINA_TRUE if server is our listening server */ | ||
154 | Eina_Bool connecting : 1; /* EINA_FALSE if just initialized or connected */ | ||
155 | Eina_Bool handshaking : 1; /* EINA_TRUE if server is ssl handshaking */ | ||
156 | Eina_Bool upgrade : 1; | ||
157 | Eina_Bool ssl_prepared : 1; | ||
158 | Eina_Bool use_cert : 1; /* EINA_TRUE if using certificate auth */ | ||
159 | Ecore_Con_Ssl_State ssl_state; /* current state of ssl handshake on the server */ | ||
160 | Eina_Bool verify : 1; /* EINA_TRUE if certificates will be verified */ | ||
161 | Eina_Bool verify_basic : 1; /* EINA_TRUE if certificates will be verified only against the hostname */ | ||
162 | Eina_Bool reject_excess_clients : 1; | ||
163 | Eina_Bool delete_me : 1; | ||
164 | #ifdef _WIN32 | ||
165 | Eina_Bool want_write : 1; | ||
166 | Eina_Bool read_stop : 1; | ||
167 | Eina_Bool read_stopped : 1; | ||
168 | HANDLE pipe; | ||
169 | HANDLE thread_read; | ||
170 | HANDLE event_read; | ||
171 | HANDLE event_peek; | ||
172 | DWORD nbr_bytes; | ||
173 | #endif | ||
174 | }; | ||
175 | |||
176 | #ifdef HAVE_CURL | ||
177 | struct _Ecore_Con_Url | ||
178 | { | ||
179 | ECORE_MAGIC; | ||
180 | CURL *curl_easy; | ||
181 | struct curl_slist *headers; | ||
182 | Eina_List *additional_headers; | ||
183 | Eina_List *response_headers; | ||
184 | const char *url; | ||
185 | |||
186 | Ecore_Con_Url_Time time_condition; | ||
187 | double timestamp; | ||
188 | void *data; | ||
189 | |||
190 | Ecore_Fd_Handler *fd_handler; | ||
191 | int fd; | ||
192 | int flags; | ||
193 | |||
194 | int received; | ||
195 | int write_fd; | ||
196 | |||
197 | Eina_Bool active : 1; | ||
198 | }; | ||
199 | #endif | ||
200 | |||
201 | struct _Ecore_Con_Info | ||
202 | { | ||
203 | unsigned int size; | ||
204 | struct addrinfo info; | ||
205 | char ip[NI_MAXHOST]; | ||
206 | char service[NI_MAXSERV]; | ||
207 | }; | ||
208 | |||
209 | struct _Ecore_Con_Lookup | ||
210 | { | ||
211 | Ecore_Con_Dns_Cb done_cb; | ||
212 | const void *data; | ||
213 | }; | ||
214 | |||
215 | /* from ecore_con.c */ | ||
216 | void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info); | ||
217 | void ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate); | ||
218 | void ecore_con_event_server_del(Ecore_Con_Server *svr); | ||
219 | void ecore_con_event_server_error(Ecore_Con_Server *svr, const char *error); | ||
220 | void ecore_con_event_client_add(Ecore_Con_Client *cl); | ||
221 | void ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate); | ||
222 | void ecore_con_event_client_del(Ecore_Con_Client *cl); | ||
223 | void ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error); | ||
224 | |||
225 | /* from ecore_local_win32.c */ | ||
226 | #ifdef _WIN32 | ||
227 | Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr); | ||
228 | Eina_Bool ecore_con_local_connect(Ecore_Con_Server *svr, | ||
229 | Eina_Bool (*cb_done)(void *data, | ||
230 | Ecore_Fd_Handler *fd_handler)); | ||
231 | Eina_Bool ecore_con_local_win32_server_flush(Ecore_Con_Server *svr); | ||
232 | Eina_Bool ecore_con_local_win32_client_flush(Ecore_Con_Client *cl); | ||
233 | void ecore_con_local_win32_server_del(Ecore_Con_Server *svr); | ||
234 | void ecore_con_local_win32_client_del(Ecore_Con_Client *cl); | ||
235 | #else | ||
236 | /* from ecore_local.c */ | ||
237 | int ecore_con_local_init(void); | ||
238 | int ecore_con_local_shutdown(void); | ||
239 | int ecore_con_local_connect(Ecore_Con_Server *svr, | ||
240 | Eina_Bool (*cb_done)( | ||
241 | void *data, | ||
242 | Ecore_Fd_Handler *fd_handler), | ||
243 | void *data); | ||
244 | int ecore_con_local_listen(Ecore_Con_Server *svr, | ||
245 | Eina_Bool (*cb_listen)( | ||
246 | void *data, | ||
247 | Ecore_Fd_Handler *fd_handler), | ||
248 | void *data); | ||
249 | #endif | ||
250 | |||
251 | /* from ecore_con_info.c */ | ||
252 | int ecore_con_info_init(void); | ||
253 | int ecore_con_info_shutdown(void); | ||
254 | int ecore_con_info_tcp_connect(Ecore_Con_Server *svr, | ||
255 | Ecore_Con_Info_Cb done_cb, | ||
256 | void *data); | ||
257 | int ecore_con_info_tcp_listen(Ecore_Con_Server *svr, | ||
258 | Ecore_Con_Info_Cb done_cb, | ||
259 | void *data); | ||
260 | int ecore_con_info_udp_connect(Ecore_Con_Server *svr, | ||
261 | Ecore_Con_Info_Cb done_cb, | ||
262 | void *data); | ||
263 | int ecore_con_info_udp_listen(Ecore_Con_Server *svr, | ||
264 | Ecore_Con_Info_Cb done_cb, | ||
265 | void *data); | ||
266 | int ecore_con_info_mcast_listen(Ecore_Con_Server *svr, | ||
267 | Ecore_Con_Info_Cb done_cb, | ||
268 | void *data); | ||
269 | void ecore_con_info_data_clear(void *info); | ||
270 | |||
271 | void ecore_con_event_server_add(Ecore_Con_Server *svr); | ||
272 | |||
273 | |||
274 | /* from ecore_con_ssl.c */ | ||
275 | Ecore_Con_Ssl_Error ecore_con_ssl_init(void); | ||
276 | Ecore_Con_Ssl_Error ecore_con_ssl_shutdown(void); | ||
277 | Ecore_Con_Ssl_Error ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, int ssl_type); | ||
278 | Ecore_Con_Ssl_Error ecore_con_ssl_server_init(Ecore_Con_Server *svr); | ||
279 | Ecore_Con_Ssl_Error ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr); | ||
280 | int ecore_con_ssl_server_read(Ecore_Con_Server *svr, | ||
281 | unsigned char *buf, | ||
282 | int size); | ||
283 | int ecore_con_ssl_server_write(Ecore_Con_Server *svr, | ||
284 | const unsigned char *buf, | ||
285 | int size); | ||
286 | Ecore_Con_Ssl_Error ecore_con_ssl_client_init(Ecore_Con_Client *svr); | ||
287 | Ecore_Con_Ssl_Error ecore_con_ssl_client_shutdown(Ecore_Con_Client *svr); | ||
288 | int ecore_con_ssl_client_read(Ecore_Con_Client *svr, | ||
289 | unsigned char *buf, | ||
290 | int size); | ||
291 | int ecore_con_ssl_client_write(Ecore_Con_Client *svr, | ||
292 | const unsigned char *buf, | ||
293 | int size); | ||
294 | |||
295 | int ecore_con_info_get(Ecore_Con_Server *svr, | ||
296 | Ecore_Con_Info_Cb done_cb, | ||
297 | void *data, | ||
298 | struct addrinfo *hints); | ||
299 | |||
300 | |||
301 | #define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \ | ||
302 | TYPE *Type##_alloc(void); \ | ||
303 | void Type##_free(TYPE *e); | ||
304 | |||
305 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Add, ecore_con_event_client_add); | ||
306 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Del, ecore_con_event_client_del); | ||
307 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Write, ecore_con_event_client_write); | ||
308 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Data, ecore_con_event_client_data); | ||
309 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Error, ecore_con_event_server_error); | ||
310 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Error, ecore_con_event_client_error); | ||
311 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Add, ecore_con_event_server_add); | ||
312 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); | ||
313 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); | ||
314 | GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); | ||
315 | |||
316 | void ecore_con_mempool_init(void); | ||
317 | void ecore_con_mempool_shutdown(void); | ||
318 | |||
319 | #undef GENERIC_ALLOC_FREE_HEADER | ||
320 | |||
321 | #endif | ||
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c b/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c new file mode 100644 index 0000000..c352e94 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c | |||
@@ -0,0 +1,1777 @@ | |||
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 "Ecore.h" | ||
20 | #include "ecore_con_private.h" | ||
21 | |||
22 | EAPI int ECORE_CON_EVENT_CLIENT_UPGRADE = 0; | ||
23 | EAPI int ECORE_CON_EVENT_SERVER_UPGRADE = 0; | ||
24 | |||
25 | static int _init_con_ssl_init_count = 0; | ||
26 | |||
27 | #ifdef USE_GNUTLS | ||
28 | # ifdef EINA_HAVE_THREADS | ||
29 | GCRY_THREAD_OPTION_PTHREAD_IMPL; | ||
30 | # endif | ||
31 | |||
32 | static int _client_connected = 0; | ||
33 | |||
34 | # define SSL_SUFFIX(ssl_func) ssl_func ## _gnutls | ||
35 | # define _ECORE_CON_SSL_AVAILABLE 1 | ||
36 | |||
37 | #elif USE_OPENSSL | ||
38 | |||
39 | # define SSL_SUFFIX(ssl_func) ssl_func ## _openssl | ||
40 | # define _ECORE_CON_SSL_AVAILABLE 2 | ||
41 | |||
42 | #else | ||
43 | # define SSL_SUFFIX(ssl_func) ssl_func ## _none | ||
44 | # define _ECORE_CON_SSL_AVAILABLE 0 | ||
45 | |||
46 | #endif | ||
47 | |||
48 | #if USE_GNUTLS | ||
49 | static void | ||
50 | _gnutls_print_errors(void *conn, int type, int ret) | ||
51 | { | ||
52 | char buf[1024]; | ||
53 | |||
54 | if (!ret) return; | ||
55 | |||
56 | snprintf(buf, sizeof(buf), "GNUTLS error: %s - %s", gnutls_strerror_name(ret), gnutls_strerror(ret)); | ||
57 | if (type == ECORE_CON_EVENT_CLIENT_ERROR) | ||
58 | ecore_con_event_client_error(conn, buf); | ||
59 | else | ||
60 | ecore_con_event_server_error(conn, buf); | ||
61 | } | ||
62 | |||
63 | #ifdef ISCOMFITOR | ||
64 | static void | ||
65 | _gnutls_log_func(int level, | ||
66 | const char *str) | ||
67 | { | ||
68 | DBG("|<%d>| %s", level, str); | ||
69 | } | ||
70 | #endif | ||
71 | |||
72 | static const char * | ||
73 | SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status) | ||
74 | { | ||
75 | switch (status) | ||
76 | { | ||
77 | case GNUTLS_HANDSHAKE_HELLO_REQUEST: | ||
78 | return "Hello request"; | ||
79 | |||
80 | case GNUTLS_HANDSHAKE_CLIENT_HELLO: | ||
81 | return "Client hello"; | ||
82 | |||
83 | case GNUTLS_HANDSHAKE_SERVER_HELLO: | ||
84 | return "Server hello"; | ||
85 | |||
86 | case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: | ||
87 | return "New session ticket"; | ||
88 | |||
89 | case GNUTLS_HANDSHAKE_CERTIFICATE_PKT: | ||
90 | return "Certificate packet"; | ||
91 | |||
92 | case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE: | ||
93 | return "Server key exchange"; | ||
94 | |||
95 | case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST: | ||
96 | return "Certificate request"; | ||
97 | |||
98 | case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE: | ||
99 | return "Server hello done"; | ||
100 | |||
101 | case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY: | ||
102 | return "Certificate verify"; | ||
103 | |||
104 | case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE: | ||
105 | return "Client key exchange"; | ||
106 | |||
107 | case GNUTLS_HANDSHAKE_FINISHED: | ||
108 | return "Finished"; | ||
109 | |||
110 | case GNUTLS_HANDSHAKE_SUPPLEMENTAL: | ||
111 | return "Supplemental"; | ||
112 | } | ||
113 | return NULL; | ||
114 | } | ||
115 | |||
116 | #elif USE_OPENSSL | ||
117 | |||
118 | static void | ||
119 | _openssl_print_errors(void *conn, int type) | ||
120 | { | ||
121 | char buf[1024]; | ||
122 | do | ||
123 | { | ||
124 | unsigned long err; | ||
125 | |||
126 | err = ERR_get_error(); | ||
127 | if (!err) break; | ||
128 | snprintf(buf, sizeof(buf), "OpenSSL error: %s", ERR_reason_error_string(err)); | ||
129 | if (type == ECORE_CON_EVENT_CLIENT_ERROR) | ||
130 | ecore_con_event_client_error(conn, buf); | ||
131 | else | ||
132 | ecore_con_event_server_error(conn, buf); | ||
133 | |||
134 | } while (1); | ||
135 | } | ||
136 | |||
137 | static Eina_Bool | ||
138 | _openssl_name_verify(const char *name, const char *svrname) | ||
139 | { | ||
140 | if (name[0] == '*') | ||
141 | { | ||
142 | /* we allow *.domain.TLD with a wildcard, but nothing else */ | ||
143 | const char *p, *s; | ||
144 | |||
145 | EINA_SAFETY_ON_TRUE_RETURN_VAL((name[1] != '.') || (!name[2]), EINA_FALSE); | ||
146 | p = strchr(name + 1, '*'); | ||
147 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!!p, EINA_FALSE); | ||
148 | /* verify that we have a domain of at least *.X.TLD and not *.TLD */ | ||
149 | p = strchr(name + 2, '.'); | ||
150 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!p, EINA_FALSE); | ||
151 | s = strchr(svrname, '.'); | ||
152 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!s, EINA_FALSE); | ||
153 | /* same as above for the stored name */ | ||
154 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!strchr(s + 1, '.'), EINA_FALSE); | ||
155 | EINA_SAFETY_ON_TRUE_RETURN_VAL(strcasecmp(s, name + 1), EINA_FALSE); | ||
156 | } | ||
157 | else | ||
158 | EINA_SAFETY_ON_TRUE_RETURN_VAL(strcasecmp(name, svrname), EINA_FALSE); | ||
159 | return EINA_TRUE; | ||
160 | } | ||
161 | |||
162 | #endif | ||
163 | |||
164 | #define SSL_ERROR_CHECK_GOTO_ERROR(X) \ | ||
165 | do \ | ||
166 | { \ | ||
167 | if ((X)) \ | ||
168 | { \ | ||
169 | ERR("Error at %s:%s:%d!", __FILE__, __PRETTY_FUNCTION__, __LINE__); \ | ||
170 | goto error; \ | ||
171 | } \ | ||
172 | } \ | ||
173 | while (0) | ||
174 | |||
175 | static Ecore_Con_Ssl_Error | ||
176 | SSL_SUFFIX(_ecore_con_ssl_init) (void); | ||
177 | static Ecore_Con_Ssl_Error | ||
178 | SSL_SUFFIX(_ecore_con_ssl_shutdown) (void); | ||
179 | |||
180 | static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (Ecore_Con_Server * svr, const char *ca_file); | ||
181 | static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (Ecore_Con_Server * svr, const char *crl_file); | ||
182 | static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (Ecore_Con_Server * svr, const char *cert); | ||
183 | static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (Ecore_Con_Server * svr, const char *key_file); | ||
184 | |||
185 | static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_prepare) (Ecore_Con_Server * svr, int ssl_type); | ||
186 | static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_init) (Ecore_Con_Server * svr); | ||
187 | static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (Ecore_Con_Server *svr); | ||
188 | static int SSL_SUFFIX(_ecore_con_ssl_server_read) (Ecore_Con_Server *svr, unsigned char *buf, int size); | ||
189 | static int SSL_SUFFIX(_ecore_con_ssl_server_write) (Ecore_Con_Server *svr, const unsigned char *buf, int size); | ||
190 | |||
191 | static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_client_init) (Ecore_Con_Client * cl); | ||
192 | static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (Ecore_Con_Client *cl); | ||
193 | static int SSL_SUFFIX(_ecore_con_ssl_client_read) (Ecore_Con_Client * cl, | ||
194 | unsigned char *buf, int size); | ||
195 | static int SSL_SUFFIX(_ecore_con_ssl_client_write) (Ecore_Con_Client * cl, | ||
196 | const unsigned char *buf, int size); | ||
197 | |||
198 | /* | ||
199 | * General SSL API | ||
200 | */ | ||
201 | |||
202 | Ecore_Con_Ssl_Error | ||
203 | ecore_con_ssl_init(void) | ||
204 | { | ||
205 | if (!_init_con_ssl_init_count++) | ||
206 | { | ||
207 | SSL_SUFFIX(_ecore_con_ssl_init) (); | ||
208 | #if _ECORE_CON_SSL_AVAILABLE != 0 | ||
209 | ECORE_CON_EVENT_CLIENT_UPGRADE = ecore_event_type_new(); | ||
210 | ECORE_CON_EVENT_SERVER_UPGRADE = ecore_event_type_new(); | ||
211 | #endif | ||
212 | } | ||
213 | |||
214 | return _init_con_ssl_init_count; | ||
215 | } | ||
216 | |||
217 | Ecore_Con_Ssl_Error | ||
218 | ecore_con_ssl_shutdown(void) | ||
219 | { | ||
220 | if (!--_init_con_ssl_init_count) | ||
221 | SSL_SUFFIX(_ecore_con_ssl_shutdown) (); | ||
222 | |||
223 | return _init_con_ssl_init_count; | ||
224 | } | ||
225 | |||
226 | Ecore_Con_Ssl_Error | ||
227 | ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, | ||
228 | int ssl_type) | ||
229 | { | ||
230 | if (!ssl_type) | ||
231 | return ECORE_CON_SSL_ERROR_NONE; | ||
232 | return SSL_SUFFIX(_ecore_con_ssl_server_prepare) (svr, ssl_type); | ||
233 | } | ||
234 | |||
235 | Ecore_Con_Ssl_Error | ||
236 | ecore_con_ssl_server_init(Ecore_Con_Server *svr) | ||
237 | { | ||
238 | if (!(svr->type & ECORE_CON_SSL)) | ||
239 | return ECORE_CON_SSL_ERROR_NONE; | ||
240 | return SSL_SUFFIX(_ecore_con_ssl_server_init) (svr); | ||
241 | } | ||
242 | |||
243 | Ecore_Con_Ssl_Error | ||
244 | ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr) | ||
245 | { | ||
246 | if (!(svr->type & ECORE_CON_SSL)) | ||
247 | return ECORE_CON_SSL_ERROR_NONE; | ||
248 | return SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (svr); | ||
249 | } | ||
250 | |||
251 | int | ||
252 | ecore_con_ssl_server_read(Ecore_Con_Server *svr, | ||
253 | unsigned char *buf, | ||
254 | int size) | ||
255 | { | ||
256 | return SSL_SUFFIX(_ecore_con_ssl_server_read) (svr, buf, size); | ||
257 | } | ||
258 | |||
259 | int | ||
260 | ecore_con_ssl_server_write(Ecore_Con_Server *svr, | ||
261 | const unsigned char *buf, | ||
262 | int size) | ||
263 | { | ||
264 | return SSL_SUFFIX(_ecore_con_ssl_server_write) (svr, buf, size); | ||
265 | } | ||
266 | |||
267 | Ecore_Con_Ssl_Error | ||
268 | ecore_con_ssl_client_init(Ecore_Con_Client *cl) | ||
269 | { | ||
270 | if (!(cl->host_server->type & ECORE_CON_SSL)) | ||
271 | return ECORE_CON_SSL_ERROR_NONE; | ||
272 | return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl); | ||
273 | } | ||
274 | |||
275 | Ecore_Con_Ssl_Error | ||
276 | ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl) | ||
277 | { | ||
278 | if (!(cl->host_server->type & ECORE_CON_SSL)) | ||
279 | return ECORE_CON_SSL_ERROR_NONE; | ||
280 | return SSL_SUFFIX(_ecore_con_ssl_client_shutdown) (cl); | ||
281 | } | ||
282 | |||
283 | int | ||
284 | ecore_con_ssl_client_read(Ecore_Con_Client *cl, | ||
285 | unsigned char *buf, | ||
286 | int size) | ||
287 | { | ||
288 | return SSL_SUFFIX(_ecore_con_ssl_client_read) (cl, buf, size); | ||
289 | } | ||
290 | |||
291 | int | ||
292 | ecore_con_ssl_client_write(Ecore_Con_Client *cl, | ||
293 | const unsigned char *buf, | ||
294 | int size) | ||
295 | { | ||
296 | return SSL_SUFFIX(_ecore_con_ssl_client_write) (cl, buf, size); | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * Returns if SSL support is available | ||
301 | * @return 1 if SSL is available and provided by gnutls, 2 if provided by openssl, | ||
302 | * 0 if it is not available. | ||
303 | * @ingroup Ecore_Con_Client_Group | ||
304 | */ | ||
305 | EAPI int | ||
306 | ecore_con_ssl_available_get(void) | ||
307 | { | ||
308 | return _ECORE_CON_SSL_AVAILABLE; | ||
309 | } | ||
310 | |||
311 | /** | ||
312 | * @addtogroup Ecore_Con_SSL_Group Ecore Connection SSL Functions | ||
313 | * | ||
314 | * Functions that operate on Ecore connection objects pertaining to SSL. | ||
315 | * | ||
316 | * @{ | ||
317 | */ | ||
318 | |||
319 | /** | ||
320 | * @brief Enable certificate verification on a server object | ||
321 | * | ||
322 | * Call this function on a server object before main loop has started | ||
323 | * to enable verification of certificates against loaded certificates. | ||
324 | * @param svr The server object | ||
325 | */ | ||
326 | EAPI void | ||
327 | ecore_con_ssl_server_verify(Ecore_Con_Server *svr) | ||
328 | { | ||
329 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
330 | { | ||
331 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_verify"); | ||
332 | return; | ||
333 | } | ||
334 | svr->verify = EINA_TRUE; | ||
335 | } | ||
336 | |||
337 | /** | ||
338 | * @brief Enable hostname-based certificate verification on a server object | ||
339 | * | ||
340 | * Call this function on a server object before main loop has started | ||
341 | * to enable verification of certificates using ONLY their hostnames. | ||
342 | * @param svr The server object | ||
343 | * @note This function has no effect when used on a listening server created by | ||
344 | * ecore_con_server_add | ||
345 | * @since 1.1 | ||
346 | */ | ||
347 | EAPI void | ||
348 | ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr) | ||
349 | { | ||
350 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
351 | { | ||
352 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); | ||
353 | return; | ||
354 | } | ||
355 | svr->verify_basic = EINA_TRUE; | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * @brief Add an ssl certificate for use in ecore_con functions. | ||
360 | * | ||
361 | * Use this function to add a SSL PEM certificate. | ||
362 | * Simply specify the cert here to use it in the server object for connecting or listening. | ||
363 | * If there is an error loading the certificate, an error will automatically be logged. | ||
364 | * @param cert The path to the certificate. | ||
365 | * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE. | ||
366 | */ | ||
367 | |||
368 | EAPI Eina_Bool | ||
369 | ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr, | ||
370 | const char *cert) | ||
371 | { | ||
372 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
373 | { | ||
374 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cert_add"); | ||
375 | return EINA_FALSE; | ||
376 | } | ||
377 | |||
378 | return SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (svr, cert); | ||
379 | } | ||
380 | |||
381 | /** | ||
382 | * @brief Add an ssl CA file for use in ecore_con functions. | ||
383 | * | ||
384 | * Use this function to add a SSL PEM CA file. | ||
385 | * Simply specify the file here to use it in the server object for connecting or listening. | ||
386 | * If there is an error loading the CAs, an error will automatically be logged. | ||
387 | * @param ca_file The path to the CA file. | ||
388 | * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE. | ||
389 | */ | ||
390 | |||
391 | EAPI Eina_Bool | ||
392 | ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, | ||
393 | const char *ca_file) | ||
394 | { | ||
395 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
396 | { | ||
397 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cafile_add"); | ||
398 | return EINA_FALSE; | ||
399 | } | ||
400 | |||
401 | return SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (svr, ca_file); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * @brief Add an ssl private key for use in ecore_con functions. | ||
406 | * | ||
407 | * Use this function to add a SSL PEM private key | ||
408 | * Simply specify the key file here to use it in the server object for connecting or listening. | ||
409 | * If there is an error loading the key, an error will automatically be logged. | ||
410 | * @param key_file The path to the key file. | ||
411 | * @return EINA_FALSE if the file cannot be loaded, | ||
412 | * otherwise EINA_TRUE. | ||
413 | */ | ||
414 | |||
415 | EAPI Eina_Bool | ||
416 | ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr, | ||
417 | const char *key_file) | ||
418 | { | ||
419 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
420 | { | ||
421 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_privkey_add"); | ||
422 | return EINA_FALSE; | ||
423 | } | ||
424 | |||
425 | return SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (svr, key_file); | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * @brief Add an ssl CRL for use in ecore_con functions. | ||
430 | * | ||
431 | * Use this function to add a SSL PEM CRL file | ||
432 | * Simply specify the CRL file here to use it in the server object for connecting or listening. | ||
433 | * If there is an error loading the CRL, an error will automatically be logged. | ||
434 | * @param crl_file The path to the CRL file. | ||
435 | * @return EINA_FALSE if the file cannot be loaded, | ||
436 | * otherwise EINA_TRUE. | ||
437 | */ | ||
438 | |||
439 | EAPI Eina_Bool | ||
440 | ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, | ||
441 | const char *crl_file) | ||
442 | { | ||
443 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
444 | { | ||
445 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_crl_add"); | ||
446 | return EINA_FALSE; | ||
447 | } | ||
448 | |||
449 | return SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (svr, crl_file); | ||
450 | } | ||
451 | |||
452 | /** | ||
453 | * @brief Upgrade a connection to a specified level of encryption | ||
454 | * | ||
455 | * Use this function to begin an SSL handshake on a connection (STARTTLS or similar). | ||
456 | * Once the upgrade has been completed, an ECORE_CON_EVENT_SERVER_UPGRADE event will be emitted. | ||
457 | * The connection should be treated as disconnected until the next event. | ||
458 | * @param svr The server object | ||
459 | * @param ssl_type The SSL connection type (ONLY). | ||
460 | * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE. | ||
461 | * @note This function is NEVER to be used on a server object created with ecore_con_server_add | ||
462 | * @warning Setting a wrong value for @p compl_type WILL mess up your program. | ||
463 | * @since 1.1 | ||
464 | */ | ||
465 | |||
466 | EAPI Eina_Bool | ||
467 | ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type ssl_type) | ||
468 | { | ||
469 | if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) | ||
470 | { | ||
471 | ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); | ||
472 | return EINA_FALSE; | ||
473 | } | ||
474 | #if _ECORE_CON_SSL_AVAILABLE == 0 | ||
475 | return EINA_FALSE; | ||
476 | #endif | ||
477 | |||
478 | if (!svr->ssl_prepared) | ||
479 | { | ||
480 | if (ecore_con_ssl_server_prepare(svr, ssl_type)) | ||
481 | return EINA_FALSE; | ||
482 | } | ||
483 | svr->type |= ssl_type; | ||
484 | svr->upgrade = EINA_TRUE; | ||
485 | svr->handshaking = EINA_TRUE; | ||
486 | svr->ssl_state = ECORE_CON_SSL_STATE_INIT; | ||
487 | return !SSL_SUFFIX(_ecore_con_ssl_server_init) (svr); | ||
488 | } | ||
489 | |||
490 | /** | ||
491 | * @brief Upgrade a connection to a specified level of encryption | ||
492 | * | ||
493 | * Use this function to begin an SSL handshake on a connection (STARTTLS or similar). | ||
494 | * Once the upgrade has been completed, an ECORE_CON_EVENT_CLIENT_UPGRADE event will be emitted. | ||
495 | * The connection should be treated as disconnected until the next event. | ||
496 | * @param cl The client object | ||
497 | * @param compl_type The SSL connection type (ONLY). | ||
498 | * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE. | ||
499 | * @warning Setting a wrong value for @p compl_type WILL mess up your program. | ||
500 | * @since 1.1 | ||
501 | */ | ||
502 | |||
503 | EAPI Eina_Bool | ||
504 | ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type ssl_type) | ||
505 | { | ||
506 | if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) | ||
507 | { | ||
508 | ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__); | ||
509 | return EINA_FALSE; | ||
510 | } | ||
511 | #if _ECORE_CON_SSL_AVAILABLE == 0 | ||
512 | return EINA_FALSE; | ||
513 | #endif | ||
514 | |||
515 | if (!cl->host_server->ssl_prepared) | ||
516 | { | ||
517 | if (ecore_con_ssl_server_prepare(cl->host_server, ssl_type)) | ||
518 | return EINA_FALSE; | ||
519 | } | ||
520 | cl->host_server->type |= ssl_type; | ||
521 | cl->upgrade = EINA_TRUE; | ||
522 | cl->host_server->upgrade = EINA_TRUE; | ||
523 | cl->handshaking = EINA_TRUE; | ||
524 | cl->ssl_state = ECORE_CON_SSL_STATE_INIT; | ||
525 | return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl); | ||
526 | } | ||
527 | |||
528 | /** | ||
529 | * @} | ||
530 | */ | ||
531 | |||
532 | #if USE_GNUTLS | ||
533 | |||
534 | /* | ||
535 | * GnuTLS | ||
536 | */ | ||
537 | |||
538 | static Ecore_Con_Ssl_Error | ||
539 | _ecore_con_ssl_init_gnutls(void) | ||
540 | { | ||
541 | #ifdef EINA_HAVE_THREADS | ||
542 | if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread)) | ||
543 | WRN("YOU ARE USING PTHREADS, BUT I CANNOT INITIALIZE THREADSAFE GCRYPT OPERATIONS!"); | ||
544 | #endif | ||
545 | if (gnutls_global_init()) | ||
546 | return ECORE_CON_SSL_ERROR_INIT_FAILED; | ||
547 | |||
548 | #ifdef ISCOMFITOR | ||
549 | gnutls_global_set_log_level(9); | ||
550 | gnutls_global_set_log_function(_gnutls_log_func); | ||
551 | #endif | ||
552 | return ECORE_CON_SSL_ERROR_NONE; | ||
553 | } | ||
554 | |||
555 | static Ecore_Con_Ssl_Error | ||
556 | _ecore_con_ssl_shutdown_gnutls(void) | ||
557 | { | ||
558 | gnutls_global_deinit(); | ||
559 | |||
560 | return ECORE_CON_SSL_ERROR_NONE; | ||
561 | } | ||
562 | |||
563 | static Ecore_Con_Ssl_Error | ||
564 | _ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr, | ||
565 | int ssl_type) | ||
566 | { | ||
567 | int ret; | ||
568 | |||
569 | if (ssl_type & ECORE_CON_USE_SSL2) | ||
570 | return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; | ||
571 | |||
572 | switch (ssl_type) | ||
573 | { | ||
574 | case ECORE_CON_USE_SSL3: | ||
575 | case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: | ||
576 | case ECORE_CON_USE_TLS: | ||
577 | case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: | ||
578 | case ECORE_CON_USE_MIXED: | ||
579 | case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: | ||
580 | break; | ||
581 | |||
582 | default: | ||
583 | return ECORE_CON_SSL_ERROR_NONE; | ||
584 | } | ||
585 | |||
586 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_allocate_credentials(&svr->cert)); | ||
587 | |||
588 | if (svr->use_cert) | ||
589 | { | ||
590 | if (svr->created) | ||
591 | { | ||
592 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_init(&svr->dh_params)); | ||
593 | INF("Generating DH params"); | ||
594 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_generate2(svr->dh_params, 1024)); | ||
595 | |||
596 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_server_credentials(&svr->anoncred_s)); | ||
597 | /* TODO: implement PSK */ | ||
598 | // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_server_credentials(&svr->pskcred_s)); | ||
599 | |||
600 | gnutls_anon_set_server_dh_params(svr->anoncred_s, svr->dh_params); | ||
601 | gnutls_certificate_set_dh_params(svr->cert, svr->dh_params); | ||
602 | //gnutls_psk_set_server_dh_params(svr->pskcred_s, svr->dh_params); | ||
603 | INF("DH params successfully generated and applied!"); | ||
604 | } | ||
605 | else | ||
606 | { | ||
607 | //SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_client_credentials(&svr->pskcred_c)); | ||
608 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_client_credentials(&svr->anoncred_c)); | ||
609 | } | ||
610 | } | ||
611 | |||
612 | svr->ssl_prepared = EINA_TRUE; | ||
613 | return ECORE_CON_SSL_ERROR_NONE; | ||
614 | |||
615 | error: | ||
616 | _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret); | ||
617 | _ecore_con_ssl_server_shutdown_gnutls(svr); | ||
618 | return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; | ||
619 | } | ||
620 | |||
621 | |||
622 | static Ecore_Con_Ssl_Error | ||
623 | _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr) | ||
624 | { | ||
625 | const gnutls_datum_t *cert_list; | ||
626 | unsigned int iter, cert_list_size; | ||
627 | gnutls_x509_crt_t cert = NULL; | ||
628 | 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"; | ||
629 | int ret = 0; | ||
630 | |||
631 | switch (svr->ssl_state) | ||
632 | { | ||
633 | case ECORE_CON_SSL_STATE_DONE: | ||
634 | return ECORE_CON_SSL_ERROR_NONE; | ||
635 | |||
636 | case ECORE_CON_SSL_STATE_INIT: | ||
637 | if (svr->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */ | ||
638 | return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; | ||
639 | |||
640 | switch (svr->type & ECORE_CON_SSL) | ||
641 | { | ||
642 | case ECORE_CON_USE_SSL3: | ||
643 | case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: | ||
644 | 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"; | ||
645 | break; | ||
646 | |||
647 | case ECORE_CON_USE_TLS: | ||
648 | case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: | ||
649 | 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"; | ||
650 | break; | ||
651 | |||
652 | case ECORE_CON_USE_MIXED: | ||
653 | case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: | ||
654 | break; | ||
655 | |||
656 | default: | ||
657 | return ECORE_CON_SSL_ERROR_NONE; | ||
658 | } | ||
659 | |||
660 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&svr->session, GNUTLS_CLIENT)); | ||
661 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_client(svr->session)); | ||
662 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_server_name_set(svr->session, GNUTLS_NAME_DNS, svr->name, strlen(svr->name))); | ||
663 | INF("Applying priority string: %s", priority); | ||
664 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(svr->session, priority, NULL)); | ||
665 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_CERTIFICATE, svr->cert)); | ||
666 | // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_PSK, svr->pskcred_c)); | ||
667 | if (!svr->use_cert) | ||
668 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c)); | ||
669 | |||
670 | gnutls_dh_set_prime_bits(svr->session, 512); | ||
671 | gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)((intptr_t)svr->fd)); | ||
672 | svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; | ||
673 | |||
674 | case ECORE_CON_SSL_STATE_HANDSHAKING: | ||
675 | if (!svr->session) | ||
676 | { | ||
677 | DBG("Server was previously lost, going to error condition"); | ||
678 | goto error; | ||
679 | } | ||
680 | ret = gnutls_handshake(svr->session); | ||
681 | DBG("calling gnutls_handshake(): returned with '%s'", gnutls_strerror_name(ret)); | ||
682 | SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret)); | ||
683 | if (!ret) | ||
684 | { | ||
685 | svr->handshaking = EINA_FALSE; | ||
686 | svr->ssl_state = ECORE_CON_SSL_STATE_DONE; | ||
687 | } | ||
688 | else | ||
689 | { | ||
690 | if (gnutls_record_get_direction(svr->session)) | ||
691 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); | ||
692 | else | ||
693 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
694 | return ECORE_CON_SSL_ERROR_NONE; | ||
695 | } | ||
696 | |||
697 | default: | ||
698 | break; | ||
699 | } | ||
700 | |||
701 | if ((!svr->verify) && (!svr->verify_basic)) | ||
702 | /* not verifying certificates, so we're done! */ | ||
703 | return ECORE_CON_SSL_ERROR_NONE; | ||
704 | if (svr->verify) | ||
705 | { | ||
706 | /* use CRL/CA lists to verify */ | ||
707 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(svr->session, &iter)); | ||
708 | if (iter & GNUTLS_CERT_INVALID) | ||
709 | ERR("The certificate is not trusted."); | ||
710 | else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND) | ||
711 | ERR("The certificate hasn't got a known issuer."); | ||
712 | else if (iter & GNUTLS_CERT_REVOKED) | ||
713 | ERR("The certificate has been revoked."); | ||
714 | else if (iter & GNUTLS_CERT_EXPIRED) | ||
715 | ERR("The certificate has expired"); | ||
716 | else if (iter & GNUTLS_CERT_NOT_ACTIVATED) | ||
717 | ERR("The certificate is not yet activated"); | ||
718 | |||
719 | if (iter) | ||
720 | goto error; | ||
721 | } | ||
722 | if (gnutls_certificate_type_get(svr->session) != GNUTLS_CRT_X509) | ||
723 | { | ||
724 | ERR("Warning: PGP certificates are not yet supported!"); | ||
725 | goto error; | ||
726 | } | ||
727 | |||
728 | SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(svr->session, &cert_list_size))); | ||
729 | SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size); | ||
730 | |||
731 | SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert)); | ||
732 | SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)); | ||
733 | |||
734 | SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->name)); | ||
735 | gnutls_x509_crt_deinit(cert); | ||
736 | DBG("SSL certificate verification succeeded!"); | ||
737 | return ECORE_CON_SSL_ERROR_NONE; | ||
738 | |||
739 | error: | ||
740 | _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret); | ||
741 | if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)) | ||
742 | ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(svr->session))); | ||
743 | if (svr->session && (svr->ssl_state != ECORE_CON_SSL_STATE_DONE)) | ||
744 | { | ||
745 | ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(svr->session))); | ||
746 | ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(svr->session))); | ||
747 | } | ||
748 | if (cert) | ||
749 | gnutls_x509_crt_deinit(cert); | ||
750 | _ecore_con_ssl_server_shutdown_gnutls(svr); | ||
751 | return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; | ||
752 | } | ||
753 | |||
754 | static Eina_Bool | ||
755 | _ecore_con_ssl_server_cafile_add_gnutls(Ecore_Con_Server *svr, | ||
756 | const char *ca_file) | ||
757 | { | ||
758 | SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_trust_file(svr->cert, ca_file, | ||
759 | GNUTLS_X509_FMT_PEM) < 1); | ||
760 | |||
761 | return EINA_TRUE; | ||
762 | error: | ||
763 | ERR("Could not load CA file!"); | ||
764 | return EINA_FALSE; | ||
765 | } | ||
766 | |||
767 | static Eina_Bool | ||
768 | _ecore_con_ssl_server_crl_add_gnutls(Ecore_Con_Server *svr, | ||
769 | const char *crl_file) | ||
770 | { | ||
771 | SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_crl_file(svr->cert, crl_file, | ||
772 | GNUTLS_X509_FMT_PEM) < 1); | ||
773 | |||
774 | return EINA_TRUE; | ||
775 | error: | ||
776 | ERR("Could not load CRL file!"); | ||
777 | return EINA_FALSE; | ||
778 | } | ||
779 | |||
780 | static Eina_Bool | ||
781 | _ecore_con_ssl_server_privkey_add_gnutls(Ecore_Con_Server *svr, | ||
782 | const char *key_file) | ||
783 | { | ||
784 | SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_key_file(svr->cert, svr->cert_file, key_file, | ||
785 | GNUTLS_X509_FMT_PEM)); | ||
786 | |||
787 | return EINA_TRUE; | ||
788 | error: | ||
789 | ERR("Could not load certificate/key file!"); | ||
790 | return EINA_FALSE; | ||
791 | } | ||
792 | |||
793 | static Eina_Bool | ||
794 | _ecore_con_ssl_server_cert_add_gnutls(Ecore_Con_Server *svr, | ||
795 | const char *cert_file) | ||
796 | { | ||
797 | if (!(svr->cert_file = strdup(cert_file))) | ||
798 | return EINA_FALSE; | ||
799 | |||
800 | return EINA_TRUE; | ||
801 | } | ||
802 | |||
803 | static Ecore_Con_Ssl_Error | ||
804 | _ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr) | ||
805 | { | ||
806 | if (svr->session) | ||
807 | { | ||
808 | gnutls_bye(svr->session, GNUTLS_SHUT_RDWR); | ||
809 | gnutls_deinit(svr->session); | ||
810 | } | ||
811 | |||
812 | free(svr->cert_file); | ||
813 | svr->cert_file = NULL; | ||
814 | if (svr->cert) | ||
815 | gnutls_certificate_free_credentials(svr->cert); | ||
816 | svr->cert = NULL; | ||
817 | |||
818 | if ((svr->type & ECORE_CON_SSL) && svr->created) | ||
819 | { | ||
820 | if (svr->dh_params) | ||
821 | { | ||
822 | gnutls_dh_params_deinit(svr->dh_params); | ||
823 | svr->dh_params = NULL; | ||
824 | } | ||
825 | if (svr->anoncred_s) | ||
826 | gnutls_anon_free_server_credentials(svr->anoncred_s); | ||
827 | // if (svr->pskcred_s) | ||
828 | // gnutls_psk_free_server_credentials(svr->pskcred_s); | ||
829 | |||
830 | svr->anoncred_s = NULL; | ||
831 | svr->pskcred_s = NULL; | ||
832 | } | ||
833 | else if (svr->type & ECORE_CON_SSL) | ||
834 | { | ||
835 | if (svr->anoncred_c) | ||
836 | gnutls_anon_free_client_credentials(svr->anoncred_c); | ||
837 | // if (svr->pskcred_c) | ||
838 | // gnutls_psk_free_client_credentials(svr->pskcred_c); | ||
839 | |||
840 | svr->anoncred_c = NULL; | ||
841 | svr->pskcred_c = NULL; | ||
842 | } | ||
843 | |||
844 | svr->session = NULL; | ||
845 | |||
846 | return ECORE_CON_SSL_ERROR_NONE; | ||
847 | } | ||
848 | |||
849 | static int | ||
850 | _ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr, | ||
851 | unsigned char *buf, | ||
852 | int size) | ||
853 | { | ||
854 | int num; | ||
855 | |||
856 | if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) | ||
857 | { | ||
858 | DBG("Continuing gnutls handshake"); | ||
859 | if (!_ecore_con_ssl_server_init_gnutls(svr)) | ||
860 | return 0; | ||
861 | return -1; | ||
862 | } | ||
863 | |||
864 | num = gnutls_record_recv(svr->session, buf, size); | ||
865 | if (num > 0) | ||
866 | return num; | ||
867 | |||
868 | if (num == GNUTLS_E_REHANDSHAKE) | ||
869 | { | ||
870 | WRN("Rehandshake request ignored"); | ||
871 | return 0; | ||
872 | |||
873 | svr->handshaking = EINA_TRUE; | ||
874 | svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; | ||
875 | if (!_ecore_con_ssl_server_init_gnutls(svr)) | ||
876 | return 0; | ||
877 | } | ||
878 | else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS)) | ||
879 | return 0; | ||
880 | |||
881 | return -1; | ||
882 | } | ||
883 | |||
884 | static int | ||
885 | _ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr, | ||
886 | const unsigned char *buf, | ||
887 | int size) | ||
888 | { | ||
889 | int num; | ||
890 | |||
891 | if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) | ||
892 | { | ||
893 | DBG("Continuing gnutls handshake"); | ||
894 | if (!_ecore_con_ssl_server_init_gnutls(svr)) | ||
895 | return 0; | ||
896 | return -1; | ||
897 | } | ||
898 | |||
899 | num = gnutls_record_send(svr->session, buf, size); | ||
900 | if (num > 0) | ||
901 | return num; | ||
902 | |||
903 | if (num == GNUTLS_E_REHANDSHAKE) | ||
904 | { | ||
905 | WRN("Rehandshake request ignored"); | ||
906 | return 0; | ||
907 | /* this is only partly functional I think? */ | ||
908 | svr->handshaking = EINA_TRUE; | ||
909 | svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; | ||
910 | if (!_ecore_con_ssl_server_init_gnutls(svr)) | ||
911 | return 0; | ||
912 | } | ||
913 | else if (!gnutls_error_is_fatal(num)) | ||
914 | return 0; | ||
915 | |||
916 | return -1; | ||
917 | } | ||
918 | |||
919 | static Ecore_Con_Ssl_Error | ||
920 | _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl) | ||
921 | { | ||
922 | const gnutls_datum_t *cert_list; | ||
923 | unsigned int iter, cert_list_size; | ||
924 | 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"; | ||
925 | int ret = 0; | ||
926 | |||
927 | switch (cl->ssl_state) | ||
928 | { | ||
929 | case ECORE_CON_SSL_STATE_DONE: | ||
930 | return ECORE_CON_SSL_ERROR_NONE; | ||
931 | |||
932 | case ECORE_CON_SSL_STATE_INIT: | ||
933 | if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */ | ||
934 | return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; | ||
935 | |||
936 | switch (cl->host_server->type & ECORE_CON_SSL) | ||
937 | { | ||
938 | case ECORE_CON_USE_SSL3: | ||
939 | case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: | ||
940 | 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"; | ||
941 | break; | ||
942 | |||
943 | case ECORE_CON_USE_TLS: | ||
944 | case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: | ||
945 | 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"; | ||
946 | break; | ||
947 | |||
948 | case ECORE_CON_USE_MIXED: | ||
949 | case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: | ||
950 | break; | ||
951 | |||
952 | default: | ||
953 | return ECORE_CON_SSL_ERROR_NONE; | ||
954 | } | ||
955 | |||
956 | _client_connected++; | ||
957 | |||
958 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&cl->session, GNUTLS_SERVER)); | ||
959 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_key_generate(&cl->session_ticket)); | ||
960 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_server(cl->session, &cl->session_ticket)); | ||
961 | INF("Applying priority string: %s", priority); | ||
962 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(cl->session, priority, NULL)); | ||
963 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_CERTIFICATE, cl->host_server->cert)); | ||
964 | // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_PSK, cl->host_server->pskcred_s)); | ||
965 | if (!cl->host_server->use_cert) | ||
966 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->host_server->anoncred_s)); | ||
967 | |||
968 | gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST); | ||
969 | |||
970 | gnutls_dh_set_prime_bits(cl->session, 2048); | ||
971 | gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)((intptr_t)cl->fd)); | ||
972 | cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; | ||
973 | |||
974 | case ECORE_CON_SSL_STATE_HANDSHAKING: | ||
975 | if (!cl->session) | ||
976 | { | ||
977 | DBG("Client was previously lost, going to error condition"); | ||
978 | goto error; | ||
979 | } | ||
980 | DBG("calling gnutls_handshake()"); | ||
981 | ret = gnutls_handshake(cl->session); | ||
982 | SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret)); | ||
983 | |||
984 | if (!ret) | ||
985 | { | ||
986 | cl->handshaking = EINA_FALSE; | ||
987 | cl->ssl_state = ECORE_CON_SSL_STATE_DONE; | ||
988 | } | ||
989 | else | ||
990 | { | ||
991 | if (gnutls_record_get_direction(cl->session)) | ||
992 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); | ||
993 | else | ||
994 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); | ||
995 | return ECORE_CON_SSL_ERROR_NONE; | ||
996 | } | ||
997 | |||
998 | default: | ||
999 | break; | ||
1000 | } | ||
1001 | |||
1002 | if (!cl->host_server->verify) | ||
1003 | /* not verifying certificates, so we're done! */ | ||
1004 | return ECORE_CON_SSL_ERROR_NONE; | ||
1005 | /* use CRL/CA lists to verify */ | ||
1006 | SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(cl->session, &iter)); | ||
1007 | if (iter & GNUTLS_CERT_INVALID) | ||
1008 | ERR("The certificate is not trusted."); | ||
1009 | else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND) | ||
1010 | ERR("The certificate hasn't got a known issuer."); | ||
1011 | else if (iter & GNUTLS_CERT_REVOKED) | ||
1012 | ERR("The certificate has been revoked."); | ||
1013 | else if (iter & GNUTLS_CERT_EXPIRED) | ||
1014 | ERR("The certificate has expired"); | ||
1015 | else if (iter & GNUTLS_CERT_NOT_ACTIVATED) | ||
1016 | ERR("The certificate is not yet activated"); | ||
1017 | |||
1018 | if (iter) | ||
1019 | goto error; | ||
1020 | if (gnutls_certificate_type_get(cl->session) != GNUTLS_CRT_X509) | ||
1021 | { | ||
1022 | ERR("Warning: PGP certificates are not yet supported!"); | ||
1023 | goto error; | ||
1024 | } | ||
1025 | |||
1026 | SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(cl->session, &cert_list_size))); | ||
1027 | SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size); | ||
1028 | |||
1029 | /* | ||
1030 | gnutls_x509_crt_t cert = NULL; | ||
1031 | SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert)); | ||
1032 | SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)); | ||
1033 | |||
1034 | SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, cl->host_server->name)); | ||
1035 | gnutls_x509_crt_deinit(cert); | ||
1036 | */ | ||
1037 | DBG("SSL certificate verification succeeded!"); | ||
1038 | return ECORE_CON_SSL_ERROR_NONE; | ||
1039 | |||
1040 | error: | ||
1041 | _gnutls_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR, ret); | ||
1042 | if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)) | ||
1043 | ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(cl->session))); | ||
1044 | if (cl->session && (cl->ssl_state != ECORE_CON_SSL_STATE_DONE)) | ||
1045 | { | ||
1046 | ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(cl->session))); | ||
1047 | ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(cl->session))); | ||
1048 | } | ||
1049 | /* | ||
1050 | if (cert) | ||
1051 | gnutls_x509_crt_deinit(cert); | ||
1052 | */ | ||
1053 | _ecore_con_ssl_client_shutdown_gnutls(cl); | ||
1054 | return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; | ||
1055 | } | ||
1056 | |||
1057 | static Ecore_Con_Ssl_Error | ||
1058 | _ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl) | ||
1059 | { | ||
1060 | if (cl->session) | ||
1061 | { | ||
1062 | gnutls_bye(cl->session, GNUTLS_SHUT_RDWR); | ||
1063 | gnutls_deinit(cl->session); | ||
1064 | gnutls_free(cl->session_ticket.data); | ||
1065 | cl->session_ticket.data = NULL; | ||
1066 | } | ||
1067 | |||
1068 | cl->session = NULL; | ||
1069 | |||
1070 | return ECORE_CON_SSL_ERROR_NONE; | ||
1071 | } | ||
1072 | |||
1073 | static int | ||
1074 | _ecore_con_ssl_client_read_gnutls(Ecore_Con_Client *cl, | ||
1075 | unsigned char *buf, | ||
1076 | int size) | ||
1077 | { | ||
1078 | int num; | ||
1079 | |||
1080 | if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) | ||
1081 | { | ||
1082 | if (!_ecore_con_ssl_client_init_gnutls(cl)) | ||
1083 | return 0; | ||
1084 | return -1; | ||
1085 | } | ||
1086 | |||
1087 | num = gnutls_record_recv(cl->session, buf, size); | ||
1088 | if (num > 0) | ||
1089 | return num; | ||
1090 | |||
1091 | if (num == GNUTLS_E_REHANDSHAKE) | ||
1092 | { | ||
1093 | WRN("Rehandshake request ignored"); | ||
1094 | return 0; | ||
1095 | cl->handshaking = EINA_TRUE; | ||
1096 | cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; | ||
1097 | if (!_ecore_con_ssl_client_init_gnutls(cl)) | ||
1098 | return 0; | ||
1099 | WRN("Rehandshake request ignored"); | ||
1100 | return 0; | ||
1101 | } | ||
1102 | else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS)) | ||
1103 | return 0; | ||
1104 | |||
1105 | return -1; | ||
1106 | } | ||
1107 | |||
1108 | static int | ||
1109 | _ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl, | ||
1110 | const unsigned char *buf, | ||
1111 | int size) | ||
1112 | { | ||
1113 | int num; | ||
1114 | |||
1115 | if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) | ||
1116 | { | ||
1117 | if (!_ecore_con_ssl_client_init_gnutls(cl)) | ||
1118 | return 0; | ||
1119 | return -1; | ||
1120 | } | ||
1121 | |||
1122 | num = gnutls_record_send(cl->session, buf, size); | ||
1123 | if (num > 0) | ||
1124 | return num; | ||
1125 | |||
1126 | if (num == GNUTLS_E_REHANDSHAKE) | ||
1127 | { | ||
1128 | WRN("Rehandshake request ignored"); | ||
1129 | return 0; | ||
1130 | cl->handshaking = EINA_TRUE; | ||
1131 | cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; | ||
1132 | if (!_ecore_con_ssl_client_init_gnutls(cl)) | ||
1133 | return 0; | ||
1134 | } | ||
1135 | else if (!gnutls_error_is_fatal(num)) | ||
1136 | return 0; | ||
1137 | |||
1138 | return -1; | ||
1139 | } | ||
1140 | |||
1141 | #elif USE_OPENSSL && !USE_GNUTLS | ||
1142 | |||
1143 | /* | ||
1144 | * OpenSSL | ||
1145 | */ | ||
1146 | |||
1147 | static Ecore_Con_Ssl_Error | ||
1148 | _ecore_con_ssl_init_openssl(void) | ||
1149 | { | ||
1150 | SSL_library_init(); | ||
1151 | SSL_load_error_strings(); | ||
1152 | OpenSSL_add_all_algorithms(); | ||
1153 | |||
1154 | return ECORE_CON_SSL_ERROR_NONE; | ||
1155 | } | ||
1156 | |||
1157 | static Ecore_Con_Ssl_Error | ||
1158 | _ecore_con_ssl_shutdown_openssl(void) | ||
1159 | { | ||
1160 | ERR_free_strings(); | ||
1161 | EVP_cleanup(); | ||
1162 | return ECORE_CON_SSL_ERROR_NONE; | ||
1163 | } | ||
1164 | |||
1165 | static Ecore_Con_Ssl_Error | ||
1166 | _ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr, | ||
1167 | int ssl_type) | ||
1168 | { | ||
1169 | long options; | ||
1170 | int dh = 0; | ||
1171 | |||
1172 | if (ssl_type & ECORE_CON_USE_SSL2) | ||
1173 | return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; | ||
1174 | |||
1175 | switch (ssl_type) | ||
1176 | { | ||
1177 | case ECORE_CON_USE_SSL3: | ||
1178 | case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: | ||
1179 | if (!svr->created) | ||
1180 | SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method()))); | ||
1181 | else | ||
1182 | SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_server_method()))); | ||
1183 | break; | ||
1184 | |||
1185 | case ECORE_CON_USE_TLS: | ||
1186 | case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: | ||
1187 | if (!svr->created) | ||
1188 | SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method()))); | ||
1189 | else | ||
1190 | SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_server_method()))); | ||
1191 | break; | ||
1192 | |||
1193 | case ECORE_CON_USE_MIXED: | ||
1194 | case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: | ||
1195 | if (!svr->created) | ||
1196 | SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_client_method()))); | ||
1197 | else | ||
1198 | SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))); | ||
1199 | options = SSL_CTX_get_options(svr->ssl_ctx); | ||
1200 | SSL_CTX_set_options(svr->ssl_ctx, options | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE); | ||
1201 | break; | ||
1202 | |||
1203 | default: | ||
1204 | return ECORE_CON_SSL_ERROR_NONE; | ||
1205 | } | ||
1206 | |||
1207 | if ((!svr->use_cert) && svr->created) | ||
1208 | { | ||
1209 | DH *dh_params; | ||
1210 | INF("Generating DH params"); | ||
1211 | SSL_ERROR_CHECK_GOTO_ERROR(!(dh_params = DH_new())); | ||
1212 | SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_parameters_ex(dh_params, 1024, DH_GENERATOR_5, NULL)); | ||
1213 | SSL_ERROR_CHECK_GOTO_ERROR(!DH_check(dh_params, &dh)); | ||
1214 | SSL_ERROR_CHECK_GOTO_ERROR((dh & DH_CHECK_P_NOT_PRIME) || (dh & DH_CHECK_P_NOT_SAFE_PRIME)); | ||
1215 | SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_key(dh_params)); | ||
1216 | SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_tmp_dh(svr->ssl_ctx, dh_params)); | ||
1217 | DH_free(dh_params); | ||
1218 | INF("DH params successfully generated and applied!"); | ||
1219 | SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:@STRENGTH")); | ||
1220 | } | ||
1221 | else if (!svr->use_cert) | ||
1222 | SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:!ECDH:RSA:AES:!PSK:@STRENGTH")); | ||
1223 | |||
1224 | return ECORE_CON_SSL_ERROR_NONE; | ||
1225 | |||
1226 | error: | ||
1227 | if (dh) | ||
1228 | { | ||
1229 | if (dh & DH_CHECK_P_NOT_PRIME) | ||
1230 | ERR("openssl error: dh_params could not generate a prime!"); | ||
1231 | else | ||
1232 | ERR("openssl error: dh_params could not generate a safe prime!"); | ||
1233 | } | ||
1234 | else | ||
1235 | _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); | ||
1236 | _ecore_con_ssl_server_shutdown_openssl(svr); | ||
1237 | return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; | ||
1238 | } | ||
1239 | |||
1240 | static Ecore_Con_Ssl_Error | ||
1241 | _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr) | ||
1242 | { | ||
1243 | int ret = -1; | ||
1244 | |||
1245 | switch (svr->ssl_state) | ||
1246 | { | ||
1247 | case ECORE_CON_SSL_STATE_DONE: | ||
1248 | return ECORE_CON_SSL_ERROR_NONE; | ||
1249 | |||
1250 | case ECORE_CON_SSL_STATE_INIT: | ||
1251 | SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx))); | ||
1252 | |||
1253 | SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd)); | ||
1254 | SSL_set_connect_state(svr->ssl); | ||
1255 | svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; | ||
1256 | |||
1257 | case ECORE_CON_SSL_STATE_HANDSHAKING: | ||
1258 | if (!svr->ssl) | ||
1259 | { | ||
1260 | DBG("Server was previously lost, going to error condition"); | ||
1261 | goto error; | ||
1262 | } | ||
1263 | ret = SSL_do_handshake(svr->ssl); | ||
1264 | svr->ssl_err = SSL_get_error(svr->ssl, ret); | ||
1265 | SSL_ERROR_CHECK_GOTO_ERROR((svr->ssl_err == SSL_ERROR_SYSCALL) || (svr->ssl_err == SSL_ERROR_SSL)); | ||
1266 | |||
1267 | if (ret == 1) | ||
1268 | { | ||
1269 | svr->handshaking = EINA_FALSE; | ||
1270 | svr->ssl_state = ECORE_CON_SSL_STATE_DONE; | ||
1271 | } | ||
1272 | else | ||
1273 | { | ||
1274 | if (svr->ssl_err == SSL_ERROR_WANT_READ) | ||
1275 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
1276 | else if (svr->ssl_err == SSL_ERROR_WANT_WRITE) | ||
1277 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); | ||
1278 | return ECORE_CON_SSL_ERROR_NONE; | ||
1279 | } | ||
1280 | |||
1281 | default: | ||
1282 | break; | ||
1283 | } | ||
1284 | |||
1285 | #ifdef ISCOMFITOR | ||
1286 | { | ||
1287 | /* print session info into DBG */ | ||
1288 | SSL_SESSION *s; | ||
1289 | BIO *b; | ||
1290 | char log[4096]; | ||
1291 | |||
1292 | memset(log, 0, sizeof(log)); | ||
1293 | s = SSL_get_session(svr->ssl); | ||
1294 | b = BIO_new(BIO_s_mem()); | ||
1295 | SSL_SESSION_print(b, s); | ||
1296 | while (BIO_read(b, log, sizeof(log)) > 0) | ||
1297 | DBG("%s", log); | ||
1298 | |||
1299 | BIO_free(b); | ||
1300 | } | ||
1301 | #endif | ||
1302 | if ((!svr->verify) && (!svr->verify_basic)) | ||
1303 | /* not verifying certificates, so we're done! */ | ||
1304 | return ECORE_CON_SSL_ERROR_NONE; | ||
1305 | |||
1306 | { | ||
1307 | X509 *cert; | ||
1308 | SSL_set_verify(svr->ssl, SSL_VERIFY_PEER, NULL); | ||
1309 | /* use CRL/CA lists to verify */ | ||
1310 | cert = SSL_get_peer_certificate(svr->ssl); | ||
1311 | if (cert) | ||
1312 | { | ||
1313 | char buf[256] = {0}; | ||
1314 | if (svr->verify) | ||
1315 | SSL_ERROR_CHECK_GOTO_ERROR(SSL_get_verify_result(svr->ssl)); | ||
1316 | X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, buf, sizeof(buf)); | ||
1317 | if (buf[0]) | ||
1318 | SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->name)); | ||
1319 | else | ||
1320 | { | ||
1321 | X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, buf, sizeof(buf)); | ||
1322 | SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->name)); | ||
1323 | } | ||
1324 | } | ||
1325 | } | ||
1326 | |||
1327 | DBG("SSL certificate verification succeeded!"); | ||
1328 | |||
1329 | return ECORE_CON_SSL_ERROR_NONE; | ||
1330 | |||
1331 | error: | ||
1332 | _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); | ||
1333 | _ecore_con_ssl_server_shutdown_openssl(svr); | ||
1334 | return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; | ||
1335 | } | ||
1336 | |||
1337 | static Eina_Bool | ||
1338 | _ecore_con_ssl_server_cafile_add_openssl(Ecore_Con_Server *svr, | ||
1339 | const char *ca_file) | ||
1340 | { | ||
1341 | SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, ca_file, NULL)); | ||
1342 | return EINA_TRUE; | ||
1343 | |||
1344 | error: | ||
1345 | _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); | ||
1346 | return EINA_FALSE; | ||
1347 | } | ||
1348 | |||
1349 | static Eina_Bool | ||
1350 | _ecore_con_ssl_server_crl_add_openssl(Ecore_Con_Server *svr, | ||
1351 | const char *crl_file) | ||
1352 | { | ||
1353 | X509_STORE *st; | ||
1354 | X509_LOOKUP *lu; | ||
1355 | static Eina_Bool flag = EINA_FALSE; | ||
1356 | |||
1357 | SSL_ERROR_CHECK_GOTO_ERROR(!(st = SSL_CTX_get_cert_store(svr->ssl_ctx))); | ||
1358 | SSL_ERROR_CHECK_GOTO_ERROR(!(lu = X509_STORE_add_lookup(st, X509_LOOKUP_file()))); | ||
1359 | SSL_ERROR_CHECK_GOTO_ERROR(X509_load_crl_file(lu, crl_file, X509_FILETYPE_PEM) < 1); | ||
1360 | if (!flag) | ||
1361 | { | ||
1362 | X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); | ||
1363 | flag = EINA_TRUE; | ||
1364 | } | ||
1365 | |||
1366 | return EINA_TRUE; | ||
1367 | |||
1368 | error: | ||
1369 | _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); | ||
1370 | return EINA_FALSE; | ||
1371 | } | ||
1372 | |||
1373 | static Eina_Bool | ||
1374 | _ecore_con_ssl_server_privkey_add_openssl(Ecore_Con_Server *svr, | ||
1375 | const char *key_file) | ||
1376 | { | ||
1377 | FILE *fp = NULL; | ||
1378 | EVP_PKEY *privkey = NULL; | ||
1379 | |||
1380 | if (!(fp = fopen(key_file, "r"))) | ||
1381 | goto error; | ||
1382 | |||
1383 | SSL_ERROR_CHECK_GOTO_ERROR(!(privkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL))); | ||
1384 | |||
1385 | fclose(fp); | ||
1386 | SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_PrivateKey(svr->ssl_ctx, privkey) < 1); | ||
1387 | SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_check_private_key(svr->ssl_ctx) < 1); | ||
1388 | |||
1389 | return EINA_TRUE; | ||
1390 | |||
1391 | error: | ||
1392 | if (fp) | ||
1393 | fclose(fp); | ||
1394 | _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); | ||
1395 | return EINA_FALSE; | ||
1396 | } | ||
1397 | |||
1398 | static Eina_Bool | ||
1399 | _ecore_con_ssl_server_cert_add_openssl(Ecore_Con_Server *svr, | ||
1400 | const char *cert_file) | ||
1401 | { | ||
1402 | FILE *fp = NULL; | ||
1403 | X509 *cert = NULL; | ||
1404 | |||
1405 | if (!(fp = fopen(cert_file, "r"))) | ||
1406 | goto error; | ||
1407 | |||
1408 | SSL_ERROR_CHECK_GOTO_ERROR(!(cert = PEM_read_X509(fp, NULL, NULL, NULL))); | ||
1409 | |||
1410 | fclose(fp); | ||
1411 | |||
1412 | SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(svr->ssl_ctx, cert) < 1); | ||
1413 | |||
1414 | return EINA_TRUE; | ||
1415 | |||
1416 | error: | ||
1417 | if (fp) | ||
1418 | fclose(fp); | ||
1419 | _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); | ||
1420 | return EINA_FALSE; | ||
1421 | } | ||
1422 | |||
1423 | static Ecore_Con_Ssl_Error | ||
1424 | _ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr) | ||
1425 | { | ||
1426 | if (svr->ssl) | ||
1427 | { | ||
1428 | if (!SSL_shutdown(svr->ssl)) | ||
1429 | SSL_shutdown(svr->ssl); | ||
1430 | |||
1431 | SSL_free(svr->ssl); | ||
1432 | } | ||
1433 | |||
1434 | if (svr->ssl_ctx) | ||
1435 | SSL_CTX_free(svr->ssl_ctx); | ||
1436 | |||
1437 | svr->ssl = NULL; | ||
1438 | svr->ssl_ctx = NULL; | ||
1439 | svr->ssl_err = SSL_ERROR_NONE; | ||
1440 | |||
1441 | return ECORE_CON_SSL_ERROR_NONE; | ||
1442 | } | ||
1443 | |||
1444 | static int | ||
1445 | _ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr, | ||
1446 | unsigned char *buf, | ||
1447 | int size) | ||
1448 | { | ||
1449 | int num; | ||
1450 | |||
1451 | if (!svr->ssl) return -1; | ||
1452 | num = SSL_read(svr->ssl, buf, size); | ||
1453 | svr->ssl_err = SSL_get_error(svr->ssl, num); | ||
1454 | |||
1455 | if (svr->fd_handler) | ||
1456 | { | ||
1457 | if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ) | ||
1458 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
1459 | else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE) | ||
1460 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); | ||
1461 | } | ||
1462 | |||
1463 | if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) || | ||
1464 | (svr->ssl_err == SSL_ERROR_SYSCALL) || | ||
1465 | (svr->ssl_err == SSL_ERROR_SSL)) | ||
1466 | return -1; | ||
1467 | |||
1468 | if (num < 0) | ||
1469 | return 0; | ||
1470 | |||
1471 | return num; | ||
1472 | } | ||
1473 | |||
1474 | static int | ||
1475 | _ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr, | ||
1476 | const unsigned char *buf, | ||
1477 | int size) | ||
1478 | { | ||
1479 | int num; | ||
1480 | |||
1481 | num = SSL_write(svr->ssl, buf, size); | ||
1482 | svr->ssl_err = SSL_get_error(svr->ssl, num); | ||
1483 | |||
1484 | if (svr->fd_handler) | ||
1485 | { | ||
1486 | if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ) | ||
1487 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); | ||
1488 | else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE) | ||
1489 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); | ||
1490 | } | ||
1491 | |||
1492 | if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) || | ||
1493 | (svr->ssl_err == SSL_ERROR_SYSCALL) || | ||
1494 | (svr->ssl_err == SSL_ERROR_SSL)) | ||
1495 | return -1; | ||
1496 | |||
1497 | if (num < 0) | ||
1498 | return 0; | ||
1499 | |||
1500 | return num; | ||
1501 | } | ||
1502 | |||
1503 | static Ecore_Con_Ssl_Error | ||
1504 | _ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl) | ||
1505 | { | ||
1506 | int ret = -1; | ||
1507 | switch (cl->ssl_state) | ||
1508 | { | ||
1509 | case ECORE_CON_SSL_STATE_DONE: | ||
1510 | return ECORE_CON_SSL_ERROR_NONE; | ||
1511 | |||
1512 | case ECORE_CON_SSL_STATE_INIT: | ||
1513 | SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx))); | ||
1514 | |||
1515 | SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd)); | ||
1516 | SSL_set_accept_state(cl->ssl); | ||
1517 | cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; | ||
1518 | |||
1519 | case ECORE_CON_SSL_STATE_HANDSHAKING: | ||
1520 | if (!cl->ssl) | ||
1521 | { | ||
1522 | DBG("Client was previously lost, going to error condition"); | ||
1523 | goto error; | ||
1524 | } | ||
1525 | ret = SSL_do_handshake(cl->ssl); | ||
1526 | cl->ssl_err = SSL_get_error(cl->ssl, ret); | ||
1527 | SSL_ERROR_CHECK_GOTO_ERROR((cl->ssl_err == SSL_ERROR_SYSCALL) || (cl->ssl_err == SSL_ERROR_SSL)); | ||
1528 | if (ret == 1) | ||
1529 | { | ||
1530 | cl->handshaking = EINA_FALSE; | ||
1531 | cl->ssl_state = ECORE_CON_SSL_STATE_DONE; | ||
1532 | } | ||
1533 | else | ||
1534 | { | ||
1535 | if (cl->ssl_err == SSL_ERROR_WANT_READ) | ||
1536 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); | ||
1537 | else if (cl->ssl_err == SSL_ERROR_WANT_WRITE) | ||
1538 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); | ||
1539 | return ECORE_CON_SSL_ERROR_NONE; | ||
1540 | } | ||
1541 | |||
1542 | default: | ||
1543 | break; | ||
1544 | } | ||
1545 | |||
1546 | #ifdef ISCOMFITOR | ||
1547 | { | ||
1548 | /* print session info into DBG */ | ||
1549 | SSL_SESSION *s; | ||
1550 | BIO *b; | ||
1551 | char log[4096]; | ||
1552 | |||
1553 | memset(log, 0, sizeof(log)); | ||
1554 | s = SSL_get_session(cl->ssl); | ||
1555 | b = BIO_new(BIO_s_mem()); | ||
1556 | SSL_SESSION_print(b, s); | ||
1557 | while (BIO_read(b, log, sizeof(log)) > 0) | ||
1558 | DBG("%s", log); | ||
1559 | |||
1560 | BIO_free(b); | ||
1561 | } | ||
1562 | #endif | ||
1563 | |||
1564 | if (!cl->host_server->verify) | ||
1565 | /* not verifying certificates, so we're done! */ | ||
1566 | return ECORE_CON_SSL_ERROR_NONE; | ||
1567 | SSL_set_verify(cl->ssl, SSL_VERIFY_PEER, NULL); | ||
1568 | /* use CRL/CA lists to verify */ | ||
1569 | if (SSL_get_peer_certificate(cl->ssl)) | ||
1570 | SSL_ERROR_CHECK_GOTO_ERROR(SSL_get_verify_result(cl->ssl)); | ||
1571 | |||
1572 | return ECORE_CON_SSL_ERROR_NONE; | ||
1573 | |||
1574 | error: | ||
1575 | _openssl_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR); | ||
1576 | _ecore_con_ssl_client_shutdown_openssl(cl); | ||
1577 | return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; | ||
1578 | } | ||
1579 | |||
1580 | static Ecore_Con_Ssl_Error | ||
1581 | _ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl) | ||
1582 | { | ||
1583 | if (cl->ssl) | ||
1584 | { | ||
1585 | if (!SSL_shutdown(cl->ssl)) | ||
1586 | SSL_shutdown(cl->ssl); | ||
1587 | |||
1588 | SSL_free(cl->ssl); | ||
1589 | } | ||
1590 | |||
1591 | cl->ssl = NULL; | ||
1592 | cl->ssl_err = SSL_ERROR_NONE; | ||
1593 | |||
1594 | return ECORE_CON_SSL_ERROR_NONE; | ||
1595 | } | ||
1596 | |||
1597 | static int | ||
1598 | _ecore_con_ssl_client_read_openssl(Ecore_Con_Client *cl, | ||
1599 | unsigned char *buf, | ||
1600 | int size) | ||
1601 | { | ||
1602 | int num; | ||
1603 | |||
1604 | if (!cl->ssl) return -1; | ||
1605 | num = SSL_read(cl->ssl, buf, size); | ||
1606 | cl->ssl_err = SSL_get_error(cl->ssl, num); | ||
1607 | |||
1608 | if (cl->fd_handler) | ||
1609 | { | ||
1610 | if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ) | ||
1611 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); | ||
1612 | else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE) | ||
1613 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); | ||
1614 | } | ||
1615 | |||
1616 | if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) || | ||
1617 | (cl->ssl_err == SSL_ERROR_SYSCALL) || | ||
1618 | (cl->ssl_err == SSL_ERROR_SSL)) | ||
1619 | return -1; | ||
1620 | |||
1621 | if (num < 0) | ||
1622 | return 0; | ||
1623 | |||
1624 | return num; | ||
1625 | } | ||
1626 | |||
1627 | static int | ||
1628 | _ecore_con_ssl_client_write_openssl(Ecore_Con_Client *cl, | ||
1629 | const unsigned char *buf, | ||
1630 | int size) | ||
1631 | { | ||
1632 | int num; | ||
1633 | |||
1634 | num = SSL_write(cl->ssl, buf, size); | ||
1635 | cl->ssl_err = SSL_get_error(cl->ssl, num); | ||
1636 | |||
1637 | if (cl->fd_handler) | ||
1638 | { | ||
1639 | if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ) | ||
1640 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); | ||
1641 | else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE) | ||
1642 | ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); | ||
1643 | } | ||
1644 | |||
1645 | if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) || | ||
1646 | (cl->ssl_err == SSL_ERROR_SYSCALL) || | ||
1647 | (cl->ssl_err == SSL_ERROR_SSL)) | ||
1648 | return -1; | ||
1649 | |||
1650 | if (num < 0) | ||
1651 | return 0; | ||
1652 | |||
1653 | return num; | ||
1654 | } | ||
1655 | |||
1656 | #else | ||
1657 | |||
1658 | /* | ||
1659 | * No Ssl | ||
1660 | */ | ||
1661 | |||
1662 | static Ecore_Con_Ssl_Error | ||
1663 | _ecore_con_ssl_init_none(void) | ||
1664 | { | ||
1665 | return ECORE_CON_SSL_ERROR_NONE; | ||
1666 | } | ||
1667 | |||
1668 | static Ecore_Con_Ssl_Error | ||
1669 | _ecore_con_ssl_shutdown_none(void) | ||
1670 | { | ||
1671 | return ECORE_CON_SSL_ERROR_NONE; | ||
1672 | } | ||
1673 | |||
1674 | static Ecore_Con_Ssl_Error | ||
1675 | _ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr __UNUSED__, | ||
1676 | int ssl_type __UNUSED__) | ||
1677 | { | ||
1678 | return ECORE_CON_SSL_ERROR_NONE; | ||
1679 | } | ||
1680 | |||
1681 | static Ecore_Con_Ssl_Error | ||
1682 | _ecore_con_ssl_server_upgrade_none(Ecore_Con_Server *svr __UNUSED__) | ||
1683 | { | ||
1684 | return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; | ||
1685 | } | ||
1686 | |||
1687 | static Ecore_Con_Ssl_Error | ||
1688 | _ecore_con_ssl_server_init_none(Ecore_Con_Server *svr __UNUSED__) | ||
1689 | { | ||
1690 | return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; | ||
1691 | } | ||
1692 | |||
1693 | static Eina_Bool | ||
1694 | _ecore_con_ssl_server_cafile_add_none(Ecore_Con_Server *svr __UNUSED__, | ||
1695 | const char *ca_file __UNUSED__) | ||
1696 | { | ||
1697 | return EINA_FALSE; | ||
1698 | } | ||
1699 | |||
1700 | static Eina_Bool | ||
1701 | _ecore_con_ssl_server_cert_add_none(Ecore_Con_Server *svr __UNUSED__, | ||
1702 | const char *cert_file __UNUSED__) | ||
1703 | { | ||
1704 | return EINA_FALSE; | ||
1705 | } | ||
1706 | |||
1707 | static Eina_Bool | ||
1708 | _ecore_con_ssl_server_privkey_add_none(Ecore_Con_Server *svr __UNUSED__, | ||
1709 | const char *key_file __UNUSED__) | ||
1710 | { | ||
1711 | return EINA_FALSE; | ||
1712 | } | ||
1713 | |||
1714 | static Eina_Bool | ||
1715 | _ecore_con_ssl_server_crl_add_none(Ecore_Con_Server *svr __UNUSED__, | ||
1716 | const char *crl_file __UNUSED__) | ||
1717 | { | ||
1718 | return EINA_FALSE; | ||
1719 | } | ||
1720 | |||
1721 | static Ecore_Con_Ssl_Error | ||
1722 | _ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr __UNUSED__) | ||
1723 | { | ||
1724 | return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; | ||
1725 | } | ||
1726 | |||
1727 | static int | ||
1728 | _ecore_con_ssl_server_read_none(Ecore_Con_Server *svr __UNUSED__, | ||
1729 | unsigned char *buf __UNUSED__, | ||
1730 | int size __UNUSED__) | ||
1731 | { | ||
1732 | return -1; | ||
1733 | } | ||
1734 | |||
1735 | static int | ||
1736 | _ecore_con_ssl_server_write_none(Ecore_Con_Server *svr __UNUSED__, | ||
1737 | const unsigned char *buf __UNUSED__, | ||
1738 | int size __UNUSED__) | ||
1739 | { | ||
1740 | return -1; | ||
1741 | } | ||
1742 | |||
1743 | static Ecore_Con_Ssl_Error | ||
1744 | _ecore_con_ssl_client_upgrade_none(Ecore_Con_Client *cl __UNUSED__) | ||
1745 | { | ||
1746 | return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; | ||
1747 | } | ||
1748 | |||
1749 | static Ecore_Con_Ssl_Error | ||
1750 | _ecore_con_ssl_client_init_none(Ecore_Con_Client *cl __UNUSED__) | ||
1751 | { | ||
1752 | return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; | ||
1753 | } | ||
1754 | |||
1755 | static Ecore_Con_Ssl_Error | ||
1756 | _ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl __UNUSED__) | ||
1757 | { | ||
1758 | return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; | ||
1759 | } | ||
1760 | |||
1761 | static int | ||
1762 | _ecore_con_ssl_client_read_none(Ecore_Con_Client *cl __UNUSED__, | ||
1763 | unsigned char *buf __UNUSED__, | ||
1764 | int size __UNUSED__) | ||
1765 | { | ||
1766 | return -1; | ||
1767 | } | ||
1768 | |||
1769 | static int | ||
1770 | _ecore_con_ssl_client_write_none(Ecore_Con_Client *cl __UNUSED__, | ||
1771 | const unsigned char *buf __UNUSED__, | ||
1772 | int size __UNUSED__) | ||
1773 | { | ||
1774 | return -1; | ||
1775 | } | ||
1776 | |||
1777 | #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 new file mode 100644 index 0000000..cfcf095 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con_url.c | |||
@@ -0,0 +1,1572 @@ | |||
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 | int ECORE_CON_EVENT_URL_DATA = 0; | ||
34 | int ECORE_CON_EVENT_URL_COMPLETE = 0; | ||
35 | int ECORE_CON_EVENT_URL_PROGRESS = 0; | ||
36 | |||
37 | #ifdef HAVE_CURL | ||
38 | static Eina_Bool _ecore_con_url_fd_handler(void *data, | ||
39 | Ecore_Fd_Handler *fd_handler); | ||
40 | static Eina_Bool _ecore_con_url_perform(Ecore_Con_Url *url_con); | ||
41 | static size_t _ecore_con_url_header_cb(void *ptr, | ||
42 | size_t size, | ||
43 | size_t nitems, | ||
44 | void *stream); | ||
45 | static size_t _ecore_con_url_data_cb(void *buffer, | ||
46 | size_t size, | ||
47 | size_t nitems, | ||
48 | void *userp); | ||
49 | static int _ecore_con_url_progress_cb(void *clientp, | ||
50 | double dltotal, | ||
51 | double dlnow, | ||
52 | double ultotal, | ||
53 | double ulnow); | ||
54 | static size_t _ecore_con_url_read_cb(void *ptr, | ||
55 | size_t size, | ||
56 | size_t nitems, | ||
57 | void *stream); | ||
58 | static void _ecore_con_event_url_free(void *data __UNUSED__, | ||
59 | void *ev); | ||
60 | static int _ecore_con_url_process_completed_jobs( | ||
61 | Ecore_Con_Url *url_con_to_match); | ||
62 | static Eina_Bool _ecore_con_url_idler_handler(void *data); | ||
63 | |||
64 | static Ecore_Idler *_fd_idler_handler = NULL; | ||
65 | static Eina_List *_url_con_list = NULL; | ||
66 | static CURLM *_curlm = NULL; | ||
67 | static fd_set _current_fd_set; | ||
68 | static int _init_count = 0; | ||
69 | static Ecore_Timer *_curl_timeout = NULL; | ||
70 | static Eina_Bool pipelining = EINA_FALSE; | ||
71 | |||
72 | typedef struct _Ecore_Con_Url_Event Ecore_Con_Url_Event; | ||
73 | struct _Ecore_Con_Url_Event | ||
74 | { | ||
75 | int type; | ||
76 | void *ev; | ||
77 | }; | ||
78 | |||
79 | static Eina_Bool | ||
80 | _url_complete_idler_cb(void *data) | ||
81 | { | ||
82 | Ecore_Con_Url_Event *lev; | ||
83 | |||
84 | lev = data; | ||
85 | ecore_event_add(lev->type, lev->ev, _ecore_con_event_url_free, NULL); | ||
86 | free(lev); | ||
87 | |||
88 | return ECORE_CALLBACK_CANCEL; | ||
89 | } | ||
90 | |||
91 | static void | ||
92 | _url_complete_push_event(int type, | ||
93 | void *ev) | ||
94 | { | ||
95 | Ecore_Con_Url_Event *lev; | ||
96 | |||
97 | lev = malloc(sizeof(Ecore_Con_Url_Event)); | ||
98 | lev->type = type; | ||
99 | lev->ev = ev; | ||
100 | |||
101 | ecore_idler_add(_url_complete_idler_cb, lev); | ||
102 | } | ||
103 | |||
104 | #endif | ||
105 | |||
106 | /** | ||
107 | * @addtogroup Ecore_Con_Url_Group Ecore URL Connection Functions | ||
108 | * | ||
109 | * @{ | ||
110 | */ | ||
111 | |||
112 | EAPI int | ||
113 | ecore_con_url_init(void) | ||
114 | { | ||
115 | #ifdef HAVE_CURL | ||
116 | _init_count++; | ||
117 | |||
118 | if (_init_count > 1) | ||
119 | return _init_count; | ||
120 | |||
121 | if (!ECORE_CON_EVENT_URL_DATA) | ||
122 | { | ||
123 | ECORE_CON_EVENT_URL_DATA = ecore_event_type_new(); | ||
124 | ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new(); | ||
125 | ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new(); | ||
126 | } | ||
127 | |||
128 | if (!_curlm) | ||
129 | { | ||
130 | long ms; | ||
131 | |||
132 | FD_ZERO(&_current_fd_set); | ||
133 | if (curl_global_init(CURL_GLOBAL_ALL)) | ||
134 | { | ||
135 | while (_url_con_list) | ||
136 | ecore_con_url_free(eina_list_data_get(_url_con_list)); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | _curlm = curl_multi_init(); | ||
141 | if (!_curlm) | ||
142 | { | ||
143 | while (_url_con_list) | ||
144 | ecore_con_url_free(eina_list_data_get(_url_con_list)); | ||
145 | |||
146 | _init_count--; | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | curl_multi_timeout(_curlm, &ms); | ||
151 | if (ms <= 0) | ||
152 | ms = 1000; | ||
153 | |||
154 | _curl_timeout = | ||
155 | ecore_timer_add((double)ms / 1000, _ecore_con_url_idler_handler, | ||
156 | (void *)0xACE); | ||
157 | ecore_timer_freeze(_curl_timeout); | ||
158 | } | ||
159 | |||
160 | return 1; | ||
161 | #else | ||
162 | return 0; | ||
163 | #endif | ||
164 | } | ||
165 | |||
166 | EAPI int | ||
167 | ecore_con_url_shutdown(void) | ||
168 | { | ||
169 | #ifdef HAVE_CURL | ||
170 | if (!_init_count) | ||
171 | return 0; | ||
172 | |||
173 | _init_count--; | ||
174 | |||
175 | if (_init_count != 0) | ||
176 | return _init_count; | ||
177 | |||
178 | if (_fd_idler_handler) | ||
179 | ecore_idler_del(_fd_idler_handler); | ||
180 | |||
181 | _fd_idler_handler = NULL; | ||
182 | |||
183 | if (_curl_timeout) | ||
184 | ecore_timer_del(_curl_timeout); | ||
185 | |||
186 | _curl_timeout = NULL; | ||
187 | |||
188 | while (_url_con_list) | ||
189 | ecore_con_url_free(eina_list_data_get(_url_con_list)); | ||
190 | |||
191 | if (_curlm) | ||
192 | { | ||
193 | curl_multi_cleanup(_curlm); | ||
194 | _curlm = NULL; | ||
195 | } | ||
196 | |||
197 | curl_global_cleanup(); | ||
198 | #endif | ||
199 | return 1; | ||
200 | } | ||
201 | |||
202 | EAPI void | ||
203 | ecore_con_url_pipeline_set(Eina_Bool enable) | ||
204 | { | ||
205 | #ifdef HAVE_CURL | ||
206 | if (enable) | ||
207 | curl_multi_setopt(_curlm, CURLMOPT_PIPELINING, 1); | ||
208 | else | ||
209 | curl_multi_setopt(_curlm, CURLMOPT_PIPELINING, 0); | ||
210 | pipelining = enable; | ||
211 | #else | ||
212 | return; | ||
213 | (void)enable; | ||
214 | #endif | ||
215 | } | ||
216 | |||
217 | EAPI Eina_Bool | ||
218 | ecore_con_url_pipeline_get(void) | ||
219 | { | ||
220 | #ifdef HAVE_CURL | ||
221 | return pipelining; | ||
222 | #endif | ||
223 | return EINA_FALSE; | ||
224 | } | ||
225 | |||
226 | EAPI Ecore_Con_Url * | ||
227 | ecore_con_url_new(const char *url) | ||
228 | { | ||
229 | #ifdef HAVE_CURL | ||
230 | Ecore_Con_Url *url_con; | ||
231 | CURLcode ret; | ||
232 | |||
233 | if (!_init_count) | ||
234 | return NULL; | ||
235 | |||
236 | url_con = calloc(1, sizeof(Ecore_Con_Url)); | ||
237 | if (!url_con) | ||
238 | return NULL; | ||
239 | |||
240 | url_con->fd = -1; | ||
241 | url_con->write_fd = -1; | ||
242 | |||
243 | url_con->curl_easy = curl_easy_init(); | ||
244 | if (!url_con->curl_easy) | ||
245 | { | ||
246 | free(url_con); | ||
247 | return NULL; | ||
248 | } | ||
249 | |||
250 | ECORE_MAGIC_SET(url_con, ECORE_MAGIC_CON_URL); | ||
251 | |||
252 | if (!ecore_con_url_url_set(url_con, url)) | ||
253 | { | ||
254 | ecore_con_url_free(url_con); | ||
255 | return NULL; | ||
256 | } | ||
257 | |||
258 | ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate"); | ||
259 | if (ret != CURLE_OK) | ||
260 | { | ||
261 | ERR("Could not set CURLOPT_ENCODING to \"gzip,deflate\": %s", | ||
262 | curl_easy_strerror(ret)); | ||
263 | ecore_con_url_free(url_con); | ||
264 | return NULL; | ||
265 | } | ||
266 | |||
267 | curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEFUNCTION, | ||
268 | _ecore_con_url_data_cb); | ||
269 | curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEDATA, url_con); | ||
270 | |||
271 | curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, | ||
272 | _ecore_con_url_progress_cb); | ||
273 | curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSDATA, url_con); | ||
274 | curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_FALSE); | ||
275 | |||
276 | curl_easy_setopt(url_con->curl_easy, CURLOPT_HEADERFUNCTION, | ||
277 | _ecore_con_url_header_cb); | ||
278 | curl_easy_setopt(url_con->curl_easy, CURLOPT_HEADERDATA, url_con); | ||
279 | |||
280 | /* | ||
281 | * FIXME: Check that these timeouts are sensible defaults | ||
282 | * FIXME: Provide a means to change these timeouts | ||
283 | */ | ||
284 | curl_easy_setopt(url_con->curl_easy, CURLOPT_CONNECTTIMEOUT, 30); | ||
285 | curl_easy_setopt(url_con->curl_easy, CURLOPT_FOLLOWLOCATION, 1); | ||
286 | |||
287 | return url_con; | ||
288 | #else | ||
289 | return NULL; | ||
290 | url = NULL; | ||
291 | #endif | ||
292 | } | ||
293 | |||
294 | EAPI Ecore_Con_Url * | ||
295 | ecore_con_url_custom_new(const char *url, | ||
296 | const char *custom_request) | ||
297 | { | ||
298 | #ifdef HAVE_CURL | ||
299 | Ecore_Con_Url *url_con; | ||
300 | CURLcode ret; | ||
301 | |||
302 | if (!url) | ||
303 | return NULL; | ||
304 | |||
305 | if (!custom_request) | ||
306 | return NULL; | ||
307 | |||
308 | url_con = ecore_con_url_new(url); | ||
309 | |||
310 | if (!url_con) | ||
311 | return NULL; | ||
312 | |||
313 | ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_CUSTOMREQUEST, custom_request); | ||
314 | if (ret != CURLE_OK) | ||
315 | { | ||
316 | ERR("Could not set a custom request string: %s", | ||
317 | curl_easy_strerror(ret)); | ||
318 | ecore_con_url_free(url_con); | ||
319 | return NULL; | ||
320 | } | ||
321 | |||
322 | return url_con; | ||
323 | #else | ||
324 | return NULL; | ||
325 | url = NULL; | ||
326 | custom_request = NULL; | ||
327 | #endif | ||
328 | } | ||
329 | |||
330 | EAPI void | ||
331 | ecore_con_url_free(Ecore_Con_Url *url_con) | ||
332 | { | ||
333 | #ifdef HAVE_CURL | ||
334 | char *s; | ||
335 | CURLMcode ret; | ||
336 | |||
337 | if (!url_con) | ||
338 | return; | ||
339 | |||
340 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
341 | { | ||
342 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_free"); | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE); | ||
347 | if(url_con->fd != -1) | ||
348 | { | ||
349 | FD_CLR(url_con->fd, &_current_fd_set); | ||
350 | if (url_con->fd_handler) | ||
351 | ecore_main_fd_handler_del(url_con->fd_handler); | ||
352 | |||
353 | url_con->fd = -1; | ||
354 | url_con->fd_handler = NULL; | ||
355 | } | ||
356 | |||
357 | if (url_con->curl_easy) | ||
358 | { | ||
359 | // FIXME: For an unknown reason, progress continue to arrive after destruction | ||
360 | // this prevent any further call to the callback. | ||
361 | curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL); | ||
362 | curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_TRUE); | ||
363 | |||
364 | if (url_con->active) | ||
365 | { | ||
366 | url_con->active = EINA_FALSE; | ||
367 | |||
368 | ret = curl_multi_remove_handle(_curlm, url_con->curl_easy); | ||
369 | if (ret != CURLM_OK) | ||
370 | ERR("curl_multi_remove_handle failed: %s", | ||
371 | curl_multi_strerror(ret)); | ||
372 | } | ||
373 | |||
374 | curl_easy_cleanup(url_con->curl_easy); | ||
375 | } | ||
376 | |||
377 | _url_con_list = eina_list_remove(_url_con_list, url_con); | ||
378 | curl_slist_free_all(url_con->headers); | ||
379 | EINA_LIST_FREE(url_con->additional_headers, s) | ||
380 | free(s); | ||
381 | EINA_LIST_FREE(url_con->response_headers, s) | ||
382 | free(s); | ||
383 | eina_stringshare_del(url_con->url); | ||
384 | free(url_con); | ||
385 | #else | ||
386 | return; | ||
387 | (void)url_con; | ||
388 | #endif | ||
389 | } | ||
390 | |||
391 | EAPI const char * | ||
392 | ecore_con_url_url_get(Ecore_Con_Url *url_con) | ||
393 | { | ||
394 | #ifdef HAVE_CURL | ||
395 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
396 | { | ||
397 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, __func__); | ||
398 | return NULL; | ||
399 | } | ||
400 | return url_con->url; | ||
401 | #else | ||
402 | return NULL; | ||
403 | (void)url_con; | ||
404 | #endif | ||
405 | } | ||
406 | |||
407 | EAPI Eina_Bool | ||
408 | ecore_con_url_url_set(Ecore_Con_Url *url_con, | ||
409 | const char *url) | ||
410 | { | ||
411 | #ifdef HAVE_CURL | ||
412 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
413 | { | ||
414 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_url_set"); | ||
415 | return EINA_FALSE; | ||
416 | } | ||
417 | |||
418 | if (url_con->active) | ||
419 | return EINA_FALSE; | ||
420 | |||
421 | eina_stringshare_replace(&url_con->url, url); | ||
422 | |||
423 | if (url_con->url) | ||
424 | curl_easy_setopt(url_con->curl_easy, CURLOPT_URL, | ||
425 | url_con->url); | ||
426 | else | ||
427 | curl_easy_setopt(url_con->curl_easy, CURLOPT_URL, ""); | ||
428 | |||
429 | return EINA_TRUE; | ||
430 | #else | ||
431 | return EINA_FALSE; | ||
432 | (void)url; | ||
433 | (void)url_con; | ||
434 | #endif | ||
435 | } | ||
436 | |||
437 | EAPI void | ||
438 | ecore_con_url_data_set(Ecore_Con_Url *url_con, | ||
439 | void *data) | ||
440 | { | ||
441 | #ifdef HAVE_CURL | ||
442 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
443 | { | ||
444 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_set"); | ||
445 | return; | ||
446 | } | ||
447 | |||
448 | url_con->data = data; | ||
449 | #else | ||
450 | return; | ||
451 | url_con = NULL; | ||
452 | data = NULL; | ||
453 | #endif | ||
454 | } | ||
455 | |||
456 | EAPI void | ||
457 | ecore_con_url_additional_header_add(Ecore_Con_Url *url_con, | ||
458 | const char *key, | ||
459 | const char *value) | ||
460 | { | ||
461 | #ifdef HAVE_CURL | ||
462 | char *tmp; | ||
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_header_add"); | ||
468 | return; | ||
469 | } | ||
470 | |||
471 | tmp = malloc(strlen(key) + strlen(value) + 3); | ||
472 | if (!tmp) | ||
473 | return; | ||
474 | |||
475 | sprintf(tmp, "%s: %s", key, value); | ||
476 | url_con->additional_headers = eina_list_append(url_con->additional_headers, | ||
477 | tmp); | ||
478 | #else | ||
479 | return; | ||
480 | url_con = NULL; | ||
481 | key = NULL; | ||
482 | value = NULL; | ||
483 | #endif | ||
484 | } | ||
485 | |||
486 | EAPI void | ||
487 | ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con) | ||
488 | { | ||
489 | #ifdef HAVE_CURL | ||
490 | char *s; | ||
491 | |||
492 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
493 | { | ||
494 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
495 | "ecore_con_url_additional_headers_clear"); | ||
496 | return; | ||
497 | } | ||
498 | |||
499 | EINA_LIST_FREE(url_con->additional_headers, s) | ||
500 | free(s); | ||
501 | #else | ||
502 | return; | ||
503 | url_con = NULL; | ||
504 | #endif | ||
505 | } | ||
506 | |||
507 | EAPI void * | ||
508 | ecore_con_url_data_get(Ecore_Con_Url *url_con) | ||
509 | { | ||
510 | #ifdef HAVE_CURL | ||
511 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
512 | { | ||
513 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_get"); | ||
514 | return NULL; | ||
515 | } | ||
516 | |||
517 | return url_con->data; | ||
518 | #else | ||
519 | return NULL; | ||
520 | url_con = NULL; | ||
521 | #endif | ||
522 | } | ||
523 | |||
524 | EAPI void | ||
525 | ecore_con_url_time(Ecore_Con_Url *url_con, | ||
526 | Ecore_Con_Url_Time condition, | ||
527 | double timestamp) | ||
528 | { | ||
529 | #ifdef HAVE_CURL | ||
530 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
531 | { | ||
532 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_time"); | ||
533 | return; | ||
534 | } | ||
535 | |||
536 | url_con->time_condition = condition; | ||
537 | url_con->timestamp = timestamp; | ||
538 | #else | ||
539 | return; | ||
540 | (void)url_con; | ||
541 | (void)condition; | ||
542 | (void)timestamp; | ||
543 | #endif | ||
544 | } | ||
545 | |||
546 | EAPI void | ||
547 | ecore_con_url_fd_set(Ecore_Con_Url *url_con, | ||
548 | int fd) | ||
549 | { | ||
550 | #ifdef HAVE_CURL | ||
551 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
552 | { | ||
553 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_set"); | ||
554 | return; | ||
555 | } | ||
556 | |||
557 | url_con->write_fd = fd; | ||
558 | #else | ||
559 | return; | ||
560 | (void)url_con; | ||
561 | (void)fd; | ||
562 | #endif | ||
563 | } | ||
564 | |||
565 | EAPI int | ||
566 | ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con) | ||
567 | { | ||
568 | #ifdef HAVE_CURL | ||
569 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
570 | { | ||
571 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
572 | "ecore_con_url_received_bytes_get"); | ||
573 | return -1; | ||
574 | } | ||
575 | |||
576 | return url_con->received; | ||
577 | #else | ||
578 | return 0; | ||
579 | (void)url_con; | ||
580 | #endif | ||
581 | } | ||
582 | |||
583 | EAPI const Eina_List * | ||
584 | ecore_con_url_response_headers_get(Ecore_Con_Url *url_con) | ||
585 | { | ||
586 | #ifdef HAVE_CURL | ||
587 | return url_con->response_headers; | ||
588 | #else | ||
589 | return NULL; | ||
590 | (void)url_con; | ||
591 | #endif | ||
592 | } | ||
593 | |||
594 | EAPI Eina_Bool | ||
595 | ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, | ||
596 | const char *username, | ||
597 | const char *password, | ||
598 | Eina_Bool safe) | ||
599 | { | ||
600 | #ifdef HAVE_CURL | ||
601 | CURLcode ret; | ||
602 | |||
603 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
604 | { | ||
605 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
606 | "ecore_con_url_httpauth_set"); | ||
607 | return EINA_FALSE; | ||
608 | } | ||
609 | |||
610 | # if LIBCURL_VERSION_NUM >= 0x071301 | ||
611 | if ((username) && (password)) | ||
612 | { | ||
613 | if (safe) | ||
614 | curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPAUTH, | ||
615 | CURLAUTH_ANYSAFE); | ||
616 | else | ||
617 | curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPAUTH, CURLAUTH_ANY); | ||
618 | |||
619 | ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERNAME, username); | ||
620 | if (ret != CURLE_OK) | ||
621 | { | ||
622 | ERR("Could not set username for HTTP authentication: %s", | ||
623 | curl_easy_strerror(ret)); | ||
624 | return EINA_FALSE; | ||
625 | } | ||
626 | |||
627 | ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_PASSWORD, password); | ||
628 | if (ret != CURLE_OK) | ||
629 | { | ||
630 | ERR("Could not set password for HTTP authentication: %s", | ||
631 | curl_easy_strerror(ret)); | ||
632 | return EINA_FALSE; | ||
633 | } | ||
634 | |||
635 | return EINA_TRUE; | ||
636 | } | ||
637 | # endif | ||
638 | #else | ||
639 | return EINA_FALSE; | ||
640 | (void)url_con; | ||
641 | (void)username; | ||
642 | (void)password; | ||
643 | (void)safe; | ||
644 | #endif | ||
645 | |||
646 | return EINA_FALSE; | ||
647 | } | ||
648 | |||
649 | #define MODE_AUTO 0 | ||
650 | #define MODE_GET 1 | ||
651 | #define MODE_POST 2 | ||
652 | |||
653 | static Eina_Bool | ||
654 | _ecore_con_url_send(Ecore_Con_Url *url_con, | ||
655 | int mode, | ||
656 | const void *data, | ||
657 | long length, | ||
658 | const char *content_type) | ||
659 | { | ||
660 | #ifdef HAVE_CURL | ||
661 | Eina_List *l; | ||
662 | const char *s; | ||
663 | char tmp[256]; | ||
664 | |||
665 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
666 | { | ||
667 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_send"); | ||
668 | return EINA_FALSE; | ||
669 | } | ||
670 | |||
671 | if (url_con->active) | ||
672 | return EINA_FALSE; | ||
673 | |||
674 | if (!url_con->url) | ||
675 | return EINA_FALSE; | ||
676 | |||
677 | /* Free response headers from previous send() calls */ | ||
678 | EINA_LIST_FREE(url_con->response_headers, s) | ||
679 | free((char *)s); | ||
680 | url_con->response_headers = NULL; | ||
681 | |||
682 | curl_slist_free_all(url_con->headers); | ||
683 | url_con->headers = NULL; | ||
684 | |||
685 | if ((mode == MODE_POST) || (mode == MODE_AUTO)) | ||
686 | { | ||
687 | if (data) | ||
688 | { | ||
689 | if ((content_type) && (strlen(content_type) < 200)) | ||
690 | { | ||
691 | snprintf(tmp, sizeof(tmp), "Content-Type: %s", content_type); | ||
692 | url_con->headers = curl_slist_append(url_con->headers, tmp); | ||
693 | } | ||
694 | |||
695 | curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, data); | ||
696 | curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, length); | ||
697 | } | ||
698 | else curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, 0); | ||
699 | if (mode == MODE_POST) | ||
700 | curl_easy_setopt(url_con->curl_easy, CURLOPT_POST, 1); | ||
701 | } | ||
702 | |||
703 | switch (url_con->time_condition) | ||
704 | { | ||
705 | case ECORE_CON_URL_TIME_NONE: | ||
706 | curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION, | ||
707 | CURL_TIMECOND_NONE); | ||
708 | break; | ||
709 | |||
710 | case ECORE_CON_URL_TIME_IFMODSINCE: | ||
711 | curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION, | ||
712 | CURL_TIMECOND_IFMODSINCE); | ||
713 | curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE, | ||
714 | (long)url_con->timestamp); | ||
715 | break; | ||
716 | |||
717 | case ECORE_CON_URL_TIME_IFUNMODSINCE: | ||
718 | curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION, | ||
719 | CURL_TIMECOND_IFUNMODSINCE); | ||
720 | curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE, | ||
721 | (long)url_con->timestamp); | ||
722 | break; | ||
723 | } | ||
724 | |||
725 | /* Additional headers */ | ||
726 | EINA_LIST_FOREACH(url_con->additional_headers, l, s) | ||
727 | url_con->headers = curl_slist_append(url_con->headers, s); | ||
728 | |||
729 | curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPHEADER, url_con->headers); | ||
730 | |||
731 | url_con->received = 0; | ||
732 | |||
733 | return _ecore_con_url_perform(url_con); | ||
734 | #else | ||
735 | return EINA_FALSE; | ||
736 | (void)url_con; | ||
737 | (void)mode; | ||
738 | (void)data; | ||
739 | (void)length; | ||
740 | (void)content_type; | ||
741 | #endif | ||
742 | } | ||
743 | |||
744 | EINA_DEPRECATED EAPI Eina_Bool | ||
745 | ecore_con_url_send(Ecore_Con_Url *url_con, | ||
746 | const void *data, | ||
747 | long length, | ||
748 | const char *content_type) | ||
749 | { | ||
750 | return _ecore_con_url_send(url_con, MODE_AUTO, data, length, content_type); | ||
751 | } | ||
752 | |||
753 | EAPI Eina_Bool | ||
754 | ecore_con_url_get(Ecore_Con_Url *url_con) | ||
755 | { | ||
756 | return _ecore_con_url_send(url_con, MODE_GET, NULL, 0, NULL); | ||
757 | } | ||
758 | |||
759 | EAPI Eina_Bool | ||
760 | ecore_con_url_post(Ecore_Con_Url *url_con, | ||
761 | const void *data, | ||
762 | long length, | ||
763 | const char *content_type) | ||
764 | { | ||
765 | return _ecore_con_url_send(url_con, MODE_POST, data, length, content_type); | ||
766 | } | ||
767 | |||
768 | EAPI Eina_Bool | ||
769 | ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, | ||
770 | const char *filename, | ||
771 | const char *user, | ||
772 | const char *pass, | ||
773 | const char *upload_dir) | ||
774 | { | ||
775 | #ifdef HAVE_CURL | ||
776 | char url[4096]; | ||
777 | char userpwd[4096]; | ||
778 | FILE *fd; | ||
779 | struct stat file_info; | ||
780 | CURLcode ret; | ||
781 | |||
782 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
783 | { | ||
784 | ECORE_MAGIC_FAIL(url_con, | ||
785 | ECORE_MAGIC_CON_URL, | ||
786 | "ecore_con_url_ftp_upload"); | ||
787 | return EINA_FALSE; | ||
788 | } | ||
789 | |||
790 | if (url_con->active) | ||
791 | return EINA_FALSE; | ||
792 | |||
793 | if (!url_con->url) | ||
794 | return EINA_FALSE; | ||
795 | |||
796 | if (filename) | ||
797 | { | ||
798 | if (stat(filename, &file_info)) | ||
799 | return EINA_FALSE; | ||
800 | |||
801 | snprintf(userpwd, sizeof(userpwd), "%s:%s", user, pass); | ||
802 | ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERPWD, userpwd); | ||
803 | if (ret != CURLE_OK) | ||
804 | { | ||
805 | ERR("Could not set username and password for FTP upload: %s", | ||
806 | curl_easy_strerror(ret)); | ||
807 | return EINA_FALSE; | ||
808 | } | ||
809 | |||
810 | char tmp[PATH_MAX]; | ||
811 | snprintf(tmp, PATH_MAX, "%s", filename); | ||
812 | |||
813 | if (upload_dir) | ||
814 | snprintf(url, sizeof(url), "ftp://%s/%s/%s", url_con->url, | ||
815 | upload_dir, basename(tmp)); | ||
816 | else | ||
817 | snprintf(url, sizeof(url), "ftp://%s/%s", url_con->url, | ||
818 | basename(tmp)); | ||
819 | |||
820 | if (!ecore_con_url_url_set(url_con, url)) | ||
821 | return EINA_FALSE; | ||
822 | |||
823 | curl_easy_setopt(url_con->curl_easy, CURLOPT_INFILESIZE_LARGE, | ||
824 | (curl_off_t)file_info.st_size); | ||
825 | curl_easy_setopt(url_con->curl_easy, CURLOPT_UPLOAD, 1); | ||
826 | curl_easy_setopt(url_con->curl_easy, CURLOPT_READFUNCTION, | ||
827 | _ecore_con_url_read_cb); | ||
828 | |||
829 | fd = fopen(filename, "rb"); | ||
830 | if (!fd) | ||
831 | { | ||
832 | ERR("Could not open \"%s\" for FTP upload", filename); | ||
833 | return EINA_FALSE; | ||
834 | } | ||
835 | curl_easy_setopt(url_con->curl_easy, CURLOPT_READDATA, fd); | ||
836 | |||
837 | return _ecore_con_url_perform(url_con); | ||
838 | } | ||
839 | #else | ||
840 | return EINA_FALSE; | ||
841 | (void)url_con; | ||
842 | (void)filename; | ||
843 | (void)user; | ||
844 | (void)pass; | ||
845 | (void)upload_dir; | ||
846 | #endif | ||
847 | |||
848 | return EINA_FALSE; | ||
849 | } | ||
850 | |||
851 | EAPI void | ||
852 | ecore_con_url_cookies_init(Ecore_Con_Url *url_con) | ||
853 | { | ||
854 | #ifdef HAVE_CURL | ||
855 | if (!url_con) | ||
856 | return; | ||
857 | |||
858 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
859 | { | ||
860 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
861 | "ecore_con_url_cookies_init"); | ||
862 | return; | ||
863 | } | ||
864 | |||
865 | curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, ""); | ||
866 | #else | ||
867 | return; | ||
868 | (void)url_con; | ||
869 | #endif | ||
870 | } | ||
871 | |||
872 | EAPI void | ||
873 | ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, Eina_Bool ignore) | ||
874 | { | ||
875 | #ifdef HAVE_CURL | ||
876 | if (!url_con) | ||
877 | return; | ||
878 | |||
879 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
880 | { | ||
881 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
882 | "ecore_con_url_cookies_ignore_old_session_set"); | ||
883 | return; | ||
884 | } | ||
885 | |||
886 | curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIESESSION, ignore); | ||
887 | #else | ||
888 | return; | ||
889 | (void)url_con; | ||
890 | (void)ignore; | ||
891 | #endif | ||
892 | } | ||
893 | |||
894 | EAPI void | ||
895 | ecore_con_url_cookies_clear(Ecore_Con_Url *url_con) | ||
896 | { | ||
897 | #ifdef HAVE_CURL | ||
898 | if (!url_con) | ||
899 | return; | ||
900 | |||
901 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
902 | { | ||
903 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
904 | "ecore_con_url_cookies_clear"); | ||
905 | return; | ||
906 | } | ||
907 | |||
908 | curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "ALL"); | ||
909 | #else | ||
910 | return; | ||
911 | (void)url_con; | ||
912 | #endif | ||
913 | } | ||
914 | |||
915 | EAPI void | ||
916 | ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con) | ||
917 | { | ||
918 | #ifdef HAVE_CURL | ||
919 | if (!url_con) | ||
920 | return; | ||
921 | |||
922 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
923 | { | ||
924 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
925 | "ecore_con_url_cookies_session_clear"); | ||
926 | return; | ||
927 | } | ||
928 | |||
929 | curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "SESS"); | ||
930 | #else | ||
931 | return; | ||
932 | (void)url_con; | ||
933 | #endif | ||
934 | } | ||
935 | |||
936 | EAPI void | ||
937 | ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, const char * const file_name) | ||
938 | { | ||
939 | #ifdef HAVE_CURL | ||
940 | if (!url_con) | ||
941 | return; | ||
942 | |||
943 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
944 | { | ||
945 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
946 | "ecore_con_url_cookies_file_add"); | ||
947 | return; | ||
948 | } | ||
949 | |||
950 | curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, file_name); | ||
951 | #else | ||
952 | return; | ||
953 | (void)url_con; | ||
954 | (void)file_name; | ||
955 | #endif | ||
956 | } | ||
957 | |||
958 | EAPI Eina_Bool | ||
959 | ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, const char * const cookiejar_file) | ||
960 | { | ||
961 | #ifdef HAVE_CURL | ||
962 | CURLcode ret; | ||
963 | |||
964 | if (!url_con) | ||
965 | return EINA_FALSE; | ||
966 | |||
967 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
968 | { | ||
969 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
970 | "ecore_con_url_cookies_jar_file_set"); | ||
971 | return EINA_FALSE; | ||
972 | } | ||
973 | |||
974 | ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEJAR, | ||
975 | cookiejar_file); | ||
976 | if (ret != CURLE_OK) | ||
977 | { | ||
978 | ERR("Setting the cookie-jar name failed: %s", | ||
979 | curl_easy_strerror(ret)); | ||
980 | return EINA_FALSE; | ||
981 | } | ||
982 | |||
983 | return EINA_TRUE; | ||
984 | #else | ||
985 | return EINA_FALSE; | ||
986 | (void)url_con; | ||
987 | (void)cookiejar_file; | ||
988 | #endif | ||
989 | } | ||
990 | |||
991 | EAPI void | ||
992 | ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con) | ||
993 | { | ||
994 | #ifdef HAVE_CURL | ||
995 | if (!url_con) | ||
996 | return; | ||
997 | |||
998 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
999 | { | ||
1000 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
1001 | "ecore_con_url_cookies_jar_write"); | ||
1002 | return; | ||
1003 | } | ||
1004 | |||
1005 | curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "FLUSH"); | ||
1006 | #else | ||
1007 | return; | ||
1008 | (void)url_con; | ||
1009 | #endif | ||
1010 | } | ||
1011 | |||
1012 | EAPI void | ||
1013 | ecore_con_url_verbose_set(Ecore_Con_Url *url_con, | ||
1014 | Eina_Bool verbose) | ||
1015 | { | ||
1016 | #ifdef HAVE_CURL | ||
1017 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
1018 | { | ||
1019 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
1020 | "ecore_con_url_verbose_set"); | ||
1021 | return; | ||
1022 | } | ||
1023 | |||
1024 | if (url_con->active) | ||
1025 | return; | ||
1026 | |||
1027 | if (!url_con->url) | ||
1028 | return; | ||
1029 | |||
1030 | curl_easy_setopt(url_con->curl_easy, CURLOPT_VERBOSE, (int)verbose); | ||
1031 | #else | ||
1032 | return; | ||
1033 | (void)url_con; | ||
1034 | (void)verbose; | ||
1035 | #endif | ||
1036 | } | ||
1037 | |||
1038 | EAPI void | ||
1039 | ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, | ||
1040 | Eina_Bool use_epsv) | ||
1041 | { | ||
1042 | #ifdef HAVE_CURL | ||
1043 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
1044 | { | ||
1045 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
1046 | "ecore_con_url_ftp_use_epsv_set"); | ||
1047 | return; | ||
1048 | } | ||
1049 | |||
1050 | if (url_con->active) | ||
1051 | return; | ||
1052 | |||
1053 | if (!url_con->url) | ||
1054 | return; | ||
1055 | |||
1056 | curl_easy_setopt(url_con->curl_easy, CURLOPT_FTP_USE_EPSV, (int)use_epsv); | ||
1057 | #else | ||
1058 | return; | ||
1059 | (void)url_con; | ||
1060 | (void)use_epsv; | ||
1061 | #endif | ||
1062 | } | ||
1063 | |||
1064 | /** | ||
1065 | * Toggle libcurl's verify peer's certificate option. | ||
1066 | * | ||
1067 | * If @p verify is @c EINA_TRUE, libcurl will verify | ||
1068 | * the authenticity of the peer's certificate, otherwise | ||
1069 | * it will not. Default behavior of libcurl is to check | ||
1070 | * peer's certificate. | ||
1071 | * | ||
1072 | * @param url_con Ecore_Con_Url instance which will be acted upon. | ||
1073 | * @param verify Whether or not libcurl will check peer's certificate. | ||
1074 | * @since 1.1.0 | ||
1075 | */ | ||
1076 | EAPI void | ||
1077 | ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con, | ||
1078 | Eina_Bool verify) | ||
1079 | { | ||
1080 | #ifdef HAVE_CURL | ||
1081 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
1082 | { | ||
1083 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, | ||
1084 | "ecore_con_url_ssl_verify_peer_set"); | ||
1085 | return; | ||
1086 | } | ||
1087 | |||
1088 | if (url_con->active) | ||
1089 | return; | ||
1090 | |||
1091 | if (!url_con->url) | ||
1092 | return; | ||
1093 | |||
1094 | curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, (int)verify); | ||
1095 | #else | ||
1096 | return; | ||
1097 | (void)url_con; | ||
1098 | (void)verify; | ||
1099 | #endif | ||
1100 | } | ||
1101 | |||
1102 | /** | ||
1103 | * Set a custom CA to trust for SSL/TLS connections. | ||
1104 | * | ||
1105 | * Specify the path of a file (in PEM format) containing one or more | ||
1106 | * CA certificate(s) to use for the validation of the server certificate. | ||
1107 | * | ||
1108 | * This function can also disable CA validation if @p ca_path is @c NULL. | ||
1109 | * However, the server certificate still needs to be valid for the connection | ||
1110 | * to succeed (i.e., the certificate must concern the server the | ||
1111 | * connection is made to). | ||
1112 | * | ||
1113 | * @param url_con Connection object that will use the custom CA. | ||
1114 | * @param ca_path Path to a CA certificate(s) file or @c NULL to disable | ||
1115 | * CA validation. | ||
1116 | * | ||
1117 | * @return @c 0 on success. When cURL is used, non-zero return values | ||
1118 | * are equal to cURL error codes. | ||
1119 | */ | ||
1120 | EAPI int | ||
1121 | ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path) | ||
1122 | { | ||
1123 | int res = -1; | ||
1124 | |||
1125 | #ifdef HAVE_CURL | ||
1126 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
1127 | { | ||
1128 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_ssl_ca_set"); | ||
1129 | return -1; | ||
1130 | } | ||
1131 | |||
1132 | if (url_con->active) return -1; | ||
1133 | if (!url_con->url) return -1; | ||
1134 | if (ca_path == NULL) | ||
1135 | res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 0); | ||
1136 | else | ||
1137 | { | ||
1138 | res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 1); | ||
1139 | if (!res) | ||
1140 | res = curl_easy_setopt(url_con->curl_easy, CURLOPT_CAINFO, ca_path); | ||
1141 | } | ||
1142 | #else | ||
1143 | return -1; | ||
1144 | (void)url_con; | ||
1145 | (void)ca_path; | ||
1146 | #endif | ||
1147 | |||
1148 | return res; | ||
1149 | } | ||
1150 | |||
1151 | |||
1152 | /** | ||
1153 | * @} | ||
1154 | */ | ||
1155 | |||
1156 | #ifdef HAVE_CURL | ||
1157 | static int | ||
1158 | _ecore_con_url_suspend_fd_handler(void) | ||
1159 | { | ||
1160 | Eina_List *l; | ||
1161 | Ecore_Con_Url *url_con; | ||
1162 | int deleted = 0; | ||
1163 | |||
1164 | if (!_url_con_list) | ||
1165 | return 0; | ||
1166 | |||
1167 | EINA_LIST_FOREACH(_url_con_list, l, url_con) | ||
1168 | { | ||
1169 | if (url_con->active && url_con->fd_handler) | ||
1170 | { | ||
1171 | ecore_main_fd_handler_del(url_con->fd_handler); | ||
1172 | url_con->fd_handler = NULL; | ||
1173 | deleted++; | ||
1174 | } | ||
1175 | } | ||
1176 | |||
1177 | return deleted; | ||
1178 | } | ||
1179 | |||
1180 | static int | ||
1181 | _ecore_con_url_restart_fd_handler(void) | ||
1182 | { | ||
1183 | Eina_List *l; | ||
1184 | Ecore_Con_Url *url_con; | ||
1185 | int activated = 0; | ||
1186 | |||
1187 | if (!_url_con_list) | ||
1188 | return 0; | ||
1189 | |||
1190 | EINA_LIST_FOREACH(_url_con_list, l, url_con) | ||
1191 | { | ||
1192 | if (!url_con->fd_handler && url_con->fd != -1) | ||
1193 | { | ||
1194 | url_con->fd_handler = | ||
1195 | ecore_main_fd_handler_add(url_con->fd, url_con->flags, | ||
1196 | _ecore_con_url_fd_handler, | ||
1197 | NULL, NULL, NULL); | ||
1198 | activated++; | ||
1199 | } | ||
1200 | } | ||
1201 | |||
1202 | return activated; | ||
1203 | } | ||
1204 | |||
1205 | static size_t | ||
1206 | _ecore_con_url_data_cb(void *buffer, | ||
1207 | size_t size, | ||
1208 | size_t nitems, | ||
1209 | void *userp) | ||
1210 | { | ||
1211 | Ecore_Con_Url *url_con; | ||
1212 | Ecore_Con_Event_Url_Data *e; | ||
1213 | size_t real_size = size * nitems; | ||
1214 | |||
1215 | url_con = (Ecore_Con_Url *)userp; | ||
1216 | |||
1217 | if (!url_con) | ||
1218 | return -1; | ||
1219 | |||
1220 | if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) | ||
1221 | { | ||
1222 | ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_cb"); | ||
1223 | return -1; | ||
1224 | } | ||
1225 | |||
1226 | url_con->received += real_size; | ||
1227 | |||
1228 | if (url_con->write_fd < 0) | ||
1229 | { | ||
1230 | e = | ||
1231 | malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) * | ||
1232 | (real_size - 1)); | ||
1233 | if (e) | ||
1234 | { | ||
1235 | e->url_con = url_con; | ||
1236 | e->size = real_size; | ||
1237 | memcpy(e->data, buffer, real_size); | ||
1238 | ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, | ||
1239 | _ecore_con_event_url_free, NULL); | ||
1240 | } | ||
1241 | } | ||
1242 | else | ||
1243 | { | ||
1244 | ssize_t count = 0; | ||
1245 | size_t total_size = real_size; | ||
1246 | size_t offset = 0; | ||
1247 | |||
1248 | while (total_size > 0) | ||
1249 | { | ||
1250 | count = write(url_con->write_fd, | ||
1251 | (char *)buffer + offset, | ||
1252 | total_size); | ||
1253 | if (count < 0) | ||
1254 | { | ||
1255 | if (errno != EAGAIN && errno != EINTR) | ||
1256 | return -1; | ||
1257 | } | ||
1258 | else | ||
1259 | { | ||
1260 | total_size -= count; | ||
1261 | offset += count; | ||
1262 | } | ||
1263 | } | ||
1264 | } | ||
1265 | |||
1266 | return real_size; | ||
1267 | } | ||
1268 | |||
1269 | #define ECORE_CON_URL_TRANSMISSION(Transmit, Event, Url_con, Total, Now) \ | ||
1270 | { \ | ||
1271 | Ecore_Con_Event_Url_Progress *e; \ | ||
1272 | if ((Total != 0) || (Now != 0)) \ | ||
1273 | { \ | ||
1274 | e = calloc(1, sizeof(Ecore_Con_Event_Url_Progress)); \ | ||
1275 | if (e) \ | ||
1276 | { \ | ||
1277 | e->url_con = url_con; \ | ||
1278 | e->total = Total; \ | ||
1279 | e->now = Now; \ | ||
1280 | ecore_event_add(Event, e, _ecore_con_event_url_free, NULL); \ | ||
1281 | } \ | ||
1282 | } \ | ||
1283 | } | ||
1284 | |||
1285 | static size_t | ||
1286 | _ecore_con_url_header_cb(void *ptr, | ||
1287 | size_t size, | ||
1288 | size_t nitems, | ||
1289 | void *stream) | ||
1290 | { | ||
1291 | size_t real_size = size * nitems; | ||
1292 | Ecore_Con_Url *url_con = stream; | ||
1293 | |||
1294 | char *header = malloc(sizeof(char) * (real_size + 1)); | ||
1295 | if (!header) | ||
1296 | return real_size; | ||
1297 | |||
1298 | memcpy(header, ptr, real_size); | ||
1299 | header[real_size] = '\0'; | ||
1300 | |||
1301 | url_con->response_headers = eina_list_append(url_con->response_headers, | ||
1302 | header); | ||
1303 | |||
1304 | return real_size; | ||
1305 | } | ||
1306 | |||
1307 | static int | ||
1308 | _ecore_con_url_progress_cb(void *clientp, | ||
1309 | double dltotal, | ||
1310 | double dlnow, | ||
1311 | double ultotal, | ||
1312 | double ulnow) | ||
1313 | { | ||
1314 | Ecore_Con_Event_Url_Progress *e; | ||
1315 | Ecore_Con_Url *url_con; | ||
1316 | |||
1317 | url_con = clientp; | ||
1318 | |||
1319 | e = malloc(sizeof(Ecore_Con_Event_Url_Progress)); | ||
1320 | if (e) | ||
1321 | { | ||
1322 | e->url_con = url_con; | ||
1323 | e->down.total = dltotal; | ||
1324 | e->down.now = dlnow; | ||
1325 | e->up.total = ultotal; | ||
1326 | e->up.now = ulnow; | ||
1327 | ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, | ||
1328 | _ecore_con_event_url_free, NULL); | ||
1329 | } | ||
1330 | |||
1331 | return 0; | ||
1332 | } | ||
1333 | |||
1334 | static size_t | ||
1335 | _ecore_con_url_read_cb(void *ptr, | ||
1336 | size_t size, | ||
1337 | size_t nitems, | ||
1338 | void *stream) | ||
1339 | { | ||
1340 | size_t retcode = fread(ptr, size, nitems, stream); | ||
1341 | |||
1342 | if (ferror((FILE *)stream)) | ||
1343 | { | ||
1344 | fclose(stream); | ||
1345 | return CURL_READFUNC_ABORT; | ||
1346 | } | ||
1347 | else if (retcode == 0) | ||
1348 | { | ||
1349 | fclose((FILE *)stream); | ||
1350 | return 0; | ||
1351 | } | ||
1352 | |||
1353 | #ifdef _WIN32 | ||
1354 | INF("*** We read %Iu bytes from file", retcode); | ||
1355 | #else | ||
1356 | INF("*** We read %zu bytes from file", retcode); | ||
1357 | #endif | ||
1358 | return retcode; | ||
1359 | } | ||
1360 | |||
1361 | static Eina_Bool | ||
1362 | _ecore_con_url_perform(Ecore_Con_Url *url_con) | ||
1363 | { | ||
1364 | fd_set read_set, write_set, exc_set; | ||
1365 | int fd_max, fd; | ||
1366 | int flags, still_running; | ||
1367 | int completed_immediately = 0; | ||
1368 | CURLMcode ret; | ||
1369 | |||
1370 | _url_con_list = eina_list_append(_url_con_list, url_con); | ||
1371 | |||
1372 | url_con->active = EINA_TRUE; | ||
1373 | curl_multi_add_handle(_curlm, url_con->curl_easy); | ||
1374 | curl_multi_perform(_curlm, &still_running); | ||
1375 | |||
1376 | completed_immediately = _ecore_con_url_process_completed_jobs(url_con); | ||
1377 | |||
1378 | if (!completed_immediately) | ||
1379 | { | ||
1380 | if (url_con->fd_handler) | ||
1381 | ecore_main_fd_handler_del(url_con->fd_handler); | ||
1382 | |||
1383 | url_con->fd_handler = NULL; | ||
1384 | |||
1385 | /* url_con still active -- set up an fd_handler */ | ||
1386 | FD_ZERO(&read_set); | ||
1387 | FD_ZERO(&write_set); | ||
1388 | FD_ZERO(&exc_set); | ||
1389 | |||
1390 | /* Stupid curl, why can't I get the fd to the current added job? */ | ||
1391 | ret = curl_multi_fdset(_curlm, &read_set, &write_set, &exc_set, | ||
1392 | &fd_max); | ||
1393 | if (ret != CURLM_OK) | ||
1394 | { | ||
1395 | ERR("curl_multi_fdset failed: %s", curl_multi_strerror(ret)); | ||
1396 | return EINA_FALSE; | ||
1397 | } | ||
1398 | |||
1399 | for (fd = 0; fd <= fd_max; fd++) | ||
1400 | { | ||
1401 | if (!FD_ISSET(fd, &_current_fd_set)) | ||
1402 | { | ||
1403 | flags = 0; | ||
1404 | if (FD_ISSET(fd, &read_set)) | ||
1405 | flags |= ECORE_FD_READ; | ||
1406 | |||
1407 | if (FD_ISSET(fd, &write_set)) | ||
1408 | flags |= ECORE_FD_WRITE; | ||
1409 | |||
1410 | if (FD_ISSET(fd, &exc_set)) | ||
1411 | flags |= ECORE_FD_ERROR; | ||
1412 | |||
1413 | if (flags) | ||
1414 | { | ||
1415 | long ms = 0; | ||
1416 | |||
1417 | ret = curl_multi_timeout(_curlm, &ms); | ||
1418 | if (ret != CURLM_OK) | ||
1419 | ERR("curl_multi_timeout failed: %s", | ||
1420 | curl_multi_strerror(ret)); | ||
1421 | |||
1422 | if (ms == 0) | ||
1423 | ms = 1000; | ||
1424 | |||
1425 | FD_SET(fd, &_current_fd_set); | ||
1426 | url_con->fd = fd; | ||
1427 | url_con->flags = flags; | ||
1428 | url_con->fd_handler = | ||
1429 | ecore_main_fd_handler_add(fd, flags, | ||
1430 | _ecore_con_url_fd_handler, | ||
1431 | NULL, NULL, NULL); | ||
1432 | break; | ||
1433 | } | ||
1434 | } | ||
1435 | } | ||
1436 | if (!url_con->fd_handler) | ||
1437 | { | ||
1438 | /* Failed to set up an fd_handler */ | ||
1439 | ecore_timer_freeze(_curl_timeout); | ||
1440 | |||
1441 | ret = curl_multi_remove_handle(_curlm, url_con->curl_easy); | ||
1442 | if (ret != CURLM_OK) | ||
1443 | ERR("curl_multi_remove_handle failed: %s", | ||
1444 | curl_multi_strerror(ret)); | ||
1445 | |||
1446 | url_con->active = EINA_FALSE; | ||
1447 | url_con->fd = -1; | ||
1448 | return EINA_FALSE; | ||
1449 | } | ||
1450 | |||
1451 | ecore_timer_thaw(_curl_timeout); | ||
1452 | } | ||
1453 | |||
1454 | return EINA_TRUE; | ||
1455 | } | ||
1456 | |||
1457 | static Eina_Bool | ||
1458 | _ecore_con_url_idler_handler(void *data) | ||
1459 | { | ||
1460 | int done, still_running; | ||
1461 | |||
1462 | done = (curl_multi_perform(_curlm, &still_running) != CURLM_CALL_MULTI_PERFORM); | ||
1463 | |||
1464 | _ecore_con_url_process_completed_jobs(NULL); | ||
1465 | |||
1466 | if (done) | ||
1467 | { | ||
1468 | _ecore_con_url_restart_fd_handler(); | ||
1469 | _fd_idler_handler = NULL; | ||
1470 | |||
1471 | if (!_url_con_list) | ||
1472 | ecore_timer_freeze(_curl_timeout); | ||
1473 | |||
1474 | return data == | ||
1475 | (void *)0xACE ? ECORE_CALLBACK_RENEW : ECORE_CALLBACK_CANCEL; | ||
1476 | } | ||
1477 | |||
1478 | return ECORE_CALLBACK_RENEW; | ||
1479 | } | ||
1480 | |||
1481 | static Eina_Bool | ||
1482 | _ecore_con_url_fd_handler(void *data __UNUSED__, | ||
1483 | Ecore_Fd_Handler *fd_handler __UNUSED__) | ||
1484 | { | ||
1485 | _ecore_con_url_suspend_fd_handler(); | ||
1486 | |||
1487 | if (!_fd_idler_handler) | ||
1488 | _fd_idler_handler = ecore_idler_add( | ||
1489 | _ecore_con_url_idler_handler, NULL); | ||
1490 | |||
1491 | return ECORE_CALLBACK_RENEW; | ||
1492 | } | ||
1493 | |||
1494 | static int | ||
1495 | _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match) | ||
1496 | { | ||
1497 | Eina_List *l; | ||
1498 | Ecore_Con_Url *url_con; | ||
1499 | Ecore_Con_Event_Url_Complete *e; | ||
1500 | CURLMsg *curlmsg; | ||
1501 | CURLMcode ret; | ||
1502 | int n_remaining; | ||
1503 | int job_matched = 0; | ||
1504 | |||
1505 | /* Loop jobs and check if any are done */ | ||
1506 | while ((curlmsg = curl_multi_info_read(_curlm, &n_remaining))) | ||
1507 | { | ||
1508 | if (curlmsg->msg != CURLMSG_DONE) | ||
1509 | continue; | ||
1510 | |||
1511 | /* find the job which is done */ | ||
1512 | EINA_LIST_FOREACH(_url_con_list, l, url_con) | ||
1513 | { | ||
1514 | if (curlmsg->easy_handle == url_con->curl_easy) | ||
1515 | { | ||
1516 | if (url_con_to_match && | ||
1517 | (url_con == url_con_to_match)) | ||
1518 | job_matched = 1; | ||
1519 | |||
1520 | if(url_con->fd != -1) | ||
1521 | { | ||
1522 | FD_CLR(url_con->fd, &_current_fd_set); | ||
1523 | if (url_con->fd_handler) | ||
1524 | ecore_main_fd_handler_del( | ||
1525 | url_con->fd_handler); | ||
1526 | |||
1527 | url_con->fd = -1; | ||
1528 | url_con->fd_handler = NULL; | ||
1529 | } | ||
1530 | |||
1531 | _url_con_list = eina_list_remove(_url_con_list, url_con); | ||
1532 | url_con->active = EINA_FALSE; | ||
1533 | e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete)); | ||
1534 | if (e) | ||
1535 | { | ||
1536 | e->url_con = url_con; | ||
1537 | e->status = 0; | ||
1538 | if (curlmsg->data.result == CURLE_OK) | ||
1539 | { | ||
1540 | long status; /* curl API uses long, not int */ | ||
1541 | |||
1542 | status = 0; | ||
1543 | curl_easy_getinfo(curlmsg->easy_handle, | ||
1544 | CURLINFO_RESPONSE_CODE, | ||
1545 | &status); | ||
1546 | e->status = status; | ||
1547 | } | ||
1548 | |||
1549 | _url_complete_push_event(ECORE_CON_EVENT_URL_COMPLETE, e); | ||
1550 | } | ||
1551 | |||
1552 | ret = curl_multi_remove_handle(_curlm, url_con->curl_easy); | ||
1553 | if (ret != CURLM_OK) | ||
1554 | ERR("curl_multi_remove_handle failed: %s", | ||
1555 | curl_multi_strerror(ret)); | ||
1556 | |||
1557 | break; | ||
1558 | } | ||
1559 | } | ||
1560 | } | ||
1561 | |||
1562 | return job_matched; | ||
1563 | } | ||
1564 | |||
1565 | static void | ||
1566 | _ecore_con_event_url_free(void *data __UNUSED__, | ||
1567 | void *ev) | ||
1568 | { | ||
1569 | free(ev); | ||
1570 | } | ||
1571 | |||
1572 | #endif | ||
diff --git a/libraries/ecore/src/lib/ecore_config/Ecore_Config.h b/libraries/ecore/src/lib/ecore_config/Ecore_Config.h new file mode 100644 index 0000000..6733d7b --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/Ecore_Config.h | |||
@@ -0,0 +1,312 @@ | |||
1 | #ifndef _ECORE_CONFIG_H | ||
2 | # define _ECORE_CONFIG_H | ||
3 | |||
4 | #ifdef EAPI | ||
5 | #undef EAPI | ||
6 | #endif | ||
7 | #ifdef _MSC_VER | ||
8 | # ifdef BUILDING_DLL | ||
9 | # define EAPI __declspec(dllexport) | ||
10 | # else | ||
11 | # define EAPI __declspec(dllimport) | ||
12 | # endif | ||
13 | #else | ||
14 | # ifdef __GNUC__ | ||
15 | # if __GNUC__ >= 4 | ||
16 | # define EAPI __attribute__ ((visibility("default"))) | ||
17 | # else | ||
18 | # define EAPI | ||
19 | # endif | ||
20 | # else | ||
21 | # define EAPI | ||
22 | # endif | ||
23 | #endif | ||
24 | |||
25 | /** | ||
26 | * @file | ||
27 | * @brief Provides the Enlightened Property Library. | ||
28 | * | ||
29 | * This file provies all headers and structs for use with Ecore_Config. | ||
30 | * Using individual header files should not be necessary. | ||
31 | */ | ||
32 | |||
33 | # define DIR_DELIMITER '/' | ||
34 | # define ECORE_CONFIG_FLOAT_PRECISION 1000 | ||
35 | |||
36 | /* FIXME: this should only be included if evas is present */ | ||
37 | # include <Evas.h> | ||
38 | |||
39 | # define ECORE_CONFIG_GLOBAL_ID "_system" | ||
40 | |||
41 | /* structures */ | ||
42 | |||
43 | /** | ||
44 | * Valid configuration property types. | ||
45 | */ | ||
46 | typedef enum Ecore_Config_Type | ||
47 | { | ||
48 | ECORE_CONFIG_NIL = 0, /**< Property with no value. */ | ||
49 | ECORE_CONFIG_INT = 1, /**< Integer property type. */ | ||
50 | ECORE_CONFIG_FLT = 2, /**< Float property type. */ | ||
51 | ECORE_CONFIG_STR = 3, /**< String property type. */ | ||
52 | ECORE_CONFIG_RGB = 4, /**< Colour property type. */ | ||
53 | ECORE_CONFIG_THM = 5, /**< Theme property type. */ | ||
54 | ECORE_CONFIG_BLN = 6, /**< Boolean property type. */ | ||
55 | ECORE_CONFIG_SCT = 7, /**< Structure property type */ | ||
56 | } Ecore_Config_Type; | ||
57 | |||
58 | typedef enum Ecore_Config_Flag | ||
59 | { | ||
60 | ECORE_CONFIG_FLAG_NONE = 0, | ||
61 | ECORE_CONFIG_FLAG_BOUNDS = 1, | ||
62 | ECORE_CONFIG_FLAG_MODIFIED = 2, | ||
63 | ECORE_CONFIG_FLAG_SYSTEM = 4, | ||
64 | ECORE_CONFIG_FLAG_CMDLN = 8 | ||
65 | } Ecore_Config_Flag; | ||
66 | |||
67 | /** | ||
68 | * Property change callback function prototype. | ||
69 | */ | ||
70 | typedef int (*Ecore_Config_Listener) (const char *key, | ||
71 | const Ecore_Config_Type type, | ||
72 | const int tag, void *data); | ||
73 | |||
74 | typedef struct Ecore_Config_Listener_List | ||
75 | { | ||
76 | Ecore_Config_Listener listener; | ||
77 | const char *name; | ||
78 | void *data; | ||
79 | int tag; | ||
80 | struct Ecore_Config_Listener_List *next; | ||
81 | } Ecore_Config_Listener_List; | ||
82 | |||
83 | /** | ||
84 | * The actual property for storing a key-value pair. | ||
85 | */ | ||
86 | typedef struct Ecore_Config_Prop | ||
87 | { | ||
88 | char *key; /* Property key. */ | ||
89 | char *description; /* Description set by ecore_config_descibe. */ | ||
90 | char short_opt; /* short identifier on command line (-f) */ | ||
91 | char *long_opt; /* long identifier on command line (--foo) */ | ||
92 | char *ptr; /* Used as the value when the property is a string or theme. */ | ||
93 | Ecore_Config_Type type; /* Property type. */ | ||
94 | long val; /* Used as the value when the property is an integer, float or colour. */ | ||
95 | long lo; /* Lower bound for the value when the property is an integer or float. */ | ||
96 | long hi; /* Higher bound for the value when the property is an integer or float. */ | ||
97 | long step; /* Increment for the value when the property is an integer or float. */ | ||
98 | Ecore_Config_Flag flags; /// < Configuration flags. | ||
99 | Ecore_Config_Listener_List *listeners; /* List of change listeners. */ | ||
100 | void *data; /// < Stores extra data for the property. | ||
101 | struct Ecore_Config_Prop *parent; /* if we are in a struct we have a parent to notify of changes etc */ | ||
102 | struct Ecore_Config_Prop *next; /* Pointer to the next property in the list. */ | ||
103 | } Ecore_Config_Prop; | ||
104 | |||
105 | /* | ||
106 | * A container for a list of properties. Provided so that an | ||
107 | * application can use different set of properties at any time. This | ||
108 | * is useful for multiple window support. | ||
109 | */ | ||
110 | typedef struct Ecore_Config_Bundle | ||
111 | { | ||
112 | char *identifier; /* Identifier for this set of properties (window ID for example) */ | ||
113 | char *owner; /* This is used to store the application name related to the bundle */ | ||
114 | long serial; /* Unique identifier to identify bundle */ | ||
115 | Ecore_Config_Prop *data; /* Pointer to root of property list */ | ||
116 | void *user_data; /* App specific pointer to "other data" */ | ||
117 | struct Ecore_Config_Bundle *next; /* Pointer to next bundle in this application */ | ||
118 | } Ecore_Config_Bundle; | ||
119 | |||
120 | typedef struct Ecore_Config_Server | ||
121 | { | ||
122 | void *server; | ||
123 | char *name; | ||
124 | Ecore_Config_Bundle *bundles; /* data anchor */ | ||
125 | struct Ecore_Config_Server *next; | ||
126 | } Ecore_Config_Server; | ||
127 | |||
128 | # ifdef __cplusplus | ||
129 | extern "C" | ||
130 | { | ||
131 | # endif | ||
132 | |||
133 | /* global ptrs to save passing them through the API */ | ||
134 | EAPI extern Ecore_Config_Server *__ecore_config_server_global; | ||
135 | EAPI extern Ecore_Config_Server *__ecore_config_server_local; | ||
136 | EAPI extern Ecore_Config_Bundle *__ecore_config_bundle_local; | ||
137 | EAPI extern char *__ecore_config_app_name; | ||
138 | |||
139 | EAPI Ecore_Config_Prop *ecore_config_get(const char *key); | ||
140 | EAPI const char *ecore_config_type_get(const Ecore_Config_Prop *e); | ||
141 | EAPI int ecore_config_boolean_get(const char *key); | ||
142 | EAPI char *ecore_config_string_get(const char *key); | ||
143 | EAPI long ecore_config_int_get(const char *key); | ||
144 | EAPI int ecore_config_argb_get(const char *key, int *a, int *r, | ||
145 | int *g, int *b); | ||
146 | EAPI long ecore_config_argbint_get(const char *key); | ||
147 | EAPI char *ecore_config_argbstr_get(const char *key); | ||
148 | EAPI float ecore_config_float_get(const char *key); | ||
149 | EAPI char *ecore_config_theme_get(const char *key); | ||
150 | EAPI char *ecore_config_as_string_get(const char *key); | ||
151 | EAPI int ecore_config_bound(Ecore_Config_Prop *e); | ||
152 | EAPI int ecore_config_describe(const char *key, const char *desc); | ||
153 | EAPI int ecore_config_short_opt_set(const char *key, | ||
154 | char short_opt); | ||
155 | EAPI int ecore_config_long_opt_set(const char *key, | ||
156 | const char *long_opt); | ||
157 | EAPI int ecore_config_set(const char *key, const char *val); | ||
158 | EAPI int ecore_config_typed_set(const char *key, const void *val, | ||
159 | int type); | ||
160 | EAPI int ecore_config_boolean_set(const char *key, int val); | ||
161 | EAPI int ecore_config_string_set(const char *key, const char *val); | ||
162 | EAPI int ecore_config_int_set(const char *key, int val); | ||
163 | EAPI int ecore_config_argb_set(const char *key, int a, int r, int g, int b); | ||
164 | EAPI int ecore_config_argbint_set(const char *key, long argb); | ||
165 | EAPI int ecore_config_argbstr_set(const char *key, const char *val); | ||
166 | EAPI int ecore_config_float_set(const char *key, float val); | ||
167 | EAPI int ecore_config_theme_set(const char *key, const char *val); | ||
168 | EAPI int ecore_config_theme_preview_group_set(const char *key, | ||
169 | const char *group); | ||
170 | EAPI int ecore_config_as_string_set(const char *key, const char *val); | ||
171 | |||
172 | EAPI int ecore_config_default(const char *key, const char *val, | ||
173 | float lo, float hi, float step); | ||
174 | EAPI int ecore_config_typed_default(const char *key, const void *val, | ||
175 | int type); | ||
176 | EAPI int ecore_config_boolean_default(const char *key, int val); | ||
177 | EAPI int ecore_config_int_default(const char *key, int val); | ||
178 | EAPI int ecore_config_int_default_bound(const char *key, int val, | ||
179 | int lo, int hi, int step); | ||
180 | EAPI int ecore_config_string_default(const char *key, const char *val); | ||
181 | EAPI int ecore_config_float_default(const char *key, float val); | ||
182 | EAPI int ecore_config_float_default_bound(const char *key, | ||
183 | float val, float lo, | ||
184 | float hi, float step); | ||
185 | EAPI int ecore_config_argb_default(const char *key, int a, int r, int g, int b); | ||
186 | EAPI int ecore_config_argbint_default(const char *key, long argb); | ||
187 | EAPI int ecore_config_argbstr_default(const char *key, const char *val); | ||
188 | EAPI int ecore_config_theme_default(const char *key, const char *val); | ||
189 | EAPI int ecore_config_struct_default(const char *key); | ||
190 | EAPI int ecore_config_struct_int_add(const char *key, const char *name, int val); | ||
191 | EAPI int ecore_config_struct_float_add(const char *key, const char *name, float val); | ||
192 | EAPI int ecore_config_struct_create(const char *key); | ||
193 | EAPI int ecore_config_struct_string_add(const char *key, const char *name, const char* val); | ||
194 | EAPI int ecore_config_struct_theme_add(const char *key, const char *name, const char* val); | ||
195 | EAPI int ecore_config_struct_argb_add(const char *key, const char *name, int a, int r, int g, int b); | ||
196 | EAPI int ecore_config_struct_boolean_add(const char *key, const char *name, int val); | ||
197 | EAPI int ecore_config_struct_get(const char *key, void *data); | ||
198 | |||
199 | EAPI int ecore_config_listen(const char *name, const char *key, | ||
200 | Ecore_Config_Listener listener, | ||
201 | int tag, void *data); | ||
202 | EAPI int ecore_config_deaf(const char *name, const char *key, | ||
203 | Ecore_Config_Listener listener); | ||
204 | EAPI Ecore_Config_Prop *ecore_config_dst(Ecore_Config_Prop *e); | ||
205 | EAPI int ecore_config_type_guess(const char *key, const char *val); | ||
206 | |||
207 | EAPI Ecore_Config_Bundle *ecore_config_bundle_new(Ecore_Config_Server *srv, | ||
208 | const char *id); | ||
209 | EAPI Ecore_Config_Bundle *ecore_config_bundle_1st_get(Ecore_Config_Server *srv); | ||
210 | EAPI Ecore_Config_Bundle *ecore_config_bundle_next_get(Ecore_Config_Bundle *ns); | ||
211 | EAPI Ecore_Config_Bundle *ecore_config_bundle_by_serial_get(Ecore_Config_Server *srv, | ||
212 | long serial); | ||
213 | EAPI Ecore_Config_Bundle *ecore_config_bundle_by_label_get(Ecore_Config_Server *srv, | ||
214 | const char *label); | ||
215 | EAPI long ecore_config_bundle_serial_get(Ecore_Config_Bundle *ns); | ||
216 | EAPI char *ecore_config_bundle_label_get(Ecore_Config_Bundle *ns); | ||
217 | |||
218 | EAPI int ecore_config_init(const char *name); | ||
219 | EAPI int ecore_config_shutdown(void); | ||
220 | |||
221 | EAPI int ecore_config_system_init(void); | ||
222 | EAPI int ecore_config_system_shutdown(void); | ||
223 | |||
224 | EAPI int ecore_config_load(void); | ||
225 | EAPI int ecore_config_file_load(const char *file); | ||
226 | EAPI int ecore_config_save(void); | ||
227 | EAPI int ecore_config_file_save(const char *file); | ||
228 | |||
229 | /* error codes */ | ||
230 | # define ECORE_CONFIG_ERR_NOTSUPP (-16) | ||
231 | # define ECORE_CONFIG_ERR_NOFILE (-15) | ||
232 | # define ECORE_CONFIG_ERR_META_DLFAIL (-14) | ||
233 | # define ECORE_CONFIG_ERR_META_FILE (-13) | ||
234 | # define ECORE_CONFIG_ERR_META_FORMAT (-12) | ||
235 | # define ECORE_CONFIG_ERR_MONMIS (-11) | ||
236 | # define ECORE_CONFIG_ERR_NOEXEC (-10) | ||
237 | # define ECORE_CONFIG_ERR_PARTIAL (-9) | ||
238 | # define ECORE_CONFIG_ERR_PATHEX (-8) | ||
239 | # define ECORE_CONFIG_ERR_TYPEMISMATCH (-7) | ||
240 | # define ECORE_CONFIG_ERR_MUTEX (-6) | ||
241 | # define ECORE_CONFIG_ERR_NOTFOUND (-5) /* Error indicating that the item searched for could not be found. */ | ||
242 | # define ECORE_CONFIG_ERR_OOM (-4) /* Error given when the program runs out of memory. */ | ||
243 | # define ECORE_CONFIG_ERR_IGNORED (-3) /* Error occurred, but was ignored. */ | ||
244 | # define ECORE_CONFIG_ERR_NODATA (-2) /* Error given when necessary data is not provided. */ | ||
245 | # define ECORE_CONFIG_ERR_FAIL (-1) /* Failure result. */ | ||
246 | # define ECORE_CONFIG_ERR_SUCC (0) /* Success result. */ | ||
247 | |||
248 | # define ECORE_CONFIG_PARSE_HELP (-2) /* Help was displayed */ | ||
249 | # define ECORE_CONFIG_PARSE_EXIT (-1) /* An error occurred */ | ||
250 | # define ECORE_CONFIG_PARSE_CONTINUE (0) /* Arguments parsed successfully */ | ||
251 | |||
252 | /* convenience mathods in convenience.c */ | ||
253 | /* FIXME: this should only be included if evas is present */ | ||
254 | EAPI int ecore_config_evas_font_path_apply(Evas *evas); | ||
255 | EAPI char *ecore_config_theme_search_path_get(void); | ||
256 | EAPI int ecore_config_theme_search_path_append(const char *append); | ||
257 | |||
258 | EAPI char *ecore_config_theme_default_path_get(void); | ||
259 | EAPI char *ecore_config_theme_with_path_from_name_get(char *name); | ||
260 | EAPI char *ecore_config_theme_with_path_get(const char *key); | ||
261 | EAPI void ecore_config_args_display(void); | ||
262 | EAPI int ecore_config_args_parse(void); | ||
263 | EAPI void ecore_config_args_callback_str_add(char short_opt, | ||
264 | char *long_opt, char *desc, | ||
265 | void (*func)(char *val, void *data), | ||
266 | void *data); | ||
267 | EAPI void ecore_config_args_callback_noarg_add(char short_opt, | ||
268 | char *long_opt, char *desc, | ||
269 | void (*func)(char *val, void *data), | ||
270 | void *data); | ||
271 | EAPI void ecore_config_app_describe(char *description); | ||
272 | |||
273 | EAPI int ecore_config_create(const char *key, void *val, | ||
274 | char short_opt, char *long_opt, | ||
275 | char *desc); | ||
276 | EAPI int ecore_config_typed_create(const char *key, void *val, | ||
277 | int type, char short_opt, | ||
278 | char *long_opt, char *desc); | ||
279 | EAPI int ecore_config_boolean_create(const char *key, int val, | ||
280 | char short_opt, char *long_opt, | ||
281 | char *desc); | ||
282 | EAPI int ecore_config_int_create(const char *key, int val, | ||
283 | char short_opt, char *long_opt, | ||
284 | char *desc); | ||
285 | EAPI int ecore_config_int_create_bound(const char *key, int val, | ||
286 | int low, int high, | ||
287 | int step, char short_opt, | ||
288 | char *long_opt, | ||
289 | char *desc); | ||
290 | EAPI int ecore_config_string_create(const char *key, char *val, | ||
291 | char short_opt, | ||
292 | char *long_opt, char *desc); | ||
293 | EAPI int ecore_config_float_create(const char *key, float val, | ||
294 | char short_opt, char *long_opt, | ||
295 | char *desc); | ||
296 | EAPI int ecore_config_float_create_bound(const char *key, | ||
297 | float val, float low, | ||
298 | float high, float step, | ||
299 | char short_opt, | ||
300 | char *long_opt, | ||
301 | char *desc); | ||
302 | EAPI int ecore_config_argb_create(const char *key, char *val, | ||
303 | char short_opt, char *long_opt, | ||
304 | char *desc); | ||
305 | EAPI int ecore_config_theme_create(const char *key, char *val, | ||
306 | char short_opt, char *long_opt, | ||
307 | char *desc); | ||
308 | |||
309 | # ifdef __cplusplus | ||
310 | } | ||
311 | # endif | ||
312 | #endif | ||
diff --git a/libraries/ecore/src/lib/ecore_config/Makefile.am b/libraries/ecore/src/lib/ecore_config/Makefile.am new file mode 100644 index 0000000..c459351 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/Makefile.am | |||
@@ -0,0 +1,62 @@ | |||
1 | MAINTAINERCLEANFILES = Makefile.in | ||
2 | |||
3 | AM_CPPFLAGS = \ | ||
4 | -I$(top_srcdir)/src/lib/ecore \ | ||
5 | -I$(top_srcdir)/src/lib/ecore_ipc \ | ||
6 | -I$(top_srcdir)/ \ | ||
7 | -I$(top_builddir)/src/lib/ecore \ | ||
8 | -I$(top_builddir)/src/lib/ecore_ipc \ | ||
9 | -I$(top_builddir)/ \ | ||
10 | -DPACKAGE_BIN_DIR=\"$(bindir)\" \ | ||
11 | -DPACKAGE_LIB_DIR=\"$(libdir)\" \ | ||
12 | -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ | ||
13 | @EVAS_CFLAGS@ \ | ||
14 | @EET_CFLAGS@ \ | ||
15 | @EINA_CFLAGS@ | ||
16 | |||
17 | CLEANFILES = $(DB) | ||
18 | |||
19 | #DB = system.db | ||
20 | #$(DB): Makefile | ||
21 | # edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/theme/name str "winter" | ||
22 | # edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/font/path str "$(pkgdatadir)/data/fonts" | ||
23 | # edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/browser str `which firefox 2>/dev/null || which phoenix 2>/dev/null || which mozilla 2>/dev/null || which opera 2>/dev/null || which konqueror 2>/dev/null || which epiphany 2>/dev/null` | ||
24 | # edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/email str `which thunderbird 2>/dev/null || which mozilla 2>/dev/null || which kmail 2>/dev/null || which sylpheed 2>/dev/null || which evolution 2>/dev/null` | ||
25 | |||
26 | lib_LTLIBRARIES = libecore_config.la | ||
27 | |||
28 | includes_HEADERS = Ecore_Config.h | ||
29 | includesdir = $(includedir)/ecore-@VMAJ@ | ||
30 | |||
31 | libecore_config_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ | ||
32 | |||
33 | #config_DATA = $(DB) | ||
34 | #configdir = $(pkgdatadir) | ||
35 | |||
36 | libecore_config_la_SOURCES = \ | ||
37 | ecore_config.c \ | ||
38 | ecore_config_util.c \ | ||
39 | ecore_config_storage.c \ | ||
40 | ecore_config_extra.c \ | ||
41 | ecore_config_db.c | ||
42 | |||
43 | libecore_config_la_LIBADD = \ | ||
44 | $(top_builddir)/src/lib/ecore/libecore.la \ | ||
45 | @EET_LIBS@ \ | ||
46 | @EINA_LIBS@ \ | ||
47 | @EVAS_LIBS@ | ||
48 | |||
49 | if BUILD_ECORE_IPC | ||
50 | |||
51 | libecore_config_la_SOURCES += \ | ||
52 | ecore_config_ipc_main.c \ | ||
53 | ecore_config_ipc_ecore.c | ||
54 | |||
55 | libecore_config_la_LIBADD += $(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la | ||
56 | |||
57 | endif | ||
58 | |||
59 | EXTRA_DIST = \ | ||
60 | ecore_config_ipc.h \ | ||
61 | ecore_config_private.h \ | ||
62 | ecore_config_util.h | ||
diff --git a/libraries/ecore/src/lib/ecore_config/Makefile.in b/libraries/ecore/src/lib/ecore_config/Makefile.in new file mode 100644 index 0000000..1732a34 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/Makefile.in | |||
@@ -0,0 +1,855 @@ | |||
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 | |||
19 | VPATH = @srcdir@ | ||
20 | pkgdatadir = $(datadir)/@PACKAGE@ | ||
21 | pkgincludedir = $(includedir)/@PACKAGE@ | ||
22 | pkglibdir = $(libdir)/@PACKAGE@ | ||
23 | pkglibexecdir = $(libexecdir)/@PACKAGE@ | ||
24 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd | ||
25 | install_sh_DATA = $(install_sh) -c -m 644 | ||
26 | install_sh_PROGRAM = $(install_sh) -c | ||
27 | install_sh_SCRIPT = $(install_sh) -c | ||
28 | INSTALL_HEADER = $(INSTALL_DATA) | ||
29 | transform = $(program_transform_name) | ||
30 | NORMAL_INSTALL = : | ||
31 | PRE_INSTALL = : | ||
32 | POST_INSTALL = : | ||
33 | NORMAL_UNINSTALL = : | ||
34 | PRE_UNINSTALL = : | ||
35 | POST_UNINSTALL = : | ||
36 | build_triplet = @build@ | ||
37 | host_triplet = @host@ | ||
38 | @BUILD_ECORE_IPC_TRUE@am__append_1 = \ | ||
39 | @BUILD_ECORE_IPC_TRUE@ecore_config_ipc_main.c \ | ||
40 | @BUILD_ECORE_IPC_TRUE@ecore_config_ipc_ecore.c | ||
41 | |||
42 | @BUILD_ECORE_IPC_TRUE@am__append_2 = $(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la | ||
43 | subdir = src/lib/ecore_config | ||
44 | DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \ | ||
45 | $(srcdir)/Makefile.in | ||
46 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ||
47 | am__aclocal_m4_deps = $(top_srcdir)/m4/ac_attribute.m4 \ | ||
48 | $(top_srcdir)/m4/ac_path_generic.m4 \ | ||
49 | $(top_srcdir)/m4/check_x_extension.m4 \ | ||
50 | $(top_srcdir)/m4/ecore_check_module.m4 \ | ||
51 | $(top_srcdir)/m4/ecore_check_options.m4 \ | ||
52 | $(top_srcdir)/m4/efl_compiler_flag.m4 \ | ||
53 | $(top_srcdir)/m4/efl_doxygen.m4 \ | ||
54 | $(top_srcdir)/m4/efl_examples.m4 \ | ||
55 | $(top_srcdir)/m4/efl_path_max.m4 $(top_srcdir)/m4/efl_tests.m4 \ | ||
56 | $(top_srcdir)/m4/efl_threads.m4 $(top_srcdir)/m4/gettext.m4 \ | ||
57 | $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ | ||
58 | $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/lib-ld.m4 \ | ||
59 | $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ | ||
60 | $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ | ||
61 | $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ | ||
62 | $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ | ||
63 | $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ | ||
64 | $(top_srcdir)/configure.ac | ||
65 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ | ||
66 | $(ACLOCAL_M4) | ||
67 | mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs | ||
68 | CONFIG_HEADER = $(top_builddir)/config.h | ||
69 | CONFIG_CLEAN_FILES = | ||
70 | CONFIG_CLEAN_VPATH_FILES = | ||
71 | am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; | ||
72 | am__vpath_adj = case $$p in \ | ||
73 | $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ | ||
74 | *) f=$$p;; \ | ||
75 | esac; | ||
76 | am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; | ||
77 | am__install_max = 40 | ||
78 | am__nobase_strip_setup = \ | ||
79 | srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` | ||
80 | am__nobase_strip = \ | ||
81 | for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" | ||
82 | am__nobase_list = $(am__nobase_strip_setup); \ | ||
83 | for p in $$list; do echo "$$p $$p"; done | \ | ||
84 | sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ | ||
85 | $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ | ||
86 | if (++n[$$2] == $(am__install_max)) \ | ||
87 | { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ | ||
88 | END { for (dir in files) print dir, files[dir] }' | ||
89 | am__base_list = \ | ||
90 | sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ | ||
91 | sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | ||
92 | am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)" | ||
93 | LTLIBRARIES = $(lib_LTLIBRARIES) | ||
94 | libecore_config_la_DEPENDENCIES = \ | ||
95 | $(top_builddir)/src/lib/ecore/libecore.la $(am__append_2) | ||
96 | am__libecore_config_la_SOURCES_DIST = ecore_config.c \ | ||
97 | ecore_config_util.c ecore_config_storage.c \ | ||
98 | ecore_config_extra.c ecore_config_db.c ecore_config_ipc_main.c \ | ||
99 | ecore_config_ipc_ecore.c | ||
100 | @BUILD_ECORE_IPC_TRUE@am__objects_1 = ecore_config_ipc_main.lo \ | ||
101 | @BUILD_ECORE_IPC_TRUE@ ecore_config_ipc_ecore.lo | ||
102 | am_libecore_config_la_OBJECTS = ecore_config.lo ecore_config_util.lo \ | ||
103 | ecore_config_storage.lo ecore_config_extra.lo \ | ||
104 | ecore_config_db.lo $(am__objects_1) | ||
105 | libecore_config_la_OBJECTS = $(am_libecore_config_la_OBJECTS) | ||
106 | AM_V_lt = $(am__v_lt_$(V)) | ||
107 | am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) | ||
108 | am__v_lt_0 = --silent | ||
109 | libecore_config_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ | ||
110 | $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ | ||
111 | $(AM_CFLAGS) $(CFLAGS) $(libecore_config_la_LDFLAGS) \ | ||
112 | $(LDFLAGS) -o $@ | ||
113 | DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) | ||
114 | depcomp = $(SHELL) $(top_srcdir)/depcomp | ||
115 | am__depfiles_maybe = depfiles | ||
116 | am__mv = mv -f | ||
117 | COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ | ||
118 | $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||
119 | LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
120 | $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ | ||
121 | $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ | ||
122 | $(AM_CFLAGS) $(CFLAGS) | ||
123 | AM_V_CC = $(am__v_CC_$(V)) | ||
124 | am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) | ||
125 | am__v_CC_0 = @echo " CC " $@; | ||
126 | AM_V_at = $(am__v_at_$(V)) | ||
127 | am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) | ||
128 | am__v_at_0 = @ | ||
129 | CCLD = $(CC) | ||
130 | LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
131 | $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ | ||
132 | $(AM_LDFLAGS) $(LDFLAGS) -o $@ | ||
133 | AM_V_CCLD = $(am__v_CCLD_$(V)) | ||
134 | am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) | ||
135 | am__v_CCLD_0 = @echo " CCLD " $@; | ||
136 | AM_V_GEN = $(am__v_GEN_$(V)) | ||
137 | am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) | ||
138 | am__v_GEN_0 = @echo " GEN " $@; | ||
139 | SOURCES = $(libecore_config_la_SOURCES) | ||
140 | DIST_SOURCES = $(am__libecore_config_la_SOURCES_DIST) | ||
141 | HEADERS = $(includes_HEADERS) | ||
142 | ETAGS = etags | ||
143 | CTAGS = ctags | ||
144 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) | ||
145 | ACLOCAL = @ACLOCAL@ | ||
146 | ALLOCA = @ALLOCA@ | ||
147 | AMTAR = @AMTAR@ | ||
148 | AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ | ||
149 | AR = @AR@ | ||
150 | AS = @AS@ | ||
151 | AUTOCONF = @AUTOCONF@ | ||
152 | AUTOHEADER = @AUTOHEADER@ | ||
153 | AUTOMAKE = @AUTOMAKE@ | ||
154 | AWK = @AWK@ | ||
155 | CARES_CFLAGS = @CARES_CFLAGS@ | ||
156 | CARES_LIBS = @CARES_LIBS@ | ||
157 | CC = @CC@ | ||
158 | CCDEPMODE = @CCDEPMODE@ | ||
159 | CFLAGS = @CFLAGS@ | ||
160 | CHECK_CFLAGS = @CHECK_CFLAGS@ | ||
161 | CHECK_LIBS = @CHECK_LIBS@ | ||
162 | CPP = @CPP@ | ||
163 | CPPFLAGS = @CPPFLAGS@ | ||
164 | CURL_CFLAGS = @CURL_CFLAGS@ | ||
165 | CURL_LIBS = @CURL_LIBS@ | ||
166 | CXX = @CXX@ | ||
167 | CXXCPP = @CXXCPP@ | ||
168 | CXXDEPMODE = @CXXDEPMODE@ | ||
169 | CXXFLAGS = @CXXFLAGS@ | ||
170 | CYGPATH_W = @CYGPATH_W@ | ||
171 | DEFS = @DEFS@ | ||
172 | DEPDIR = @DEPDIR@ | ||
173 | DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@ | ||
174 | DIRECTFB_LIBS = @DIRECTFB_LIBS@ | ||
175 | DLLTOOL = @DLLTOOL@ | ||
176 | DSYMUTIL = @DSYMUTIL@ | ||
177 | DUMPBIN = @DUMPBIN@ | ||
178 | ECHO_C = @ECHO_C@ | ||
179 | ECHO_N = @ECHO_N@ | ||
180 | ECHO_T = @ECHO_T@ | ||
181 | ECORE_XCB_CFLAGS = @ECORE_XCB_CFLAGS@ | ||
182 | ECORE_XCB_LIBS = @ECORE_XCB_LIBS@ | ||
183 | EFL_ECORE_BUILD = @EFL_ECORE_BUILD@ | ||
184 | EFL_ECORE_CON_BUILD = @EFL_ECORE_CON_BUILD@ | ||
185 | EFL_ECORE_EVAS_BUILD = @EFL_ECORE_EVAS_BUILD@ | ||
186 | EFL_ECORE_FILE_BUILD = @EFL_ECORE_FILE_BUILD@ | ||
187 | EFL_ECORE_IMF_BUILD = @EFL_ECORE_IMF_BUILD@ | ||
188 | EFL_ECORE_IMF_EVAS_BUILD = @EFL_ECORE_IMF_EVAS_BUILD@ | ||
189 | EFL_ECORE_INPUT_BUILD = @EFL_ECORE_INPUT_BUILD@ | ||
190 | EFL_ECORE_INPUT_EVAS_BUILD = @EFL_ECORE_INPUT_EVAS_BUILD@ | ||
191 | EFL_ECORE_IPC_BUILD = @EFL_ECORE_IPC_BUILD@ | ||
192 | EFL_ECORE_PSL1GHT_BUILD = @EFL_ECORE_PSL1GHT_BUILD@ | ||
193 | EFL_ECORE_SDL_BUILD = @EFL_ECORE_SDL_BUILD@ | ||
194 | EFL_ECORE_WIN32_BUILD = @EFL_ECORE_WIN32_BUILD@ | ||
195 | EFL_ECORE_WINCE_BUILD = @EFL_ECORE_WINCE_BUILD@ | ||
196 | EFL_PTHREAD_CFLAGS = @EFL_PTHREAD_CFLAGS@ | ||
197 | EFL_PTHREAD_LIBS = @EFL_PTHREAD_LIBS@ | ||
198 | EGREP = @EGREP@ | ||
199 | EINA_CFLAGS = @EINA_CFLAGS@ | ||
200 | EINA_LIBS = @EINA_LIBS@ | ||
201 | ESCAPE_CFLAGS = @ESCAPE_CFLAGS@ | ||
202 | ESCAPE_LIBS = @ESCAPE_LIBS@ | ||
203 | EVAS_CFLAGS = @EVAS_CFLAGS@ | ||
204 | EVAS_LIBS = @EVAS_LIBS@ | ||
205 | EVIL_CFLAGS = @EVIL_CFLAGS@ | ||
206 | EVIL_LIBS = @EVIL_LIBS@ | ||
207 | EXEEXT = @EXEEXT@ | ||
208 | FGREP = @FGREP@ | ||
209 | GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ | ||
210 | GLIB_CFLAGS = @GLIB_CFLAGS@ | ||
211 | GLIB_LIBS = @GLIB_LIBS@ | ||
212 | GMSGFMT = @GMSGFMT@ | ||
213 | GMSGFMT_015 = @GMSGFMT_015@ | ||
214 | GREP = @GREP@ | ||
215 | INSTALL = @INSTALL@ | ||
216 | INSTALL_DATA = @INSTALL_DATA@ | ||
217 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ | ||
218 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ | ||
219 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ | ||
220 | INTLLIBS = @INTLLIBS@ | ||
221 | INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ | ||
222 | KEYSYMDEFS = @KEYSYMDEFS@ | ||
223 | LD = @LD@ | ||
224 | LDFLAGS = @LDFLAGS@ | ||
225 | LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ | ||
226 | LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ | ||
227 | LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ | ||
228 | LIBICONV = @LIBICONV@ | ||
229 | LIBINTL = @LIBINTL@ | ||
230 | LIBOBJS = @LIBOBJS@ | ||
231 | LIBS = @LIBS@ | ||
232 | LIBTOOL = @LIBTOOL@ | ||
233 | LIPO = @LIPO@ | ||
234 | LN_S = @LN_S@ | ||
235 | LTLIBICONV = @LTLIBICONV@ | ||
236 | LTLIBINTL = @LTLIBINTL@ | ||
237 | LTLIBOBJS = @LTLIBOBJS@ | ||
238 | MAKEINFO = @MAKEINFO@ | ||
239 | MKDIR_P = @MKDIR_P@ | ||
240 | MSGFMT = @MSGFMT@ | ||
241 | MSGFMT_015 = @MSGFMT_015@ | ||
242 | MSGMERGE = @MSGMERGE@ | ||
243 | NM = @NM@ | ||
244 | NMEDIT = @NMEDIT@ | ||
245 | OBJC = @OBJC@ | ||
246 | OBJCDEPMODE = @OBJCDEPMODE@ | ||
247 | OBJCFLAGS = @OBJCFLAGS@ | ||
248 | OBJDUMP = @OBJDUMP@ | ||
249 | OBJEXT = @OBJEXT@ | ||
250 | OTOOL = @OTOOL@ | ||
251 | OTOOL64 = @OTOOL64@ | ||
252 | PACKAGE = @PACKAGE@ | ||
253 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ | ||
254 | PACKAGE_NAME = @PACKAGE_NAME@ | ||
255 | PACKAGE_STRING = @PACKAGE_STRING@ | ||
256 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ | ||
257 | PACKAGE_URL = @PACKAGE_URL@ | ||
258 | PACKAGE_VERSION = @PACKAGE_VERSION@ | ||
259 | PATH_SEPARATOR = @PATH_SEPARATOR@ | ||
260 | PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ | ||
261 | PIXMAN_LIBS = @PIXMAN_LIBS@ | ||
262 | PKG_CONFIG = @PKG_CONFIG@ | ||
263 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ | ||
264 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ | ||
265 | POSUB = @POSUB@ | ||
266 | RANLIB = @RANLIB@ | ||
267 | SDL_CFLAGS = @SDL_CFLAGS@ | ||
268 | SDL_CONFIG = @SDL_CONFIG@ | ||
269 | SDL_LIBS = @SDL_LIBS@ | ||
270 | SED = @SED@ | ||
271 | SET_MAKE = @SET_MAKE@ | ||
272 | SHELL = @SHELL@ | ||
273 | SSL_CFLAGS = @SSL_CFLAGS@ | ||
274 | SSL_LIBS = @SSL_LIBS@ | ||
275 | STRIP = @STRIP@ | ||
276 | TLS2_CFLAGS = @TLS2_CFLAGS@ | ||
277 | TLS2_LIBS = @TLS2_LIBS@ | ||
278 | TLS_CFLAGS = @TLS_CFLAGS@ | ||
279 | TLS_LIBS = @TLS_LIBS@ | ||
280 | TSLIB_CFLAGS = @TSLIB_CFLAGS@ | ||
281 | TSLIB_LIBS = @TSLIB_LIBS@ | ||
282 | USE_NLS = @USE_NLS@ | ||
283 | VERSION = @VERSION@ | ||
284 | VMAJ = @VMAJ@ | ||
285 | WIN32_CFLAGS = @WIN32_CFLAGS@ | ||
286 | WIN32_CPPFLAGS = @WIN32_CPPFLAGS@ | ||
287 | WIN32_LIBS = @WIN32_LIBS@ | ||
288 | XCB_COMPOSITE_CFLAGS = @XCB_COMPOSITE_CFLAGS@ | ||
289 | XCB_COMPOSITE_LIBS = @XCB_COMPOSITE_LIBS@ | ||
290 | XCB_CURSOR_CFLAGS = @XCB_CURSOR_CFLAGS@ | ||
291 | XCB_CURSOR_LIBS = @XCB_CURSOR_LIBS@ | ||
292 | XCB_DAMAGE_CFLAGS = @XCB_DAMAGE_CFLAGS@ | ||
293 | XCB_DAMAGE_LIBS = @XCB_DAMAGE_LIBS@ | ||
294 | XCB_DPMS_CFLAGS = @XCB_DPMS_CFLAGS@ | ||
295 | XCB_DPMS_LIBS = @XCB_DPMS_LIBS@ | ||
296 | XCB_RANDR_CFLAGS = @XCB_RANDR_CFLAGS@ | ||
297 | XCB_RANDR_LIBS = @XCB_RANDR_LIBS@ | ||
298 | XCB_RENDER_CFLAGS = @XCB_RENDER_CFLAGS@ | ||
299 | XCB_RENDER_LIBS = @XCB_RENDER_LIBS@ | ||
300 | XCB_SCREENSAVER_CFLAGS = @XCB_SCREENSAVER_CFLAGS@ | ||
301 | XCB_SCREENSAVER_LIBS = @XCB_SCREENSAVER_LIBS@ | ||
302 | XCB_SHAPE_CFLAGS = @XCB_SHAPE_CFLAGS@ | ||
303 | XCB_SHAPE_LIBS = @XCB_SHAPE_LIBS@ | ||
304 | XCB_SYNC_CFLAGS = @XCB_SYNC_CFLAGS@ | ||
305 | XCB_SYNC_LIBS = @XCB_SYNC_LIBS@ | ||
306 | XCB_X11_CFLAGS = @XCB_X11_CFLAGS@ | ||
307 | XCB_X11_LIBS = @XCB_X11_LIBS@ | ||
308 | XCB_XFIXES_CFLAGS = @XCB_XFIXES_CFLAGS@ | ||
309 | XCB_XFIXES_LIBS = @XCB_XFIXES_LIBS@ | ||
310 | XCB_XGESTURE_CFLAGS = @XCB_XGESTURE_CFLAGS@ | ||
311 | XCB_XGESTURE_LIBS = @XCB_XGESTURE_LIBS@ | ||
312 | XCB_XINERAMA_CFLAGS = @XCB_XINERAMA_CFLAGS@ | ||
313 | XCB_XINERAMA_LIBS = @XCB_XINERAMA_LIBS@ | ||
314 | XCB_XINPUT_CFLAGS = @XCB_XINPUT_CFLAGS@ | ||
315 | XCB_XINPUT_LIBS = @XCB_XINPUT_LIBS@ | ||
316 | XCB_XPRINT_CFLAGS = @XCB_XPRINT_CFLAGS@ | ||
317 | XCB_XPRINT_LIBS = @XCB_XPRINT_LIBS@ | ||
318 | XCB_XTEST_CFLAGS = @XCB_XTEST_CFLAGS@ | ||
319 | XCB_XTEST_LIBS = @XCB_XTEST_LIBS@ | ||
320 | XCOMPOSITE_CFLAGS = @XCOMPOSITE_CFLAGS@ | ||
321 | XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ | ||
322 | XDAMAGE_CFLAGS = @XDAMAGE_CFLAGS@ | ||
323 | XDAMAGE_LIBS = @XDAMAGE_LIBS@ | ||
324 | XDPMS_CFLAGS = @XDPMS_CFLAGS@ | ||
325 | XDPMS_LIBS = @XDPMS_LIBS@ | ||
326 | XFIXES_CFLAGS = @XFIXES_CFLAGS@ | ||
327 | XFIXES_LIBS = @XFIXES_LIBS@ | ||
328 | XGESTURE_CFLAGS = @XGESTURE_CFLAGS@ | ||
329 | XGESTURE_LIBS = @XGESTURE_LIBS@ | ||
330 | XGETTEXT = @XGETTEXT@ | ||
331 | XGETTEXT_015 = @XGETTEXT_015@ | ||
332 | XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ | ||
333 | XI2_CFLAGS = @XI2_CFLAGS@ | ||
334 | XI2_LIBS = @XI2_LIBS@ | ||
335 | XINERAMA_CFLAGS = @XINERAMA_CFLAGS@ | ||
336 | XINERAMA_LIBS = @XINERAMA_LIBS@ | ||
337 | XKB_CFLAGS = @XKB_CFLAGS@ | ||
338 | XKB_LIBS = @XKB_LIBS@ | ||
339 | XMKMF = @XMKMF@ | ||
340 | XPRINT_CFLAGS = @XPRINT_CFLAGS@ | ||
341 | XPRINT_LIBS = @XPRINT_LIBS@ | ||
342 | XRANDR_CFLAGS = @XRANDR_CFLAGS@ | ||
343 | XRANDR_LIBS = @XRANDR_LIBS@ | ||
344 | XRENDER_CFLAGS = @XRENDER_CFLAGS@ | ||
345 | XRENDER_LIBS = @XRENDER_LIBS@ | ||
346 | XSS_CFLAGS = @XSS_CFLAGS@ | ||
347 | XSS_LIBS = @XSS_LIBS@ | ||
348 | XTEST_CFLAGS = @XTEST_CFLAGS@ | ||
349 | XTEST_LIBS = @XTEST_LIBS@ | ||
350 | X_CFLAGS = @X_CFLAGS@ | ||
351 | X_EXTRA_LIBS = @X_EXTRA_LIBS@ | ||
352 | X_LIBS = @X_LIBS@ | ||
353 | X_PRE_LIBS = @X_PRE_LIBS@ | ||
354 | Xcursor_cflags = @Xcursor_cflags@ | ||
355 | Xcursor_libs = @Xcursor_libs@ | ||
356 | abs_builddir = @abs_builddir@ | ||
357 | abs_srcdir = @abs_srcdir@ | ||
358 | abs_top_builddir = @abs_top_builddir@ | ||
359 | abs_top_srcdir = @abs_top_srcdir@ | ||
360 | ac_ct_CC = @ac_ct_CC@ | ||
361 | ac_ct_CXX = @ac_ct_CXX@ | ||
362 | ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ | ||
363 | ac_ct_OBJC = @ac_ct_OBJC@ | ||
364 | am__include = @am__include@ | ||
365 | am__leading_dot = @am__leading_dot@ | ||
366 | am__quote = @am__quote@ | ||
367 | am__tar = @am__tar@ | ||
368 | am__untar = @am__untar@ | ||
369 | bindir = @bindir@ | ||
370 | build = @build@ | ||
371 | build_alias = @build_alias@ | ||
372 | build_cpu = @build_cpu@ | ||
373 | build_os = @build_os@ | ||
374 | build_vendor = @build_vendor@ | ||
375 | builddir = @builddir@ | ||
376 | cocoa_ldflags = @cocoa_ldflags@ | ||
377 | datadir = @datadir@ | ||
378 | datarootdir = @datarootdir@ | ||
379 | dlopen_libs = @dlopen_libs@ | ||
380 | docdir = @docdir@ | ||
381 | dvidir = @dvidir@ | ||
382 | ecore_cocoa_cflags = @ecore_cocoa_cflags@ | ||
383 | ecore_cocoa_libs = @ecore_cocoa_libs@ | ||
384 | ecore_con_cflags = @ecore_con_cflags@ | ||
385 | ecore_con_libs = @ecore_con_libs@ | ||
386 | ecore_directfb_cflags = @ecore_directfb_cflags@ | ||
387 | ecore_directfb_libs = @ecore_directfb_libs@ | ||
388 | ecore_evas_cflags = @ecore_evas_cflags@ | ||
389 | ecore_evas_libs = @ecore_evas_libs@ | ||
390 | ecore_fb_cflags = @ecore_fb_cflags@ | ||
391 | ecore_fb_libs = @ecore_fb_libs@ | ||
392 | ecore_file_cflags = @ecore_file_cflags@ | ||
393 | ecore_file_libs = @ecore_file_libs@ | ||
394 | ecore_imf_cflags = @ecore_imf_cflags@ | ||
395 | ecore_imf_evas_cflags = @ecore_imf_evas_cflags@ | ||
396 | ecore_imf_evas_libs = @ecore_imf_evas_libs@ | ||
397 | ecore_imf_libs = @ecore_imf_libs@ | ||
398 | ecore_imf_xim_cflags = @ecore_imf_xim_cflags@ | ||
399 | ecore_imf_xim_libs = @ecore_imf_xim_libs@ | ||
400 | ecore_input_cflags = @ecore_input_cflags@ | ||
401 | ecore_input_evas_cflags = @ecore_input_evas_cflags@ | ||
402 | ecore_input_evas_libs = @ecore_input_evas_libs@ | ||
403 | ecore_input_libs = @ecore_input_libs@ | ||
404 | ecore_ipc_cflags = @ecore_ipc_cflags@ | ||
405 | ecore_ipc_libs = @ecore_ipc_libs@ | ||
406 | ecore_psl1ght_cflags = @ecore_psl1ght_cflags@ | ||
407 | ecore_psl1ght_libs = @ecore_psl1ght_libs@ | ||
408 | ecore_sdl_cflags = @ecore_sdl_cflags@ | ||
409 | ecore_sdl_libs = @ecore_sdl_libs@ | ||
410 | ecore_win32_cflags = @ecore_win32_cflags@ | ||
411 | ecore_win32_libs = @ecore_win32_libs@ | ||
412 | ecore_wince_cflags = @ecore_wince_cflags@ | ||
413 | ecore_wince_libs = @ecore_wince_libs@ | ||
414 | ecore_x_cflags = @ecore_x_cflags@ | ||
415 | ecore_x_libs = @ecore_x_libs@ | ||
416 | ecore_x_libs_private = @ecore_x_libs_private@ | ||
417 | efl_doxygen = @efl_doxygen@ | ||
418 | efl_have_doxygen = @efl_have_doxygen@ | ||
419 | exec_prefix = @exec_prefix@ | ||
420 | have_ecore_x_xcb_define = @have_ecore_x_xcb_define@ | ||
421 | host = @host@ | ||
422 | host_alias = @host_alias@ | ||
423 | host_cpu = @host_cpu@ | ||
424 | host_os = @host_os@ | ||
425 | host_vendor = @host_vendor@ | ||
426 | htmldir = @htmldir@ | ||
427 | includedir = @includedir@ | ||
428 | infodir = @infodir@ | ||
429 | install_sh = @install_sh@ | ||
430 | libdir = @libdir@ | ||
431 | libexecdir = @libexecdir@ | ||
432 | localedir = @localedir@ | ||
433 | localstatedir = @localstatedir@ | ||
434 | lt_ECHO = @lt_ECHO@ | ||
435 | lt_enable_auto_import = @lt_enable_auto_import@ | ||
436 | mandir = @mandir@ | ||
437 | mkdir_p = @mkdir_p@ | ||
438 | oldincludedir = @oldincludedir@ | ||
439 | pdfdir = @pdfdir@ | ||
440 | pkgconfig_requires_private = @pkgconfig_requires_private@ | ||
441 | prefix = @prefix@ | ||
442 | program_transform_name = @program_transform_name@ | ||
443 | psdir = @psdir@ | ||
444 | release_info = @release_info@ | ||
445 | requirements_ecore = @requirements_ecore@ | ||
446 | requirements_ecore_cocoa = @requirements_ecore_cocoa@ | ||
447 | requirements_ecore_con = @requirements_ecore_con@ | ||
448 | requirements_ecore_directfb = @requirements_ecore_directfb@ | ||
449 | requirements_ecore_evas = @requirements_ecore_evas@ | ||
450 | requirements_ecore_fb = @requirements_ecore_fb@ | ||
451 | requirements_ecore_file = @requirements_ecore_file@ | ||
452 | requirements_ecore_imf = @requirements_ecore_imf@ | ||
453 | requirements_ecore_imf_evas = @requirements_ecore_imf_evas@ | ||
454 | requirements_ecore_imf_xim = @requirements_ecore_imf_xim@ | ||
455 | requirements_ecore_input = @requirements_ecore_input@ | ||
456 | requirements_ecore_input_evas = @requirements_ecore_input_evas@ | ||
457 | requirements_ecore_ipc = @requirements_ecore_ipc@ | ||
458 | requirements_ecore_psl1ght = @requirements_ecore_psl1ght@ | ||
459 | requirements_ecore_sdl = @requirements_ecore_sdl@ | ||
460 | requirements_ecore_win32 = @requirements_ecore_win32@ | ||
461 | requirements_ecore_wince = @requirements_ecore_wince@ | ||
462 | requirements_ecore_x = @requirements_ecore_x@ | ||
463 | rt_libs = @rt_libs@ | ||
464 | sbindir = @sbindir@ | ||
465 | sharedstatedir = @sharedstatedir@ | ||
466 | srcdir = @srcdir@ | ||
467 | sysconfdir = @sysconfdir@ | ||
468 | target_alias = @target_alias@ | ||
469 | top_build_prefix = @top_build_prefix@ | ||
470 | top_builddir = @top_builddir@ | ||
471 | top_srcdir = @top_srcdir@ | ||
472 | version_info = @version_info@ | ||
473 | x_cflags = @x_cflags@ | ||
474 | x_includes = @x_includes@ | ||
475 | x_libs = @x_libs@ | ||
476 | MAINTAINERCLEANFILES = Makefile.in | ||
477 | AM_CPPFLAGS = \ | ||
478 | -I$(top_srcdir)/src/lib/ecore \ | ||
479 | -I$(top_srcdir)/src/lib/ecore_ipc \ | ||
480 | -I$(top_srcdir)/ \ | ||
481 | -I$(top_builddir)/src/lib/ecore \ | ||
482 | -I$(top_builddir)/src/lib/ecore_ipc \ | ||
483 | -I$(top_builddir)/ \ | ||
484 | -DPACKAGE_BIN_DIR=\"$(bindir)\" \ | ||
485 | -DPACKAGE_LIB_DIR=\"$(libdir)\" \ | ||
486 | -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ | ||
487 | @EVAS_CFLAGS@ \ | ||
488 | @EET_CFLAGS@ \ | ||
489 | @EINA_CFLAGS@ | ||
490 | |||
491 | CLEANFILES = $(DB) | ||
492 | |||
493 | #DB = system.db | ||
494 | #$(DB): Makefile | ||
495 | # edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/theme/name str "winter" | ||
496 | # edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/font/path str "$(pkgdatadir)/data/fonts" | ||
497 | # edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/browser str `which firefox 2>/dev/null || which phoenix 2>/dev/null || which mozilla 2>/dev/null || which opera 2>/dev/null || which konqueror 2>/dev/null || which epiphany 2>/dev/null` | ||
498 | # edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/email str `which thunderbird 2>/dev/null || which mozilla 2>/dev/null || which kmail 2>/dev/null || which sylpheed 2>/dev/null || which evolution 2>/dev/null` | ||
499 | lib_LTLIBRARIES = libecore_config.la | ||
500 | includes_HEADERS = Ecore_Config.h | ||
501 | includesdir = $(includedir)/ecore-@VMAJ@ | ||
502 | libecore_config_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ | ||
503 | |||
504 | #config_DATA = $(DB) | ||
505 | #configdir = $(pkgdatadir) | ||
506 | libecore_config_la_SOURCES = ecore_config.c ecore_config_util.c \ | ||
507 | ecore_config_storage.c ecore_config_extra.c ecore_config_db.c \ | ||
508 | $(am__append_1) | ||
509 | libecore_config_la_LIBADD = $(top_builddir)/src/lib/ecore/libecore.la \ | ||
510 | @EET_LIBS@ @EINA_LIBS@ @EVAS_LIBS@ $(am__append_2) | ||
511 | EXTRA_DIST = \ | ||
512 | ecore_config_ipc.h \ | ||
513 | ecore_config_private.h \ | ||
514 | ecore_config_util.h | ||
515 | |||
516 | all: all-am | ||
517 | |||
518 | .SUFFIXES: | ||
519 | .SUFFIXES: .c .lo .o .obj | ||
520 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) | ||
521 | @for dep in $?; do \ | ||
522 | case '$(am__configure_deps)' in \ | ||
523 | *$$dep*) \ | ||
524 | ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ | ||
525 | && { if test -f $@; then exit 0; else break; fi; }; \ | ||
526 | exit 1;; \ | ||
527 | esac; \ | ||
528 | done; \ | ||
529 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lib/ecore_config/Makefile'; \ | ||
530 | $(am__cd) $(top_srcdir) && \ | ||
531 | $(AUTOMAKE) --gnu src/lib/ecore_config/Makefile | ||
532 | .PRECIOUS: Makefile | ||
533 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status | ||
534 | @case '$?' in \ | ||
535 | *config.status*) \ | ||
536 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ | ||
537 | *) \ | ||
538 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ | ||
539 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ | ||
540 | esac; | ||
541 | |||
542 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) | ||
543 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
544 | |||
545 | $(top_srcdir)/configure: $(am__configure_deps) | ||
546 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
547 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) | ||
548 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
549 | $(am__aclocal_m4_deps): | ||
550 | install-libLTLIBRARIES: $(lib_LTLIBRARIES) | ||
551 | @$(NORMAL_INSTALL) | ||
552 | test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" | ||
553 | @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ | ||
554 | list2=; for p in $$list; do \ | ||
555 | if test -f $$p; then \ | ||
556 | list2="$$list2 $$p"; \ | ||
557 | else :; fi; \ | ||
558 | done; \ | ||
559 | test -z "$$list2" || { \ | ||
560 | echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ | ||
561 | $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ | ||
562 | } | ||
563 | |||
564 | uninstall-libLTLIBRARIES: | ||
565 | @$(NORMAL_UNINSTALL) | ||
566 | @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ | ||
567 | for p in $$list; do \ | ||
568 | $(am__strip_dir) \ | ||
569 | echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ | ||
570 | $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ | ||
571 | done | ||
572 | |||
573 | clean-libLTLIBRARIES: | ||
574 | -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) | ||
575 | @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ | ||
576 | dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ | ||
577 | test "$$dir" != "$$p" || dir=.; \ | ||
578 | echo "rm -f \"$${dir}/so_locations\""; \ | ||
579 | rm -f "$${dir}/so_locations"; \ | ||
580 | done | ||
581 | libecore_config.la: $(libecore_config_la_OBJECTS) $(libecore_config_la_DEPENDENCIES) | ||
582 | $(AM_V_CCLD)$(libecore_config_la_LINK) -rpath $(libdir) $(libecore_config_la_OBJECTS) $(libecore_config_la_LIBADD) $(LIBS) | ||
583 | |||
584 | mostlyclean-compile: | ||
585 | -rm -f *.$(OBJEXT) | ||
586 | |||
587 | distclean-compile: | ||
588 | -rm -f *.tab.c | ||
589 | |||
590 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_config.Plo@am__quote@ | ||
591 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_config_db.Plo@am__quote@ | ||
592 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_config_extra.Plo@am__quote@ | ||
593 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_config_ipc_ecore.Plo@am__quote@ | ||
594 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_config_ipc_main.Plo@am__quote@ | ||
595 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_config_storage.Plo@am__quote@ | ||
596 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_config_util.Plo@am__quote@ | ||
597 | |||
598 | .c.o: | ||
599 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | ||
600 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
601 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
602 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
603 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
604 | @am__fastdepCC_FALSE@ $(COMPILE) -c $< | ||
605 | |||
606 | .c.obj: | ||
607 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` | ||
608 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
609 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
610 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
611 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
612 | @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` | ||
613 | |||
614 | .c.lo: | ||
615 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | ||
616 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo | ||
617 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
618 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ | ||
619 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
620 | @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< | ||
621 | |||
622 | mostlyclean-libtool: | ||
623 | -rm -f *.lo | ||
624 | |||
625 | clean-libtool: | ||
626 | -rm -rf .libs _libs | ||
627 | install-includesHEADERS: $(includes_HEADERS) | ||
628 | @$(NORMAL_INSTALL) | ||
629 | test -z "$(includesdir)" || $(MKDIR_P) "$(DESTDIR)$(includesdir)" | ||
630 | @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \ | ||
631 | for p in $$list; do \ | ||
632 | if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ | ||
633 | echo "$$d$$p"; \ | ||
634 | done | $(am__base_list) | \ | ||
635 | while read files; do \ | ||
636 | echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includesdir)'"; \ | ||
637 | $(INSTALL_HEADER) $$files "$(DESTDIR)$(includesdir)" || exit $$?; \ | ||
638 | done | ||
639 | |||
640 | uninstall-includesHEADERS: | ||
641 | @$(NORMAL_UNINSTALL) | ||
642 | @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \ | ||
643 | files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ | ||
644 | test -n "$$files" || exit 0; \ | ||
645 | echo " ( cd '$(DESTDIR)$(includesdir)' && rm -f" $$files ")"; \ | ||
646 | cd "$(DESTDIR)$(includesdir)" && rm -f $$files | ||
647 | |||
648 | ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) | ||
649 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
650 | unique=`for i in $$list; do \ | ||
651 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
652 | done | \ | ||
653 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
654 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
655 | mkid -fID $$unique | ||
656 | tags: TAGS | ||
657 | |||
658 | TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
659 | $(TAGS_FILES) $(LISP) | ||
660 | set x; \ | ||
661 | here=`pwd`; \ | ||
662 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
663 | unique=`for i in $$list; do \ | ||
664 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
665 | done | \ | ||
666 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
667 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
668 | shift; \ | ||
669 | if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ | ||
670 | test -n "$$unique" || unique=$$empty_fix; \ | ||
671 | if test $$# -gt 0; then \ | ||
672 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ | ||
673 | "$$@" $$unique; \ | ||
674 | else \ | ||
675 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ | ||
676 | $$unique; \ | ||
677 | fi; \ | ||
678 | fi | ||
679 | ctags: CTAGS | ||
680 | CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
681 | $(TAGS_FILES) $(LISP) | ||
682 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
683 | unique=`for i in $$list; do \ | ||
684 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
685 | done | \ | ||
686 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
687 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
688 | test -z "$(CTAGS_ARGS)$$unique" \ | ||
689 | || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ | ||
690 | $$unique | ||
691 | |||
692 | GTAGS: | ||
693 | here=`$(am__cd) $(top_builddir) && pwd` \ | ||
694 | && $(am__cd) $(top_srcdir) \ | ||
695 | && gtags -i $(GTAGS_ARGS) "$$here" | ||
696 | |||
697 | distclean-tags: | ||
698 | -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags | ||
699 | |||
700 | distdir: $(DISTFILES) | ||
701 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
702 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
703 | list='$(DISTFILES)'; \ | ||
704 | dist_files=`for file in $$list; do echo $$file; done | \ | ||
705 | sed -e "s|^$$srcdirstrip/||;t" \ | ||
706 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ | ||
707 | case $$dist_files in \ | ||
708 | */*) $(MKDIR_P) `echo "$$dist_files" | \ | ||
709 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ | ||
710 | sort -u` ;; \ | ||
711 | esac; \ | ||
712 | for file in $$dist_files; do \ | ||
713 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ | ||
714 | if test -d $$d/$$file; then \ | ||
715 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ | ||
716 | if test -d "$(distdir)/$$file"; then \ | ||
717 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | ||
718 | fi; \ | ||
719 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ | ||
720 | cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ | ||
721 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | ||
722 | fi; \ | ||
723 | cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ | ||
724 | else \ | ||
725 | test -f "$(distdir)/$$file" \ | ||
726 | || cp -p $$d/$$file "$(distdir)/$$file" \ | ||
727 | || exit 1; \ | ||
728 | fi; \ | ||
729 | done | ||
730 | check-am: all-am | ||
731 | check: check-am | ||
732 | all-am: Makefile $(LTLIBRARIES) $(HEADERS) | ||
733 | installdirs: | ||
734 | for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"; do \ | ||
735 | test -z "$$dir" || $(MKDIR_P) "$$dir"; \ | ||
736 | done | ||
737 | install: install-am | ||
738 | install-exec: install-exec-am | ||
739 | install-data: install-data-am | ||
740 | uninstall: uninstall-am | ||
741 | |||
742 | install-am: all-am | ||
743 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | ||
744 | |||
745 | installcheck: installcheck-am | ||
746 | install-strip: | ||
747 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ | ||
748 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ | ||
749 | `test -z '$(STRIP)' || \ | ||
750 | echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install | ||
751 | mostlyclean-generic: | ||
752 | |||
753 | clean-generic: | ||
754 | -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) | ||
755 | |||
756 | distclean-generic: | ||
757 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) | ||
758 | -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) | ||
759 | |||
760 | maintainer-clean-generic: | ||
761 | @echo "This command is intended for maintainers to use" | ||
762 | @echo "it deletes files that may require special tools to rebuild." | ||
763 | -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) | ||
764 | clean: clean-am | ||
765 | |||
766 | clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ | ||
767 | mostlyclean-am | ||
768 | |||
769 | distclean: distclean-am | ||
770 | -rm -rf ./$(DEPDIR) | ||
771 | -rm -f Makefile | ||
772 | distclean-am: clean-am distclean-compile distclean-generic \ | ||
773 | distclean-tags | ||
774 | |||
775 | dvi: dvi-am | ||
776 | |||
777 | dvi-am: | ||
778 | |||
779 | html: html-am | ||
780 | |||
781 | html-am: | ||
782 | |||
783 | info: info-am | ||
784 | |||
785 | info-am: | ||
786 | |||
787 | install-data-am: install-includesHEADERS | ||
788 | |||
789 | install-dvi: install-dvi-am | ||
790 | |||
791 | install-dvi-am: | ||
792 | |||
793 | install-exec-am: install-libLTLIBRARIES | ||
794 | |||
795 | install-html: install-html-am | ||
796 | |||
797 | install-html-am: | ||
798 | |||
799 | install-info: install-info-am | ||
800 | |||
801 | install-info-am: | ||
802 | |||
803 | install-man: | ||
804 | |||
805 | install-pdf: install-pdf-am | ||
806 | |||
807 | install-pdf-am: | ||
808 | |||
809 | install-ps: install-ps-am | ||
810 | |||
811 | install-ps-am: | ||
812 | |||
813 | installcheck-am: | ||
814 | |||
815 | maintainer-clean: maintainer-clean-am | ||
816 | -rm -rf ./$(DEPDIR) | ||
817 | -rm -f Makefile | ||
818 | maintainer-clean-am: distclean-am maintainer-clean-generic | ||
819 | |||
820 | mostlyclean: mostlyclean-am | ||
821 | |||
822 | mostlyclean-am: mostlyclean-compile mostlyclean-generic \ | ||
823 | mostlyclean-libtool | ||
824 | |||
825 | pdf: pdf-am | ||
826 | |||
827 | pdf-am: | ||
828 | |||
829 | ps: ps-am | ||
830 | |||
831 | ps-am: | ||
832 | |||
833 | uninstall-am: uninstall-includesHEADERS uninstall-libLTLIBRARIES | ||
834 | |||
835 | .MAKE: install-am install-strip | ||
836 | |||
837 | .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ | ||
838 | clean-libLTLIBRARIES clean-libtool ctags distclean \ | ||
839 | distclean-compile distclean-generic distclean-libtool \ | ||
840 | distclean-tags distdir dvi dvi-am html html-am info info-am \ | ||
841 | install install-am install-data install-data-am install-dvi \ | ||
842 | install-dvi-am install-exec install-exec-am install-html \ | ||
843 | install-html-am install-includesHEADERS install-info \ | ||
844 | install-info-am install-libLTLIBRARIES install-man install-pdf \ | ||
845 | install-pdf-am install-ps install-ps-am install-strip \ | ||
846 | installcheck installcheck-am installdirs maintainer-clean \ | ||
847 | maintainer-clean-generic mostlyclean mostlyclean-compile \ | ||
848 | mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ | ||
849 | tags uninstall uninstall-am uninstall-includesHEADERS \ | ||
850 | uninstall-libLTLIBRARIES | ||
851 | |||
852 | |||
853 | # Tell versions [3.59,3.63) of GNU make to not export all variables. | ||
854 | # Otherwise a system limit (for SysV at least) may be exceeded. | ||
855 | .NOEXPORT: | ||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config.c b/libraries/ecore/src/lib/ecore_config/ecore_config.c new file mode 100644 index 0000000..e81538e --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config.c | |||
@@ -0,0 +1,1870 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <string.h> | ||
6 | #include <ctype.h> | ||
7 | #include <stdio.h> | ||
8 | #include <stdlib.h> | ||
9 | |||
10 | #include <sys/param.h> | ||
11 | #include <sys/types.h> | ||
12 | #include <sys/stat.h> | ||
13 | #include <fcntl.h> | ||
14 | #include <limits.h> | ||
15 | #include <unistd.h> | ||
16 | |||
17 | #include "Ecore_Config.h" | ||
18 | #include "ecore_config_private.h" | ||
19 | #include "ecore_config_ipc.h" | ||
20 | |||
21 | #include "ecore_config_util.h" | ||
22 | int _ecore_config_log_dom = -1; | ||
23 | int DEBUG = 0; | ||
24 | EAPI Ecore_Config_Server *__ecore_config_server_global = NULL; | ||
25 | EAPI Ecore_Config_Server *__ecore_config_server_local = NULL; | ||
26 | EAPI Ecore_Config_Bundle *__ecore_config_bundle_local = NULL; | ||
27 | EAPI char *__ecore_config_app_name = NULL; | ||
28 | int __ecore_config_system_init = 0; | ||
29 | |||
30 | static int _ecore_config_system_init_no_load(void); | ||
31 | static int _ecore_config_system_load(void); | ||
32 | |||
33 | static inline void *__ecore_argb_to_long(int a, int r, int g, int b, long *v); | ||
34 | static inline void *__ecore_argbstr_to_long(const char *argb, long *v); | ||
35 | |||
36 | static const char *_ecore_config_type[] = | ||
37 | { "undefined", "integer", "float", "string", "colour", "theme", "boolean", "structure" }; | ||
38 | |||
39 | /** | ||
40 | * @defgroup Ecore_Config_Property_Group Ecore Config Property Functions | ||
41 | * | ||
42 | * Functions that retrieve or set the attributes relating to a property. | ||
43 | */ | ||
44 | |||
45 | /** | ||
46 | * Removes the given property from the local configuration and destroys it. | ||
47 | * @param e Property to destroy. | ||
48 | * @return @c NULL | ||
49 | * @ingroup Ecore_Config_Property_Group | ||
50 | */ | ||
51 | EAPI Ecore_Config_Prop * | ||
52 | ecore_config_dst(Ecore_Config_Prop * e) | ||
53 | { | ||
54 | Ecore_Config_Bundle *t; | ||
55 | Ecore_Config_Prop *p, *c; | ||
56 | Ecore_Config_Listener_List *l; | ||
57 | |||
58 | p = NULL; | ||
59 | t = __ecore_config_bundle_local; | ||
60 | c = t->data; | ||
61 | |||
62 | if (!e || !e->key) | ||
63 | return NULL; | ||
64 | if (t) | ||
65 | { | ||
66 | if (t->data == e) | ||
67 | t->data = e->next; | ||
68 | else | ||
69 | { | ||
70 | do | ||
71 | { | ||
72 | p = c; | ||
73 | c = c->next; | ||
74 | } | ||
75 | while (c && (c != e)); | ||
76 | if (c) /* remove from list if even in there */ | ||
77 | p->next = c->next; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | while (e->listeners) | ||
82 | { | ||
83 | l = e->listeners; | ||
84 | e->listeners = e->listeners->next; | ||
85 | free(l); | ||
86 | } | ||
87 | |||
88 | if (e->key) | ||
89 | free(e->key); | ||
90 | if (e->ptr && ((e->type == ECORE_CONFIG_STR) || (e->type == ECORE_CONFIG_THM))) | ||
91 | free(e->ptr); | ||
92 | |||
93 | memset(e, 0, sizeof(Ecore_Config_Prop)); | ||
94 | free(e); | ||
95 | |||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * @defgroup Ecore_Config_Get_Group Configuration Retrieve Functions | ||
101 | * | ||
102 | * Functions that retrieve configuration values, based on type. | ||
103 | */ | ||
104 | |||
105 | /** | ||
106 | * Returns the property with the given key. | ||
107 | * @param key The unique name of the wanted property. | ||
108 | * @return The property that corresponds to the given key. @c NULL if the | ||
109 | * key could not be found. | ||
110 | * @ingroup Ecore_Config_Get_Group | ||
111 | */ | ||
112 | EAPI Ecore_Config_Prop * | ||
113 | ecore_config_get(const char *key) | ||
114 | { | ||
115 | Ecore_Config_Bundle *t; | ||
116 | Ecore_Config_Prop *e; | ||
117 | |||
118 | t = __ecore_config_bundle_local; | ||
119 | if (!t || !key) | ||
120 | return NULL; | ||
121 | e = t->data; | ||
122 | while (e) | ||
123 | { | ||
124 | if (!strcmp(key, e->key)) | ||
125 | return e; | ||
126 | e = e->next; | ||
127 | } | ||
128 | return NULL; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Returns the type of the property. | ||
133 | * @param e Property to get the type of. | ||
134 | * @returns The type of the property. If the property is invalid, then the | ||
135 | * string "not found" is returned. | ||
136 | * @ingroup Ecore_Config_Property_Group | ||
137 | */ | ||
138 | EAPI const char * | ||
139 | ecore_config_type_get(const Ecore_Config_Prop * e) | ||
140 | { | ||
141 | if (e) | ||
142 | { | ||
143 | return _ecore_config_type[e->type]; | ||
144 | } | ||
145 | return "not found"; | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * Returns the specified property as a string. | ||
150 | * @param key The property key. | ||
151 | * @return The string value of the property. The function returns @c NULL if | ||
152 | * the property is not a string or is not set. | ||
153 | * @ingroup Ecore_Config_Get_Group | ||
154 | */ | ||
155 | EAPI char * | ||
156 | ecore_config_string_get(const char *key) | ||
157 | { | ||
158 | return _ecore_config_string_get( ecore_config_get(key) ); | ||
159 | } | ||
160 | |||
161 | char * | ||
162 | _ecore_config_string_get(Ecore_Config_Prop *e) | ||
163 | { | ||
164 | return (e && (e->type == ECORE_CONFIG_STR) && e->ptr) ? strdup(e->ptr) : NULL; | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * Returns the specified property as an integer. | ||
169 | * @param key The property key. | ||
170 | * @return The value of the property. The function returns -1 if the | ||
171 | * property is not an integer or is not set. | ||
172 | * @ingroup Ecore_Config_Get_Group | ||
173 | */ | ||
174 | EAPI int | ||
175 | ecore_config_boolean_get(const char *key) | ||
176 | { | ||
177 | return _ecore_config_boolean_get( ecore_config_get(key) ); | ||
178 | } | ||
179 | |||
180 | int | ||
181 | _ecore_config_boolean_get(Ecore_Config_Prop *e) | ||
182 | { | ||
183 | return (e && ((e->type == ECORE_CONFIG_INT) || (e->type == ECORE_CONFIG_BLN))) ? (e->val != 0) : -1; | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns the specified property as a long integer. | ||
188 | * @param key The property key. | ||
189 | * @return The integer value of the property. The function returns 0 if the | ||
190 | * property is not an integer or is not set. | ||
191 | * @ingroup Ecore_Config_Get_Group | ||
192 | */ | ||
193 | EAPI long | ||
194 | ecore_config_int_get(const char *key) | ||
195 | { | ||
196 | return _ecore_config_int_get( ecore_config_get(key) ); | ||
197 | } | ||
198 | |||
199 | long | ||
200 | _ecore_config_int_get(Ecore_Config_Prop *e) | ||
201 | { | ||
202 | return (e && ((e->type == ECORE_CONFIG_INT) || (e->type == ECORE_CONFIG_RGB))) ? e->val : 0L; | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * Returns the specified property as a float. | ||
207 | * @param key The property key. | ||
208 | * @return The float value of the property. The function returns 0.0 if the | ||
209 | * property is not a float or is not set. | ||
210 | * @ingroup Ecore_Config_Get_Group | ||
211 | */ | ||
212 | EAPI float | ||
213 | ecore_config_float_get(const char *key) | ||
214 | { | ||
215 | return _ecore_config_float_get( ecore_config_get(key) ); | ||
216 | } | ||
217 | |||
218 | float | ||
219 | _ecore_config_float_get(Ecore_Config_Prop *e) | ||
220 | { | ||
221 | return (e && (e->type == ECORE_CONFIG_FLT)) ? ((float)e->val / ECORE_CONFIG_FLOAT_PRECISION) : 0.0; | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * Finds the alpha, red, green and blue values of a color property. | ||
226 | * @param key The property key. | ||
227 | * @param a A pointer to an integer to store the alpha value into. | ||
228 | * @param r A pointer to an integer to store the red value into. | ||
229 | * @param g A pointer to an integer to store the green value into. | ||
230 | * @param b A pointer to an integer to store the blue value into. | ||
231 | * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL | ||
232 | * otherwise. | ||
233 | * @ingroup Ecore_Config_Get_Group | ||
234 | */ | ||
235 | EAPI int | ||
236 | ecore_config_argb_get(const char *key, int *a, int *r, int *g, int *b) | ||
237 | { | ||
238 | return _ecore_config_argb_get( ecore_config_get(key), a, r, g, b); | ||
239 | } | ||
240 | |||
241 | int | ||
242 | _ecore_config_argb_get(Ecore_Config_Prop *e, int *a, int *r, int *g, int *b) | ||
243 | { | ||
244 | if (e && ((e->type == ECORE_CONFIG_RGB))) | ||
245 | { | ||
246 | if(a) *a = (e->val >> 24) & 0xff; | ||
247 | if(r) *r = (e->val >> 16) & 0xff; | ||
248 | if(g) *g = (e->val >> 8) & 0xff; | ||
249 | if(b) *b = e->val & 0xff; | ||
250 | return ECORE_CONFIG_ERR_SUCC; | ||
251 | } | ||
252 | return ECORE_CONFIG_ERR_FAIL; | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * Returns a color property as a long | ||
257 | * @param key The property key. | ||
258 | * @return ARGB data as long | ||
259 | * @ingroup Ecore_Config_Get_Group | ||
260 | */ | ||
261 | EAPI long | ||
262 | ecore_config_argbint_get(const char *key) | ||
263 | { | ||
264 | return _ecore_config_argbint_get( ecore_config_get(key) ); | ||
265 | } | ||
266 | |||
267 | long | ||
268 | _ecore_config_argbint_get(Ecore_Config_Prop *e) | ||
269 | { | ||
270 | if (e && ((e->type == ECORE_CONFIG_RGB))) | ||
271 | { | ||
272 | return e->val; | ||
273 | } | ||
274 | return 0L; | ||
275 | } | ||
276 | |||
277 | /** | ||
278 | * Returns a color property as a string of hexadecimal characters. | ||
279 | * @param key The property key. | ||
280 | * @return A string of hexadecimal characters in the format #aarrggbb. | ||
281 | * @ingroup Ecore_Config_Get_Group | ||
282 | */ | ||
283 | EAPI char * | ||
284 | ecore_config_argbstr_get(const char *key) | ||
285 | { | ||
286 | return _ecore_config_argbstr_get( ecore_config_get(key) ); | ||
287 | } | ||
288 | |||
289 | char * | ||
290 | _ecore_config_argbstr_get(Ecore_Config_Prop *e) | ||
291 | { | ||
292 | char *r; | ||
293 | |||
294 | r = NULL; | ||
295 | esprintf(&r, "#%08x", _ecore_config_int_get(e)); | ||
296 | return r; | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * Returns a theme property. | ||
301 | * @param key The property key. | ||
302 | * @return The name of the theme the property refers to. The function returns | ||
303 | * @c NULL if the property is not a theme or is not set. | ||
304 | * @ingroup Ecore_Config_Get_Group | ||
305 | */ | ||
306 | EAPI char * | ||
307 | ecore_config_theme_get(const char *key) | ||
308 | { | ||
309 | return _ecore_config_theme_get( ecore_config_get(key) ); | ||
310 | } | ||
311 | |||
312 | char * | ||
313 | _ecore_config_theme_get(Ecore_Config_Prop *e) | ||
314 | { | ||
315 | return (e && (e->type == ECORE_CONFIG_THM)) ? strdup(e->ptr) : NULL; | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * Retrieves the key as a string. | ||
320 | * @param key The property key. | ||
321 | * @return Returns a character array in the form of 'key:type=value'. @c NULL | ||
322 | * is returned if the property does not exist. | ||
323 | * @ingroup Ecore_Config_Get_Group | ||
324 | */ | ||
325 | EAPI char * | ||
326 | ecore_config_as_string_get(const char *key) | ||
327 | { | ||
328 | Ecore_Config_Prop *e; | ||
329 | char *val; | ||
330 | char *r; | ||
331 | |||
332 | val = NULL; | ||
333 | r = NULL; | ||
334 | if (!(e = ecore_config_get(key))) | ||
335 | ERR("no such property, \"%s\"...", key); | ||
336 | else | ||
337 | { | ||
338 | switch (e->type) | ||
339 | { | ||
340 | case ECORE_CONFIG_NIL: | ||
341 | val = strdup("<nil>"); | ||
342 | break; | ||
343 | case ECORE_CONFIG_INT: | ||
344 | esprintf(&val, "%ld", _ecore_config_int_get(e)); | ||
345 | break; | ||
346 | case ECORE_CONFIG_BLN: | ||
347 | esprintf(&val, "%ld", _ecore_config_boolean_get(e)); | ||
348 | break; | ||
349 | case ECORE_CONFIG_FLT: | ||
350 | esprintf(&val, "%lf", _ecore_config_float_get(e)); | ||
351 | break; | ||
352 | case ECORE_CONFIG_STR: | ||
353 | esprintf(&val, "\"%s\"", _ecore_config_string_get(e)); | ||
354 | break; | ||
355 | case ECORE_CONFIG_RGB: | ||
356 | esprintf(&val, "#%08x", _ecore_config_int_get(e)); | ||
357 | break; | ||
358 | case ECORE_CONFIG_THM: | ||
359 | esprintf(&val, "\"%s\"", _ecore_config_theme_get(e)); | ||
360 | break; | ||
361 | case ECORE_CONFIG_SCT: | ||
362 | break; | ||
363 | default: | ||
364 | esprintf(&r, "%s:unknown_type", key); | ||
365 | break; | ||
366 | } | ||
367 | if (val) | ||
368 | { | ||
369 | esprintf(&r, "%s:%s=%s", key, _ecore_config_type[e->type], val); | ||
370 | free(val); | ||
371 | } | ||
372 | } | ||
373 | return r; | ||
374 | } | ||
375 | |||
376 | EAPI int | ||
377 | ecore_config_bound(Ecore_Config_Prop * e) | ||
378 | { | ||
379 | int ret; | ||
380 | long v; | ||
381 | |||
382 | ret = ECORE_CONFIG_ERR_SUCC; | ||
383 | |||
384 | if (!e) | ||
385 | return ECORE_CONFIG_ERR_FAIL; | ||
386 | if (e->flags & ECORE_CONFIG_FLAG_BOUNDS) | ||
387 | { | ||
388 | if ((e->val < e->lo)) | ||
389 | { | ||
390 | WRN("ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...", | ||
391 | e->key, e->val, e->lo); | ||
392 | e->val = e->lo; | ||
393 | } | ||
394 | else if ((e->val > e->hi)) | ||
395 | { | ||
396 | WRN("ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...", | ||
397 | e->key, e->val, e->hi); | ||
398 | e->val = e->hi; | ||
399 | } | ||
400 | else | ||
401 | ret = ECORE_CONFIG_ERR_IGNORED; | ||
402 | } | ||
403 | else | ||
404 | ret = ECORE_CONFIG_ERR_IGNORED; | ||
405 | |||
406 | if (e->step) | ||
407 | { | ||
408 | v = ((int)(e->val / e->step)) * e->step; | ||
409 | if (v != e->val) | ||
410 | { | ||
411 | if (e->type == ECORE_CONFIG_FLT) | ||
412 | WRN("ecore_config_bound(\"%s\"): float value %f not a multiple of %f, adjusted to %f...", | ||
413 | e->key, ((double)e->val) / ECORE_CONFIG_FLOAT_PRECISION, | ||
414 | ((double)e->step) / ECORE_CONFIG_FLOAT_PRECISION, | ||
415 | ((double)v) / ECORE_CONFIG_FLOAT_PRECISION); | ||
416 | else | ||
417 | WRN("ecore_config_bound(\"%s\"): integer value %ld not a multiple of %ld, adjusted to %ld...", | ||
418 | e->key, e->val, e->step, v); | ||
419 | ret = ECORE_CONFIG_ERR_SUCC; | ||
420 | e->val = v; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | /** | ||
428 | * Tries to guess the type of a property. | ||
429 | * | ||
430 | * This function first checks to see if the property exists. If it does, then | ||
431 | * the type of the stored property is returned. Otherwise, the function tries | ||
432 | * to guess the type of the property based on @p val. | ||
433 | * | ||
434 | * @param key The property key. | ||
435 | * @param val The value in string form. | ||
436 | * @return The type of the property determined by the function. Note that if | ||
437 | * val is @c NULL, @c ECORE_CONFIG_NIL will be returned. | ||
438 | */ | ||
439 | EAPI int | ||
440 | ecore_config_type_guess(const char *key, const char *val) | ||
441 | { | ||
442 | Ecore_Config_Prop *p; | ||
443 | char *l; | ||
444 | |||
445 | l = NULL; | ||
446 | |||
447 | if (key && (p = ecore_config_get(key)) && p->type != ECORE_CONFIG_NIL) | ||
448 | return p->type; | ||
449 | |||
450 | if (!val) | ||
451 | return ECORE_CONFIG_NIL; | ||
452 | if (val[0] == '#') | ||
453 | return ECORE_CONFIG_RGB; | ||
454 | strtol(val, &l, 10); | ||
455 | if (*l) | ||
456 | { | ||
457 | float f; | ||
458 | |||
459 | if (sscanf(val, "%f%*s", &f) != 1) | ||
460 | return ECORE_CONFIG_STR; | ||
461 | return ECORE_CONFIG_FLT; | ||
462 | } | ||
463 | return ECORE_CONFIG_INT; | ||
464 | } | ||
465 | |||
466 | static int | ||
467 | ecore_config_typed_val(Ecore_Config_Prop * e, const void *val, int type) | ||
468 | { | ||
469 | |||
470 | if (!e) | ||
471 | return ECORE_CONFIG_ERR_NODATA; | ||
472 | |||
473 | if (!(val) && (type != ECORE_CONFIG_NIL && type != ECORE_CONFIG_SCT)) | ||
474 | e->ptr = NULL; | ||
475 | else | ||
476 | { | ||
477 | if (type == ECORE_CONFIG_INT || type == ECORE_CONFIG_BLN) | ||
478 | { | ||
479 | e->val = (long) *((int *)val); | ||
480 | e->type = type; | ||
481 | } | ||
482 | else if (type == ECORE_CONFIG_STR || type == ECORE_CONFIG_THM) | ||
483 | { | ||
484 | if (!(e->ptr = strdup(val))) | ||
485 | return ECORE_CONFIG_ERR_OOM; | ||
486 | if (e->type == ECORE_CONFIG_NIL) | ||
487 | e->type = type; | ||
488 | } | ||
489 | else if (type == ECORE_CONFIG_RGB) | ||
490 | { | ||
491 | __ecore_argbstr_to_long((char *)val, &e->val); | ||
492 | e->type = ECORE_CONFIG_RGB; | ||
493 | } | ||
494 | else if (type == ECORE_CONFIG_FLT) | ||
495 | { | ||
496 | e->val = (long) ((*((float *)val)) * ECORE_CONFIG_FLOAT_PRECISION); | ||
497 | e->type = ECORE_CONFIG_FLT; | ||
498 | } | ||
499 | else if (type == ECORE_CONFIG_SCT) | ||
500 | { | ||
501 | e->type = ECORE_CONFIG_SCT; | ||
502 | } | ||
503 | else | ||
504 | { | ||
505 | e->type = ECORE_CONFIG_NIL; | ||
506 | } | ||
507 | |||
508 | ecore_config_bound(e); | ||
509 | e->flags |= ECORE_CONFIG_FLAG_MODIFIED; | ||
510 | e->flags &= ~ECORE_CONFIG_FLAG_CMDLN; | ||
511 | return ECORE_CONFIG_ERR_SUCC; | ||
512 | } | ||
513 | return ECORE_CONFIG_ERR_IGNORED; | ||
514 | } | ||
515 | |||
516 | static int | ||
517 | ecore_config_typed_add(const char *key, const void *val, int type) | ||
518 | { | ||
519 | int error = ECORE_CONFIG_ERR_SUCC; | ||
520 | Ecore_Config_Prop *e = NULL; | ||
521 | Ecore_Config_Bundle *t; | ||
522 | |||
523 | t = __ecore_config_bundle_local; | ||
524 | if (!key) | ||
525 | return ECORE_CONFIG_ERR_NODATA; | ||
526 | |||
527 | if (!(e = calloc(1, sizeof(Ecore_Config_Prop)))) | ||
528 | { | ||
529 | return ECORE_CONFIG_ERR_OOM; | ||
530 | } | ||
531 | else if (!(e->key = strdup(key))) | ||
532 | { | ||
533 | error = ECORE_CONFIG_ERR_OOM; | ||
534 | } | ||
535 | else if ((error = ecore_config_typed_val(e, val, type)) == ECORE_CONFIG_ERR_SUCC) | ||
536 | { | ||
537 | if (t) | ||
538 | { | ||
539 | e->next = t->data; | ||
540 | t->data = e; | ||
541 | } | ||
542 | return ECORE_CONFIG_ERR_SUCC; | ||
543 | } | ||
544 | |||
545 | if(e->key) | ||
546 | free(e->key); | ||
547 | if(e) | ||
548 | free(e); | ||
549 | |||
550 | if (error == ECORE_CONFIG_ERR_SUCC) | ||
551 | error = ECORE_CONFIG_ERR_FAIL; | ||
552 | |||
553 | return error; | ||
554 | } | ||
555 | |||
556 | static int | ||
557 | ecore_config_add(const char *key, const char *val) | ||
558 | { | ||
559 | int type; | ||
560 | |||
561 | type = ecore_config_type_guess(key, val); | ||
562 | return ecore_config_typed_add(key, val, type); | ||
563 | } | ||
564 | |||
565 | /** | ||
566 | * Sets the description field of the indicated property. | ||
567 | * @param key The property key. | ||
568 | * @param desc Description string. | ||
569 | * @note The description string is copied for the property's use. You can | ||
570 | * free @p desc once this function is called. | ||
571 | * @ingroup Ecore_Config_Property_Group | ||
572 | */ | ||
573 | EAPI int | ||
574 | ecore_config_describe(const char *key, const char *desc) | ||
575 | { | ||
576 | Ecore_Config_Prop *e; | ||
577 | |||
578 | if (!(e = ecore_config_get(key))) | ||
579 | return ECORE_CONFIG_ERR_NODATA; | ||
580 | e->description = strdup(desc); | ||
581 | return ECORE_CONFIG_ERR_SUCC; | ||
582 | } | ||
583 | |||
584 | /** | ||
585 | * Set the short option character of a property. | ||
586 | * @param key The property key. | ||
587 | * @param short_opt Character used to indicate the value of a property | ||
588 | * given on the command line. | ||
589 | * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA | ||
590 | * is returned if the property does not exist. | ||
591 | * @ingroup Ecore_Config_Property_Group | ||
592 | */ | ||
593 | EAPI int | ||
594 | ecore_config_short_opt_set(const char *key, char short_opt) | ||
595 | { | ||
596 | Ecore_Config_Prop *e; | ||
597 | |||
598 | if (!(e = ecore_config_get(key))) | ||
599 | return ECORE_CONFIG_ERR_NODATA; | ||
600 | e->short_opt = short_opt; | ||
601 | return ECORE_CONFIG_ERR_SUCC; | ||
602 | } | ||
603 | |||
604 | /** | ||
605 | * Set the long option string of the property. | ||
606 | * @param key The property key. | ||
607 | * @param long_opt String used to indicate the value of a property given | ||
608 | * on the command line. | ||
609 | * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA | ||
610 | * is returned if the property does not exist. | ||
611 | * @ingroup Ecore_Config_Property_Group | ||
612 | */ | ||
613 | EAPI int | ||
614 | ecore_config_long_opt_set(const char *key, const char *long_opt) | ||
615 | { | ||
616 | Ecore_Config_Prop *e; | ||
617 | |||
618 | if (!(e = ecore_config_get(key))) | ||
619 | return ECORE_CONFIG_ERR_NODATA; | ||
620 | if (e->long_opt) | ||
621 | free(e->long_opt); | ||
622 | if (long_opt) | ||
623 | e->long_opt = strdup(long_opt); | ||
624 | return ECORE_CONFIG_ERR_SUCC; | ||
625 | } | ||
626 | |||
627 | static void | ||
628 | _ecore_config_listener_fire(Ecore_Config_Prop *prop) | ||
629 | { | ||
630 | Ecore_Config_Listener_List *l; | ||
631 | for (l = prop->listeners; l; l = l->next) | ||
632 | l->listener(prop->key, prop->type, l->tag, l->data); | ||
633 | |||
634 | /* fire change listeners for the generic struct container etc */ | ||
635 | if (prop->parent) | ||
636 | _ecore_config_listener_fire(prop->parent); | ||
637 | } | ||
638 | |||
639 | /** | ||
640 | * Sets the indicated property to the given value and type. | ||
641 | * @param key The property key. | ||
642 | * @param val A pointer to the value to set the property to. | ||
643 | * @param type The type of the property. | ||
644 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
645 | * @ingroup Ecore_Config_Property_Group | ||
646 | */ | ||
647 | EAPI int | ||
648 | ecore_config_typed_set(const char *key, const void *val, int type) | ||
649 | { | ||
650 | Ecore_Config_Prop *e; | ||
651 | int ret; | ||
652 | |||
653 | if (!key) | ||
654 | return ECORE_CONFIG_ERR_NODATA; | ||
655 | /* if (!t) { * global prop * | ||
656 | e=ecore_config_get(key); | ||
657 | if (e) | ||
658 | for(l=e->listeners;l;l=l->next) | ||
659 | l->listener(e->key,e->type,l->tag,l->data,t); | ||
660 | return ECORE_CONFIG_ERR_SUCC; | ||
661 | } | ||
662 | */ | ||
663 | if (!(e = ecore_config_get(key))) | ||
664 | return ecore_config_typed_add(key, val, type); | ||
665 | |||
666 | if ((ret = ecore_config_typed_val(e, val, type)) == ECORE_CONFIG_ERR_SUCC) | ||
667 | { | ||
668 | _ecore_config_listener_fire(e); | ||
669 | } | ||
670 | else | ||
671 | { | ||
672 | ERR("ecore_config_typed_set(\"%s\"): ecore_config_typed_val() failed: %d", | ||
673 | key, ret); | ||
674 | } | ||
675 | |||
676 | return ret; | ||
677 | } | ||
678 | |||
679 | /** | ||
680 | * @defgroup Ecore_Config_Set_Group Ecore Config Setters | ||
681 | * | ||
682 | * Functions that set the value of a property. | ||
683 | */ | ||
684 | |||
685 | /** | ||
686 | * Sets the indicated property to the value indicated by @a val. | ||
687 | * @param key The property key. | ||
688 | * @param val String representation of value to set. | ||
689 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
690 | * @ingroup Ecore_Config_Set_Group | ||
691 | */ | ||
692 | EAPI int | ||
693 | ecore_config_set(const char *key, const char *val) | ||
694 | { | ||
695 | int type; | ||
696 | int tmpi; | ||
697 | float tmpf; | ||
698 | long tmpl; | ||
699 | |||
700 | type = ecore_config_type_guess(key, val); | ||
701 | if (type == ECORE_CONFIG_INT || type == ECORE_CONFIG_BLN) | ||
702 | { | ||
703 | tmpi = atoi(val); | ||
704 | return ecore_config_typed_set(key, &tmpi, type); | ||
705 | } | ||
706 | else if (type == ECORE_CONFIG_FLT) | ||
707 | { | ||
708 | tmpf = atof(val); | ||
709 | return ecore_config_typed_set(key, &tmpf, type); | ||
710 | } | ||
711 | else if (type == ECORE_CONFIG_RGB) | ||
712 | { | ||
713 | __ecore_argbstr_to_long(val, &tmpl); | ||
714 | return ecore_config_typed_set(key, &tmpl, type); | ||
715 | } | ||
716 | else | ||
717 | return ecore_config_typed_set(key, val, type); | ||
718 | } | ||
719 | |||
720 | /** | ||
721 | * Sets the indicated property to the value given in the string. | ||
722 | * @param key The property key. | ||
723 | * @param val String representation of the value. | ||
724 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
725 | * @ingroup Ecore_Config_Set_Group | ||
726 | */ | ||
727 | EAPI int | ||
728 | ecore_config_as_string_set(const char *key, const char *val) | ||
729 | { | ||
730 | return ecore_config_set(key, val); | ||
731 | } | ||
732 | |||
733 | /** | ||
734 | * Sets the indicated property to the given boolean. | ||
735 | * @param key The property key. | ||
736 | * @param val Boolean integer to set the property to. | ||
737 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
738 | * @ingroup Ecore_Config_Set_Group | ||
739 | */ | ||
740 | EAPI int | ||
741 | ecore_config_boolean_set(const char *key, int val) | ||
742 | { | ||
743 | val = val ? 1 : 0; | ||
744 | return ecore_config_typed_set(key, &val, ECORE_CONFIG_BLN); | ||
745 | } | ||
746 | |||
747 | /** | ||
748 | * Sets the indicated property to the given integer. | ||
749 | * @param key The property key. | ||
750 | * @param val Integer to set the property to. | ||
751 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
752 | * @ingroup Ecore_Config_Set_Group | ||
753 | */ | ||
754 | EAPI int | ||
755 | ecore_config_int_set(const char *key, int val) | ||
756 | { | ||
757 | return ecore_config_typed_set(key, &val, ECORE_CONFIG_INT); | ||
758 | } | ||
759 | |||
760 | /** | ||
761 | * Sets the indicated property to the given string. | ||
762 | * @param key The property key. | ||
763 | * @param val String to set the property to. | ||
764 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
765 | * @ingroup Ecore_Config_Set_Group | ||
766 | */ | ||
767 | EAPI int | ||
768 | ecore_config_string_set(const char *key, const char *val) | ||
769 | { | ||
770 | return ecore_config_typed_set(key, val, ECORE_CONFIG_STR); | ||
771 | } | ||
772 | |||
773 | /** | ||
774 | * Sets the indicated property to the given float value. | ||
775 | * @param key The property key. | ||
776 | * @param val Float to set the property to. | ||
777 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
778 | * @ingroup Ecore_Config_Set_Group | ||
779 | */ | ||
780 | EAPI int | ||
781 | ecore_config_float_set(const char *key, float val) | ||
782 | { | ||
783 | return ecore_config_typed_set(key, &val, ECORE_CONFIG_FLT); | ||
784 | } | ||
785 | |||
786 | /** | ||
787 | * Sets the indicated property to a color value. | ||
788 | * @param key The property key | ||
789 | * @param a integer 0..255 | ||
790 | * @param r integer 0..255 | ||
791 | * @param g integer 0..255 | ||
792 | * @param b integer 0..255 | ||
793 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
794 | * @ingroup Ecore_Config_Set_Group | ||
795 | */ | ||
796 | EAPI int | ||
797 | ecore_config_argb_set(const char *key, int a, int r, int g, int b) | ||
798 | { | ||
799 | long v = 0; | ||
800 | return ecore_config_typed_set(key, __ecore_argb_to_long(a,r,g,b, &v), ECORE_CONFIG_RGB); | ||
801 | } | ||
802 | |||
803 | /** | ||
804 | * Sets the indicated property to a color value. | ||
805 | * @param key The property key | ||
806 | * @param argb ARGB data as long | ||
807 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
808 | * @ingroup Ecore_Config_Set_Group | ||
809 | */ | ||
810 | EAPI int | ||
811 | ecore_config_argbint_set(const char *key, long argb) | ||
812 | { | ||
813 | return ecore_config_typed_set(key, &argb, ECORE_CONFIG_RGB); | ||
814 | } | ||
815 | |||
816 | /** | ||
817 | * Sets the indicated property to a color value. | ||
818 | * @param key The property key | ||
819 | * @param val Color value in ARGB format. | ||
820 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
821 | * @ingroup Ecore_Config_Set_Group | ||
822 | */ | ||
823 | EAPI int | ||
824 | ecore_config_argbstr_set(const char *key, const char *val) | ||
825 | { | ||
826 | long v = 0; | ||
827 | return ecore_config_typed_set(key, __ecore_argbstr_to_long(val, &v), ECORE_CONFIG_RGB); | ||
828 | } | ||
829 | |||
830 | /** | ||
831 | * Sets the indicated property to a theme name. | ||
832 | * @param key The property key. | ||
833 | * @param val String giving the name of the theme. | ||
834 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
835 | * @ingroup Ecore_Config_Set_Group | ||
836 | */ | ||
837 | EAPI int | ||
838 | ecore_config_theme_set(const char *key, const char *val) | ||
839 | { | ||
840 | return ecore_config_typed_set(key, val, ECORE_CONFIG_THM); | ||
841 | } | ||
842 | |||
843 | /** | ||
844 | * Sets the theme preview group of an indicated property. | ||
845 | * @param key The property key. | ||
846 | * @param group The group name. | ||
847 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
848 | * @ingroup Ecore_Config_Set_Group | ||
849 | */ | ||
850 | EAPI int | ||
851 | ecore_config_theme_preview_group_set(const char *key, const char *group) | ||
852 | { | ||
853 | int ret; | ||
854 | Ecore_Config_Prop *e; | ||
855 | |||
856 | ret = ECORE_CONFIG_ERR_SUCC; | ||
857 | if (!(e = ecore_config_get(key))) | ||
858 | { /* prop doesn't exist yet */ | ||
859 | if ((ret = ecore_config_typed_add(key, "", ECORE_CONFIG_THM)) != ECORE_CONFIG_ERR_SUCC) /* try to add it */ | ||
860 | return ret; /* ...failed */ | ||
861 | if (!(e = ecore_config_get(key))) /* get handle */ | ||
862 | return ECORE_CONFIG_ERR_FAIL; | ||
863 | } | ||
864 | if (e->data) | ||
865 | free(e->data); | ||
866 | e->data = strdup(group); | ||
867 | |||
868 | return ret; | ||
869 | } | ||
870 | |||
871 | EAPI int | ||
872 | ecore_config_typed_default(const char *key, const void *val, int type) | ||
873 | { | ||
874 | int ret; | ||
875 | Ecore_Config_Prop *e; | ||
876 | |||
877 | ret = ECORE_CONFIG_ERR_SUCC; | ||
878 | |||
879 | if (!(e = ecore_config_get(key))) | ||
880 | { /* prop doesn't exist yet */ | ||
881 | if ((ret = ecore_config_typed_add(key, val, type)) != ECORE_CONFIG_ERR_SUCC) /* try to add it */ | ||
882 | return ret; /* ...failed */ | ||
883 | if (!(e = ecore_config_get(key))) /* get handle */ | ||
884 | return ECORE_CONFIG_ERR_FAIL; | ||
885 | e->flags = e->flags & ~ECORE_CONFIG_FLAG_MODIFIED; | ||
886 | } | ||
887 | else if (!(e->flags & ECORE_CONFIG_FLAG_MODIFIED) && !(e->flags & ECORE_CONFIG_FLAG_SYSTEM)) | ||
888 | { | ||
889 | ecore_config_typed_set(key, val, type); | ||
890 | if (!(e = ecore_config_get(key))) /* get handle */ | ||
891 | return ECORE_CONFIG_ERR_FAIL; | ||
892 | e->flags = e->flags & ~ECORE_CONFIG_FLAG_MODIFIED; | ||
893 | } | ||
894 | return ret; | ||
895 | } | ||
896 | |||
897 | /** | ||
898 | * @defgroup Ecore_Config_Default_Group Ecore Config Defaults | ||
899 | * | ||
900 | * Functions that are used to set the default values of properties. | ||
901 | */ | ||
902 | |||
903 | /** | ||
904 | * Sets the indicated property if it has not already been set or loaded. | ||
905 | * @param key The property key. | ||
906 | * @param val Default value of the key. | ||
907 | * @param lo Lowest valid value for the key. | ||
908 | * @param hi Highest valid value for the key. | ||
909 | * @param step Used by integer and float values. | ||
910 | * @return @c ECORE_CONFIG_ERR_SUCC if there are no errors. | ||
911 | * @note The @p lo, @p hi and @p step parameters are only used when storing | ||
912 | * integer and float properties. | ||
913 | * @ingroup Ecore_Config_Default_Group | ||
914 | */ | ||
915 | EAPI int | ||
916 | ecore_config_default(const char *key, const char *val, float lo, float hi, float step) | ||
917 | { | ||
918 | int ret, type; | ||
919 | Ecore_Config_Prop *e; | ||
920 | |||
921 | type = ecore_config_type_guess(key, val); | ||
922 | ret = ecore_config_typed_default(key, val, type); | ||
923 | e = ecore_config_get(key); | ||
924 | if (e) | ||
925 | { | ||
926 | if (type == ECORE_CONFIG_INT) | ||
927 | { | ||
928 | e->step = step; | ||
929 | e->flags |= ECORE_CONFIG_FLAG_BOUNDS; | ||
930 | e->lo = lo; | ||
931 | e->hi = hi; | ||
932 | ecore_config_bound(e); | ||
933 | } | ||
934 | else if (type == ECORE_CONFIG_FLT) | ||
935 | { | ||
936 | e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION); | ||
937 | e->flags |= ECORE_CONFIG_FLAG_BOUNDS; | ||
938 | e->lo = (int)(lo * ECORE_CONFIG_FLOAT_PRECISION); | ||
939 | e->hi = (int)(hi * ECORE_CONFIG_FLOAT_PRECISION); | ||
940 | ecore_config_bound(e); | ||
941 | } | ||
942 | } | ||
943 | |||
944 | return ret; | ||
945 | } | ||
946 | |||
947 | /** | ||
948 | * Sets the indicated property to the given boolean if the property has not yet | ||
949 | * been set. | ||
950 | * @param key The property key. | ||
951 | * @param val Boolean Integer to set the value to. | ||
952 | * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems. | ||
953 | * @ingroup Ecore_Config_Default_Group | ||
954 | */ | ||
955 | EAPI int | ||
956 | ecore_config_boolean_default(const char *key, int val) | ||
957 | { | ||
958 | val = val ? 1 : 0; | ||
959 | return ecore_config_typed_default(key, &val, ECORE_CONFIG_BLN); | ||
960 | } | ||
961 | |||
962 | /** | ||
963 | * Sets the indicated property to the given integer if the property has not yet | ||
964 | * been set. | ||
965 | * @param key The property key. | ||
966 | * @param val Integer to set the value to. | ||
967 | * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems. | ||
968 | * @ingroup Ecore_Config_Default_Group | ||
969 | */ | ||
970 | EAPI int | ||
971 | ecore_config_int_default(const char *key, int val) | ||
972 | { | ||
973 | return ecore_config_typed_default(key, &val, ECORE_CONFIG_INT); | ||
974 | } | ||
975 | |||
976 | /** | ||
977 | * Sets the indicated property to the given integer if the property has not yet | ||
978 | * been set. | ||
979 | * | ||
980 | * The bounds and step values are set regardless. | ||
981 | * | ||
982 | * @param key The property key. | ||
983 | * @param val Integer to set the property to. | ||
984 | * @param low Lowest valid integer value for the property. | ||
985 | * @param high Highest valid integer value for the property. | ||
986 | * @param step Increment value for the property. | ||
987 | * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems. | ||
988 | * @ingroup Ecore_Config_Default_Group | ||
989 | */ | ||
990 | EAPI int | ||
991 | ecore_config_int_default_bound(const char *key, int val, int low, int high, | ||
992 | int step) | ||
993 | { | ||
994 | Ecore_Config_Prop *e; | ||
995 | int ret; | ||
996 | |||
997 | ret = ecore_config_typed_default(key, &val, ECORE_CONFIG_INT); | ||
998 | e = ecore_config_get(key); | ||
999 | if (e) | ||
1000 | { | ||
1001 | e->step = step; | ||
1002 | e->flags |= ECORE_CONFIG_FLAG_BOUNDS; | ||
1003 | e->lo = low; | ||
1004 | e->hi = high; | ||
1005 | ecore_config_bound(e); | ||
1006 | } | ||
1007 | |||
1008 | return ret; | ||
1009 | } | ||
1010 | |||
1011 | /** | ||
1012 | * Sets the indicated property to the given string if the property has not yet | ||
1013 | * been set. | ||
1014 | * @param key The property key. | ||
1015 | * @param val String to set the property to. | ||
1016 | * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems. | ||
1017 | * @ingroup Ecore_Config_Default_Group | ||
1018 | */ | ||
1019 | EAPI int | ||
1020 | ecore_config_string_default(const char *key, const char *val) | ||
1021 | { | ||
1022 | return ecore_config_typed_default(key, val, ECORE_CONFIG_STR); | ||
1023 | } | ||
1024 | |||
1025 | /** | ||
1026 | * Sets the indicated property to the given float if the property has not yet | ||
1027 | * been set. | ||
1028 | * @param key The property key. | ||
1029 | * @param val Float to set the property to. | ||
1030 | * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems. | ||
1031 | * @ingroup Ecore_Config_Default_Group | ||
1032 | */ | ||
1033 | EAPI int | ||
1034 | ecore_config_float_default(const char *key, float val) | ||
1035 | { | ||
1036 | return ecore_config_typed_default(key, &val, ECORE_CONFIG_FLT); | ||
1037 | } | ||
1038 | |||
1039 | /** | ||
1040 | * Sets the indicated property to the given float if the property has not yet | ||
1041 | * been set. | ||
1042 | * | ||
1043 | * The bounds and step values are set regardless. | ||
1044 | * | ||
1045 | * @param key The property key. | ||
1046 | * @param val Float to set the property to. | ||
1047 | * @param low Lowest valid integer value for the property. | ||
1048 | * @param high Highest valid float value for the property. | ||
1049 | * @param step Increment value for the property. | ||
1050 | * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems. | ||
1051 | * @ingroup Ecore_Config_Default_Group | ||
1052 | */ | ||
1053 | EAPI int | ||
1054 | ecore_config_float_default_bound(const char *key, float val, float low, | ||
1055 | float high, float step) | ||
1056 | { | ||
1057 | Ecore_Config_Prop *e; | ||
1058 | int ret; | ||
1059 | |||
1060 | ret = ecore_config_typed_default(key, &val, ECORE_CONFIG_FLT); | ||
1061 | e = ecore_config_get(key); | ||
1062 | if (e) | ||
1063 | { | ||
1064 | e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION); | ||
1065 | e->flags |= ECORE_CONFIG_FLAG_BOUNDS; | ||
1066 | e->lo = (int)(low * ECORE_CONFIG_FLOAT_PRECISION); | ||
1067 | e->hi = (int)(high * ECORE_CONFIG_FLOAT_PRECISION); | ||
1068 | ecore_config_bound(e); | ||
1069 | } | ||
1070 | |||
1071 | return ret; | ||
1072 | } | ||
1073 | |||
1074 | /** | ||
1075 | * Sets the indicated property to a color value if the property has not yet | ||
1076 | * been set. | ||
1077 | * @param key The property key. | ||
1078 | * @param a integer 0..255 | ||
1079 | * @param r integer 0..255 | ||
1080 | * @param g integer 0..255 | ||
1081 | * @param b integer 0..255 | ||
1082 | * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems. | ||
1083 | * @ingroup Ecore_Config_Default_Group | ||
1084 | */ | ||
1085 | EAPI int | ||
1086 | ecore_config_argb_default(const char *key, int a, int r, int g, int b) | ||
1087 | { | ||
1088 | long v = 0; | ||
1089 | return ecore_config_typed_default(key, __ecore_argb_to_long(a,r,g,b, &v), ECORE_CONFIG_RGB); | ||
1090 | } | ||
1091 | |||
1092 | /** | ||
1093 | * Sets the indicated property to a color value if the property has not yet | ||
1094 | * been set. | ||
1095 | * @param key The property key. | ||
1096 | * @param argb ARGB data as long | ||
1097 | * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems. | ||
1098 | * @ingroup Ecore_Config_Default_Group | ||
1099 | */ | ||
1100 | EAPI int | ||
1101 | ecore_config_argbint_default(const char *key, long argb) | ||
1102 | { | ||
1103 | return ecore_config_typed_default(key, &argb, ECORE_CONFIG_RGB); | ||
1104 | } | ||
1105 | |||
1106 | /** | ||
1107 | * Sets the indicated property to a color value if the property has not yet | ||
1108 | * been set. | ||
1109 | * @param key The property key. | ||
1110 | * @param val Color value in ARGB format. | ||
1111 | * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems. | ||
1112 | * @ingroup Ecore_Config_Default_Group | ||
1113 | */ | ||
1114 | EAPI int | ||
1115 | ecore_config_argbstr_default(const char *key, const char *val) | ||
1116 | { | ||
1117 | long v = 0; | ||
1118 | return ecore_config_typed_default(key, __ecore_argbstr_to_long(val, &v), ECORE_CONFIG_RGB); | ||
1119 | } | ||
1120 | |||
1121 | /** | ||
1122 | * Sets the indicated property to a theme name if the property has not yet | ||
1123 | * been set. | ||
1124 | * @param key The property key. | ||
1125 | * @param val String giving the name of the theme. | ||
1126 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
1127 | * @ingroup Ecore_Config_Default_Group | ||
1128 | */ | ||
1129 | EAPI int | ||
1130 | ecore_config_theme_default(const char *key, const char *val) | ||
1131 | { | ||
1132 | return ecore_config_typed_default(key, val, ECORE_CONFIG_THM); | ||
1133 | } | ||
1134 | |||
1135 | /** | ||
1136 | * @defgroup Ecore_Config_Struct_Group Ecore Config Structures | ||
1137 | * | ||
1138 | * Functions that are used to create structures of properties. | ||
1139 | */ | ||
1140 | |||
1141 | /** | ||
1142 | * Sets the indicated property to a structure if the property has not yet | ||
1143 | * been set. | ||
1144 | * @param key The property key. | ||
1145 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
1146 | * @ingroup Ecore_Config_Struct_Group | ||
1147 | */ | ||
1148 | EAPI int | ||
1149 | ecore_config_struct_create(const char *key) | ||
1150 | { | ||
1151 | WRN("you are using ecore_config structures. These are very young"); | ||
1152 | WRN(" and not complete - you have been warned"); | ||
1153 | |||
1154 | return ecore_config_typed_default(key, NULL, ECORE_CONFIG_SCT); | ||
1155 | } | ||
1156 | |||
1157 | static int | ||
1158 | _ecore_config_struct_append(Ecore_Config_Prop *sct, Ecore_Config_Prop *add) | ||
1159 | { | ||
1160 | Eina_List *l; | ||
1161 | |||
1162 | if (!sct || !add || sct->type != ECORE_CONFIG_SCT) | ||
1163 | return ECORE_CONFIG_ERR_IGNORED; | ||
1164 | |||
1165 | l = sct->data; | ||
1166 | sct->data = eina_list_append(l, add); | ||
1167 | add->parent = sct; | ||
1168 | |||
1169 | return ECORE_CONFIG_ERR_SUCC; | ||
1170 | } | ||
1171 | |||
1172 | static int | ||
1173 | _ecore_config_struct_typed_add(const char *key, const char *name, const void *val, | ||
1174 | int type) | ||
1175 | { | ||
1176 | char *subkey; | ||
1177 | int ret; | ||
1178 | |||
1179 | subkey = malloc((strlen(key) + strlen(name) + 2) * sizeof(char)); | ||
1180 | strcpy(subkey, key); | ||
1181 | strcat(subkey, "."); | ||
1182 | strcat(subkey, name); | ||
1183 | |||
1184 | ecore_config_typed_default(subkey, val, type); | ||
1185 | ret = _ecore_config_struct_append(ecore_config_get(key), | ||
1186 | ecore_config_get(subkey)); | ||
1187 | free(subkey); | ||
1188 | return ret; | ||
1189 | } | ||
1190 | |||
1191 | /** | ||
1192 | * Add an int property to the named structure. The property is set if it has not | ||
1193 | * yet been set. | ||
1194 | * @param key The key of the structure to add to. | ||
1195 | * @param name The name of the item to add - this will be appended to the key | ||
1196 | * @param val the int to default to | ||
1197 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
1198 | * @ingroup Ecore_Config_Struct_Group | ||
1199 | */ | ||
1200 | EAPI int | ||
1201 | ecore_config_struct_int_add(const char *key, const char *name, int val) | ||
1202 | { | ||
1203 | return _ecore_config_struct_typed_add(key, name, &val, ECORE_CONFIG_INT); | ||
1204 | } | ||
1205 | |||
1206 | /** | ||
1207 | * Add a float property to the named structure. The property is set if it has | ||
1208 | * not yet been set. | ||
1209 | * @param key The key of the structure to add to. | ||
1210 | * @param name The name of the item to add - this will be appended to the key | ||
1211 | * @param val The float to default to | ||
1212 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
1213 | * @ingroup Ecore_Config_Struct_Group | ||
1214 | */ | ||
1215 | EAPI int | ||
1216 | ecore_config_struct_float_add(const char *key, const char *name, float val) | ||
1217 | { | ||
1218 | return _ecore_config_struct_typed_add(key, name, &val, ECORE_CONFIG_FLT); | ||
1219 | } | ||
1220 | |||
1221 | /** | ||
1222 | * Add a string property to the named structure. The property is set if it has | ||
1223 | * not yet been set. | ||
1224 | * @param key The key of the structure to add to. | ||
1225 | * @param name The name of the item to add - this will be appended to the key | ||
1226 | * @param val The string to default to | ||
1227 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
1228 | * @ingroup Ecore_Config_Struct_Group | ||
1229 | */ | ||
1230 | EAPI int | ||
1231 | ecore_config_struct_string_add(const char *key, const char *name, const char* val) | ||
1232 | { | ||
1233 | return _ecore_config_struct_typed_add(key, name, val, ECORE_CONFIG_STR); | ||
1234 | } | ||
1235 | |||
1236 | /** | ||
1237 | * Add an argb property to the named structure. The property is set if it has | ||
1238 | * not yet been set. | ||
1239 | * @param key The key of the structure to add to. | ||
1240 | * @param name The name of the item to add - this will be appended to the key | ||
1241 | * @param a The alpha to default to | ||
1242 | * @param r The red to default to | ||
1243 | * @param g The green to default to | ||
1244 | * @param b The blue to default to | ||
1245 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
1246 | * @ingroup Ecore_Config_Struct_Group | ||
1247 | */ | ||
1248 | EAPI int | ||
1249 | ecore_config_struct_argb_add(const char *key, const char *name, int a, int r, | ||
1250 | int g, int b) | ||
1251 | { | ||
1252 | long argb; | ||
1253 | |||
1254 | __ecore_argb_to_long(a, r, g, b, &argb); | ||
1255 | return _ecore_config_struct_typed_add(key, name, &argb, ECORE_CONFIG_RGB); | ||
1256 | } | ||
1257 | |||
1258 | /** | ||
1259 | * Add a theme property to the named structure. The property is set if it has | ||
1260 | * not yet been set. | ||
1261 | * @param key The key of the structure to add to. | ||
1262 | * @param name The name of the item to add - this will be appended to the key | ||
1263 | * @param val The theme name to default to | ||
1264 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
1265 | * @ingroup Ecore_Config_Struct_Group | ||
1266 | */ | ||
1267 | EAPI int | ||
1268 | ecore_config_struct_theme_add(const char *key, const char *name, const char* val) | ||
1269 | { | ||
1270 | return _ecore_config_struct_typed_add(key, name, val, ECORE_CONFIG_THM); | ||
1271 | } | ||
1272 | |||
1273 | /** | ||
1274 | * Add a boolean property to the named structure. The property is set if it has | ||
1275 | * not yet been set. | ||
1276 | * @param key The key of the structure to add to. | ||
1277 | * @param name The name of the item to add - this will be appended to the key | ||
1278 | * @param val The boolean to default to | ||
1279 | * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. | ||
1280 | * @ingroup Ecore_Config_Struct_Group | ||
1281 | */ | ||
1282 | EAPI int | ||
1283 | ecore_config_struct_boolean_add(const char *key, const char *name, int val) | ||
1284 | { | ||
1285 | val = val ? 1 : 0; | ||
1286 | return _ecore_config_struct_typed_add(key, name, &val, ECORE_CONFIG_BLN); | ||
1287 | } | ||
1288 | |||
1289 | /** | ||
1290 | * Get the contents of a defined structure property and load it into the passed | ||
1291 | * C struct | ||
1292 | * @param key The name of the structure property to look up. | ||
1293 | * @param data The struct to write into. | ||
1294 | * @return @c ECORE_CONFIG_ERR_SUCC if the structure is written successfully. | ||
1295 | * @ingroup Ecore_Config_Struct_Group | ||
1296 | */ | ||
1297 | EAPI int | ||
1298 | ecore_config_struct_get(const char *key, void *data) | ||
1299 | { | ||
1300 | Ecore_Config_Prop *e, *f; | ||
1301 | Eina_List *l; | ||
1302 | unsigned char *ptr; | ||
1303 | long argb; | ||
1304 | |||
1305 | e = ecore_config_get(key); | ||
1306 | if (!e) | ||
1307 | return ECORE_CONFIG_ERR_NODATA; | ||
1308 | |||
1309 | l = e->data; | ||
1310 | ptr = data; | ||
1311 | while (l) | ||
1312 | { | ||
1313 | f = (Ecore_Config_Prop *) l->data; | ||
1314 | switch (f->type) | ||
1315 | { | ||
1316 | case ECORE_CONFIG_INT: | ||
1317 | *((int *) ptr) = _ecore_config_int_get(f); | ||
1318 | ptr += sizeof(int); | ||
1319 | break; | ||
1320 | case ECORE_CONFIG_BLN: | ||
1321 | *((int *) ptr) = _ecore_config_boolean_get(f); | ||
1322 | ptr += sizeof(int); | ||
1323 | break; | ||
1324 | case ECORE_CONFIG_FLT: | ||
1325 | *((float *) ptr) = _ecore_config_float_get(f); | ||
1326 | ptr += sizeof(float); | ||
1327 | break; | ||
1328 | case ECORE_CONFIG_STR: | ||
1329 | case ECORE_CONFIG_THM: | ||
1330 | *((char **) ptr) = _ecore_config_string_get(f); | ||
1331 | ptr += sizeof(char *); | ||
1332 | break; | ||
1333 | case ECORE_CONFIG_RGB: | ||
1334 | argb = _ecore_config_argbint_get(f); | ||
1335 | *((int *) ptr) = (argb >> 24) & 0xff; | ||
1336 | ptr += sizeof(int); | ||
1337 | *((int *) ptr) = (argb >> 16) & 0xff; | ||
1338 | ptr += sizeof(int); | ||
1339 | *((int *) ptr) = (argb >> 8) & 0xff; | ||
1340 | ptr += sizeof(int); | ||
1341 | *((int *) ptr) = argb & 0xff; | ||
1342 | ptr += sizeof(int); | ||
1343 | break; | ||
1344 | default: | ||
1345 | WRN("ARGH - STRUCT coding not implemented yet"); | ||
1346 | } | ||
1347 | l = eina_list_next(l); | ||
1348 | } | ||
1349 | return ECORE_CONFIG_ERR_SUCC; | ||
1350 | } | ||
1351 | |||
1352 | /** | ||
1353 | * @defgroup Ecore_Config_Listeners_Group Ecore Config Listeners | ||
1354 | * | ||
1355 | * Functions that set and unset property listener callbacks. | ||
1356 | */ | ||
1357 | |||
1358 | /** | ||
1359 | * Adds a callback function to the list of functions called when a property | ||
1360 | * changes. | ||
1361 | * @param name Name of the callback. | ||
1362 | * @param key The key of the property to listen to. | ||
1363 | * @param listener Listener callback function. | ||
1364 | * @param tag Tag to pass to @p listener when it is called. | ||
1365 | * @param data Data to pass to @p listener when it is called. | ||
1366 | * @return @c ECORE_CONFIG_ERR_SUCC if successful in setting up the callback. | ||
1367 | * @ingroup Ecore_Config_Listeners_Group | ||
1368 | */ | ||
1369 | EAPI int | ||
1370 | ecore_config_listen(const char *name, const char *key, | ||
1371 | Ecore_Config_Listener listener, int tag, void *data) | ||
1372 | { | ||
1373 | Ecore_Config_Prop *e; | ||
1374 | Ecore_Config_Listener_List *l; | ||
1375 | |||
1376 | if (!key) | ||
1377 | return ECORE_CONFIG_ERR_NODATA; | ||
1378 | |||
1379 | if (!(e = ecore_config_get(key))) | ||
1380 | { | ||
1381 | int ret = ecore_config_add(key, ""); | ||
1382 | |||
1383 | if (ret != ECORE_CONFIG_ERR_SUCC) | ||
1384 | { | ||
1385 | ERR("ecore_config_listen: ecore_config_add(\"%s\") failed: %d", | ||
1386 | key, ret); | ||
1387 | return ret; | ||
1388 | } | ||
1389 | if (!(e = ecore_config_get(key))) | ||
1390 | { | ||
1391 | ERR("ecore_config_listen: list of properties corrupted!?"); | ||
1392 | return ECORE_CONFIG_ERR_FAIL; | ||
1393 | } | ||
1394 | } | ||
1395 | |||
1396 | for (l = e->listeners; l; l = l->next) | ||
1397 | if (!strcmp(l->name, name) || (l->listener == listener)) | ||
1398 | { | ||
1399 | ERR("ecore_config_listen: %s is already listening for changes of %s...", | ||
1400 | name, key); | ||
1401 | return ECORE_CONFIG_ERR_IGNORED; | ||
1402 | } | ||
1403 | |||
1404 | if (!(l = malloc(sizeof(Ecore_Config_Listener_List)))) | ||
1405 | return ECORE_CONFIG_ERR_OOM; | ||
1406 | |||
1407 | ERR("registering listener \"%s\" for \"%s\" (%d)...", name, key, e->type); | ||
1408 | |||
1409 | memset(l, 0, sizeof(Ecore_Config_Listener_List)); | ||
1410 | |||
1411 | l->listener = listener; | ||
1412 | l->name = name; | ||
1413 | l->data = data; | ||
1414 | l->tag = tag; | ||
1415 | l->next = e->listeners; | ||
1416 | e->listeners = l; | ||
1417 | |||
1418 | if (e->type != ECORE_CONFIG_NIL) /* call right on creation if prop exists and has val */ | ||
1419 | listener(key, e->type, tag, data); | ||
1420 | |||
1421 | return ECORE_CONFIG_ERR_SUCC; | ||
1422 | } | ||
1423 | |||
1424 | /** | ||
1425 | * Removes a listener callback. | ||
1426 | * @param name Name of the callback to remove. | ||
1427 | * @param key The property key the callback is listening to. | ||
1428 | * @param listener The callback function to remove. | ||
1429 | * @return @c ECORE_CONFIG_ERR_SUCC if successful in removing the callback. | ||
1430 | * If no callback matches the given parameters, then | ||
1431 | * @c ECORE_CONFIG_ERR_NOTFOUND is returned. If @c NULL is passed | ||
1432 | * for the key pointer, @c ECORE_CONFIG_ERR_NODATA is returned. | ||
1433 | * @ingroup Ecore_Config_Listeners_Group | ||
1434 | */ | ||
1435 | EAPI int | ||
1436 | ecore_config_deaf(const char *name, const char *key, | ||
1437 | Ecore_Config_Listener listener) | ||
1438 | { | ||
1439 | Ecore_Config_Prop *e; | ||
1440 | Ecore_Config_Listener_List *l, *p; | ||
1441 | int ret; | ||
1442 | |||
1443 | ret = ECORE_CONFIG_ERR_NOTFOUND; | ||
1444 | |||
1445 | if (!key) | ||
1446 | return ECORE_CONFIG_ERR_NODATA; | ||
1447 | |||
1448 | if (!(e = ecore_config_get(key))) | ||
1449 | return ECORE_CONFIG_ERR_NOTFOUND; | ||
1450 | |||
1451 | for (p = NULL, l = e->listeners; l; p = l) | ||
1452 | { | ||
1453 | Ecore_Config_Listener_List *nl; | ||
1454 | |||
1455 | nl = l->next; | ||
1456 | if ((name && !strcmp(l->name, name)) || (l->listener == listener)) | ||
1457 | { | ||
1458 | ret = ECORE_CONFIG_ERR_SUCC; | ||
1459 | if (!p) | ||
1460 | e->listeners = e->listeners->next; | ||
1461 | else | ||
1462 | p->next = l->next; | ||
1463 | memset(l, 0, sizeof(Ecore_Config_Listener)); | ||
1464 | free(l); | ||
1465 | } | ||
1466 | l = nl; | ||
1467 | } | ||
1468 | |||
1469 | return ret; | ||
1470 | } | ||
1471 | |||
1472 | /** | ||
1473 | * Locates the first configuration bundle on the given server. | ||
1474 | * @param srv The configuration server. | ||
1475 | * @return Pointer to the first configuration bundle. | ||
1476 | */ | ||
1477 | EAPI Ecore_Config_Bundle * | ||
1478 | ecore_config_bundle_1st_get(Ecore_Config_Server * srv) | ||
1479 | { /* anchor: global, but read-only */ | ||
1480 | return srv->bundles; | ||
1481 | } | ||
1482 | |||
1483 | /** | ||
1484 | * Locates the configuration bundle after the given one. | ||
1485 | * @param ns The configuration bundle. | ||
1486 | * @return The next configuration bundle. | ||
1487 | */ | ||
1488 | EAPI Ecore_Config_Bundle * | ||
1489 | ecore_config_bundle_next_get(Ecore_Config_Bundle * ns) | ||
1490 | { | ||
1491 | return ns ? ns->next : NULL; | ||
1492 | } | ||
1493 | |||
1494 | /** | ||
1495 | * Locates a configuration bundle on a configuration server based on its serial | ||
1496 | * number. | ||
1497 | * @param srv The configuration server. | ||
1498 | * @param serial Serial number. | ||
1499 | * @return The configuration bundle with the given serial number. | ||
1500 | */ | ||
1501 | EAPI Ecore_Config_Bundle * | ||
1502 | ecore_config_bundle_by_serial_get(Ecore_Config_Server * srv, long serial) | ||
1503 | { | ||
1504 | Ecore_Config_Bundle *eb; | ||
1505 | |||
1506 | eb = srv->bundles; | ||
1507 | |||
1508 | if (serial < 0) | ||
1509 | return NULL; | ||
1510 | else if (serial == 0) | ||
1511 | { | ||
1512 | Ecore_Config_Bundle *r = eb; | ||
1513 | |||
1514 | return r; | ||
1515 | } | ||
1516 | |||
1517 | while (eb) | ||
1518 | { | ||
1519 | if (eb->serial == serial) | ||
1520 | return eb; | ||
1521 | eb = eb->next; | ||
1522 | } | ||
1523 | return NULL; | ||
1524 | } | ||
1525 | |||
1526 | /** | ||
1527 | * Gets the Ecore_Config_Bundle with the given identifier from the given | ||
1528 | * server. | ||
1529 | * @param srv The configuration server. | ||
1530 | * @param label The bundle's identifier string. | ||
1531 | * @return The bundle with the given identifier string, or @c NULL if it | ||
1532 | * could not be found. | ||
1533 | */ | ||
1534 | EAPI Ecore_Config_Bundle * | ||
1535 | ecore_config_bundle_by_label_get(Ecore_Config_Server * srv, const char *label) | ||
1536 | { | ||
1537 | Ecore_Config_Bundle *ns; | ||
1538 | |||
1539 | ns = srv->bundles; | ||
1540 | |||
1541 | while (ns) | ||
1542 | { | ||
1543 | if (ns->identifier && !strcmp(ns->identifier, label)) | ||
1544 | return ns; | ||
1545 | ns = ns->next; | ||
1546 | } | ||
1547 | return NULL; | ||
1548 | } | ||
1549 | |||
1550 | /** | ||
1551 | * Retrieves the bundle's serial number. | ||
1552 | * @param ns The configuration bundle. | ||
1553 | * @return The bundle's identifier string, or -1 if ns is @c NULL. | ||
1554 | */ | ||
1555 | EAPI long | ||
1556 | ecore_config_bundle_serial_get(Ecore_Config_Bundle * ns) | ||
1557 | { | ||
1558 | return ns ? ns->serial : -1; | ||
1559 | } | ||
1560 | |||
1561 | /** | ||
1562 | * Retrieves the bundle's identifier. | ||
1563 | * @param ns The configuration bundle. | ||
1564 | * @return The bundle's identifer string. | ||
1565 | */ | ||
1566 | EAPI char * | ||
1567 | ecore_config_bundle_label_get(Ecore_Config_Bundle * ns) | ||
1568 | { | ||
1569 | return ns ? ns->identifier : NULL; | ||
1570 | } | ||
1571 | |||
1572 | /** | ||
1573 | * Creates a new Ecore_Config_Bundle. | ||
1574 | * @param srv Config server. | ||
1575 | * @param identifier Identifier string for the new bundle. | ||
1576 | * @return A pointer to a new Ecore_Config_Bundle. @c NULL is returned if the | ||
1577 | * structure couldn't be allocated. | ||
1578 | */ | ||
1579 | EAPI Ecore_Config_Bundle * | ||
1580 | ecore_config_bundle_new(Ecore_Config_Server * srv, const char *identifier) | ||
1581 | { | ||
1582 | Ecore_Config_Bundle *t; | ||
1583 | static long ss; | ||
1584 | |||
1585 | ss = 0; /* bundle unique serial */ | ||
1586 | |||
1587 | if ((t = malloc(sizeof(Ecore_Config_Bundle)))) | ||
1588 | { | ||
1589 | memset(t, 0, sizeof(Ecore_Config_Bundle)); | ||
1590 | |||
1591 | t->identifier = (char *)identifier; | ||
1592 | t->serial = ++ss; | ||
1593 | t->owner = srv->name; | ||
1594 | t->next = srv->bundles; | ||
1595 | srv->bundles = t; | ||
1596 | } | ||
1597 | return t; | ||
1598 | } | ||
1599 | |||
1600 | static Ecore_Config_Server * | ||
1601 | do_init(const char *name) | ||
1602 | { | ||
1603 | return _ecore_config_ipc_init(name); | ||
1604 | } | ||
1605 | |||
1606 | static Ecore_Config_Server * | ||
1607 | ecore_config_init_local(const char *name) | ||
1608 | { | ||
1609 | char *p; | ||
1610 | char *buf; | ||
1611 | |||
1612 | if ((p = getenv("HOME"))) | ||
1613 | { /* debug-only ### FIXME */ | ||
1614 | if (!(buf = malloc(PATH_MAX * sizeof(char)))) | ||
1615 | return NULL; | ||
1616 | snprintf(buf, PATH_MAX, "%s/.ecore/%s/.global", p, name); | ||
1617 | unlink(buf); | ||
1618 | |||
1619 | free(buf); | ||
1620 | } | ||
1621 | |||
1622 | return do_init(name); | ||
1623 | } | ||
1624 | |||
1625 | static Ecore_Config_Server * | ||
1626 | ecore_config_init_global(const char *name) | ||
1627 | { | ||
1628 | char *p; | ||
1629 | int global; | ||
1630 | char *buf; | ||
1631 | |||
1632 | if ((p = getenv("HOME"))) | ||
1633 | { /* debug-only ### FIXME */ | ||
1634 | if (!(buf = malloc(PATH_MAX * sizeof(char)))) | ||
1635 | return NULL; | ||
1636 | snprintf(buf, PATH_MAX, "%s/.ecore/%s/.global", p, name); | ||
1637 | global = creat(buf, S_IRWXU); | ||
1638 | |||
1639 | if (global >= 0) | ||
1640 | close(global); | ||
1641 | |||
1642 | free(buf); | ||
1643 | } | ||
1644 | |||
1645 | return do_init(name); | ||
1646 | } | ||
1647 | |||
1648 | /** | ||
1649 | * @defgroup Ecore_Config_App_Lib_Group Ecore Config App Library Functions | ||
1650 | * | ||
1651 | * Functions that are used to start up and shutdown the Enlightened | ||
1652 | * Property Library when used directly by an application. | ||
1653 | */ | ||
1654 | |||
1655 | /** | ||
1656 | * Initializes the Enlightened Property Library. | ||
1657 | * | ||
1658 | * Either this function or @ref ecore_config_system_init must be run | ||
1659 | * before any other function in the Enlightened Property Library, even | ||
1660 | * if you have run @ref ecore_init . The name given is used to | ||
1661 | * determine the default configuration to load. | ||
1662 | * | ||
1663 | * @param name Application name | ||
1664 | * @return @c ECORE_CONFIG_ERR_SUCC if the library is successfully set up. | ||
1665 | * @c ECORE_CONFIG_ERR_FAIL otherwise. | ||
1666 | * @ingroup Ecore_Config_App_Lib_Group | ||
1667 | */ | ||
1668 | EAPI int | ||
1669 | ecore_config_init(const char *name) | ||
1670 | { | ||
1671 | char *path; | ||
1672 | Ecore_Config_Prop *list; | ||
1673 | _ecore_config_log_dom = eina_log_domain_register | ||
1674 | ("ecore_config", ECORE_CONFIG_DEFAULT_LOG_COLOR); | ||
1675 | if(_ecore_config_log_dom < 0) | ||
1676 | { | ||
1677 | EINA_LOG_ERR("Impossible to create a log domain for the Ecore config module."); | ||
1678 | return -1; | ||
1679 | } | ||
1680 | _ecore_config_system_init_no_load(); | ||
1681 | |||
1682 | __ecore_config_app_name = strdup(name); | ||
1683 | __ecore_config_server_local = ecore_config_init_local(name); | ||
1684 | if (!__ecore_config_server_local) | ||
1685 | return ECORE_CONFIG_ERR_FAIL; | ||
1686 | |||
1687 | list = __ecore_config_bundle_local->data; | ||
1688 | free( __ecore_config_bundle_local ); | ||
1689 | __ecore_config_bundle_local = | ||
1690 | ecore_config_bundle_new(__ecore_config_server_local, "config"); | ||
1691 | __ecore_config_bundle_local->data = list; | ||
1692 | |||
1693 | path = ecore_config_theme_default_path_get(); | ||
1694 | ecore_config_string_default("/e/themes/search_path", path); | ||
1695 | if (path) | ||
1696 | free(path); | ||
1697 | |||
1698 | list = ecore_config_get("/e/themes/search_path"); | ||
1699 | if (list) | ||
1700 | { | ||
1701 | list->flags |= ECORE_CONFIG_FLAG_SYSTEM; | ||
1702 | list->flags &= ~ECORE_CONFIG_FLAG_MODIFIED; | ||
1703 | } | ||
1704 | |||
1705 | return _ecore_config_system_load(); | ||
1706 | } | ||
1707 | |||
1708 | /** | ||
1709 | * Frees memory and shuts down the library for an application. | ||
1710 | * @return @c ECORE_CONFIG_ERR_IGNORED . | ||
1711 | * @ingroup Ecore_Config_App_Lib_Group | ||
1712 | */ | ||
1713 | EAPI int | ||
1714 | ecore_config_shutdown(void) | ||
1715 | { | ||
1716 | return ecore_config_system_shutdown(); | ||
1717 | } | ||
1718 | |||
1719 | /** | ||
1720 | * @defgroup Ecore_Config_Lib_Lib_Group Ecore Config Library Functions | ||
1721 | * | ||
1722 | * Functions that are used to start up and shutdown the Enlightened | ||
1723 | * Property Library when used directly by an application. | ||
1724 | */ | ||
1725 | |||
1726 | /** | ||
1727 | * Initializes the Enlightened Property Library. | ||
1728 | * | ||
1729 | * This function is meant to be run from other programming libraries. | ||
1730 | * It should not be called from applications. | ||
1731 | * | ||
1732 | * This function (or @ref ecore_config_init ) | ||
1733 | * must be run before any other function in the | ||
1734 | * Enlightened Property Library, even if you have run @ref ecore_init . | ||
1735 | * | ||
1736 | * @return @c ECORE_CONFIG_ERR_SUCC if the library is successfully set up. | ||
1737 | * @c ECORE_CONFIG_ERR_FAIL otherwise. | ||
1738 | * @ingroup Ecore_Config_Lib_Lib_Group | ||
1739 | */ | ||
1740 | EAPI int | ||
1741 | ecore_config_system_init(void) | ||
1742 | { | ||
1743 | _ecore_config_system_init_no_load(); | ||
1744 | return _ecore_config_system_load(); | ||
1745 | } | ||
1746 | |||
1747 | static int | ||
1748 | _ecore_config_system_init_no_load(void) | ||
1749 | { | ||
1750 | char *p; | ||
1751 | |||
1752 | __ecore_config_system_init++; | ||
1753 | if (__ecore_config_system_init > 1) | ||
1754 | return ECORE_CONFIG_ERR_IGNORED; | ||
1755 | |||
1756 | DEBUG = -1; | ||
1757 | if ((p = getenv("ECORE_CONFIG_DEBUG")) && p[0] != 0) | ||
1758 | { | ||
1759 | DEBUG = atoi(p); | ||
1760 | } | ||
1761 | |||
1762 | __ecore_config_server_global = | ||
1763 | ecore_config_init_global(ECORE_CONFIG_GLOBAL_ID); | ||
1764 | if (!__ecore_config_server_global) | ||
1765 | return ECORE_CONFIG_ERR_FAIL; | ||
1766 | |||
1767 | __ecore_config_bundle_local = | ||
1768 | ecore_config_bundle_new(__ecore_config_server_global, "system"); | ||
1769 | |||
1770 | /* set up a simple default path */ | ||
1771 | ecore_config_string_default("/e/themes/search_path", PACKAGE_DATA_DIR "../ewl/themes"); | ||
1772 | |||
1773 | return ECORE_CONFIG_ERR_SUCC; | ||
1774 | } | ||
1775 | |||
1776 | |||
1777 | static int | ||
1778 | _ecore_config_system_load(void) | ||
1779 | { | ||
1780 | char *buf, *p; | ||
1781 | Ecore_Config_Prop *sys; | ||
1782 | |||
1783 | if (__ecore_config_system_init != 1) | ||
1784 | return ECORE_CONFIG_ERR_FAIL; | ||
1785 | |||
1786 | if ((p = getenv("HOME"))) | ||
1787 | { /* debug-only ### FIXME */ | ||
1788 | if ((buf = malloc(PATH_MAX * sizeof(char)))) | ||
1789 | { | ||
1790 | snprintf(buf, PATH_MAX, "%s/.e/config.eet", p); | ||
1791 | if (ecore_config_file_load(buf) != 0) { | ||
1792 | /* even if this file (system.eet) doesn't exist we can | ||
1793 | * continue without it as it isn't striclty necessary. | ||
1794 | */ | ||
1795 | ecore_config_file_load(PACKAGE_DATA_DIR "/system.eet"); | ||
1796 | } | ||
1797 | sys = __ecore_config_bundle_local->data; | ||
1798 | while (sys) | ||
1799 | { | ||
1800 | /* unmark it modified - modification will mean it has been overridden */ | ||
1801 | sys->flags &= ~ECORE_CONFIG_FLAG_MODIFIED; | ||
1802 | /* mark as system so that examine can hide them */ | ||
1803 | sys->flags |= ECORE_CONFIG_FLAG_SYSTEM; | ||
1804 | sys = sys->next; | ||
1805 | } | ||
1806 | } | ||
1807 | free(buf); | ||
1808 | } | ||
1809 | |||
1810 | return ECORE_CONFIG_ERR_SUCC; | ||
1811 | } | ||
1812 | |||
1813 | |||
1814 | /** | ||
1815 | * Frees memory and shuts down the library for other programming libraries. | ||
1816 | * @return @c ECORE_CONFIG_ERR_IGNORED | ||
1817 | * @ingroup Ecore_Config_Lib_Lib_Group | ||
1818 | */ | ||
1819 | EAPI int | ||
1820 | ecore_config_system_shutdown(void) | ||
1821 | { | ||
1822 | int ret; | ||
1823 | |||
1824 | __ecore_config_system_init--; | ||
1825 | if (__ecore_config_system_init > 0) | ||
1826 | return ECORE_CONFIG_ERR_IGNORED; | ||
1827 | |||
1828 | ret = _ecore_config_ipc_exit(); | ||
1829 | if (__ecore_config_app_name) | ||
1830 | free(__ecore_config_app_name); | ||
1831 | while(__ecore_config_bundle_local->data) | ||
1832 | ecore_config_dst(__ecore_config_bundle_local->data); | ||
1833 | free(__ecore_config_bundle_local); | ||
1834 | free(__ecore_config_server_local); | ||
1835 | free(__ecore_config_server_global); | ||
1836 | eina_log_domain_unregister(_ecore_config_log_dom); | ||
1837 | _ecore_config_log_dom = -1; | ||
1838 | return ret; | ||
1839 | } | ||
1840 | |||
1841 | static inline void * | ||
1842 | __ecore_argb_to_long(int a, int r, int g, int b, long *v) | ||
1843 | { | ||
1844 | *v = ((a << 24) & 0xff000000 ) | ||
1845 | | ((r << 16) & 0xff0000 ) | ||
1846 | | ((g << 8) & 0xff00 ) | ||
1847 | | ( b & 0xff ); | ||
1848 | |||
1849 | return v; | ||
1850 | } | ||
1851 | |||
1852 | static inline void * | ||
1853 | __ecore_argbstr_to_long(const char *argb, long *v) | ||
1854 | { | ||
1855 | char *l = NULL; | ||
1856 | |||
1857 | // convert hexadecimal string #..., #0x..., 0x..., ... to long | ||
1858 | if(*argb == '#') | ||
1859 | argb++; | ||
1860 | *v = (long)strtoul( argb, &l, 16); | ||
1861 | |||
1862 | if(*l) | ||
1863 | { | ||
1864 | ERR("ecore_config_val: value \"%s\" not a valid hexadecimal RGB value?", argb); | ||
1865 | return NULL; | ||
1866 | } | ||
1867 | |||
1868 | return v; | ||
1869 | } | ||
1870 | |||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_db.c b/libraries/ecore/src/lib/ecore_config/ecore_config_db.c new file mode 100644 index 0000000..6238958 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_db.c | |||
@@ -0,0 +1,296 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <stdlib.h> | ||
6 | #include <stdio.h> | ||
7 | #include <string.h> | ||
8 | #include <limits.h> | ||
9 | |||
10 | #include <sys/param.h> | ||
11 | #include <sys/types.h> | ||
12 | #include <sys/stat.h> | ||
13 | #include <unistd.h> | ||
14 | #include <locale.h> | ||
15 | |||
16 | #include <Eet.h> | ||
17 | |||
18 | #include "Ecore_Config.h" | ||
19 | #include "ecore_config_private.h" | ||
20 | #include "ecore_config_util.h" | ||
21 | |||
22 | struct _Ecore_Config_DB_File | ||
23 | { | ||
24 | Eet_File *ef; | ||
25 | }; | ||
26 | |||
27 | Ecore_Config_DB_File * | ||
28 | _ecore_config_db_open_read(const char *file) | ||
29 | { | ||
30 | Eet_File *ef; | ||
31 | Ecore_Config_DB_File *db; | ||
32 | |||
33 | eet_init(); | ||
34 | db = malloc(sizeof(Ecore_Config_DB_File)); | ||
35 | if (!db) return NULL; | ||
36 | ef = eet_open((char*)file, EET_FILE_MODE_READ); | ||
37 | if (!ef) | ||
38 | { | ||
39 | free(db); | ||
40 | return NULL; | ||
41 | } | ||
42 | db->ef = ef; | ||
43 | return db; | ||
44 | } | ||
45 | |||
46 | Ecore_Config_DB_File * | ||
47 | _ecore_config_db_open_write(const char *file) | ||
48 | { | ||
49 | Eet_File *ef; | ||
50 | Ecore_Config_DB_File *db; | ||
51 | |||
52 | eet_init(); | ||
53 | db = malloc(sizeof(Ecore_Config_DB_File)); | ||
54 | if (!db) return NULL; | ||
55 | ef = eet_open((char*)file, EET_FILE_MODE_WRITE); | ||
56 | if (!ef) | ||
57 | { | ||
58 | free(db); | ||
59 | return NULL; | ||
60 | } | ||
61 | db->ef = ef; | ||
62 | return db; | ||
63 | } | ||
64 | |||
65 | void | ||
66 | _ecore_config_db_close(Ecore_Config_DB_File *db) | ||
67 | { | ||
68 | eet_close(db->ef); | ||
69 | free(db); | ||
70 | eet_shutdown(); | ||
71 | } | ||
72 | |||
73 | char ** | ||
74 | _ecore_config_db_keys_get(Ecore_Config_DB_File *db, int *num_ret) | ||
75 | { | ||
76 | char **keys; | ||
77 | int key_count; | ||
78 | int i; | ||
79 | |||
80 | keys = eet_list(db->ef, (char*)"*", &key_count); | ||
81 | if (!keys) | ||
82 | { | ||
83 | *num_ret = 0; | ||
84 | return NULL; | ||
85 | } | ||
86 | /* make keys freeable - this is safe to do */ | ||
87 | for (i = 0; i < key_count; i++) keys[i] = strdup(keys[i]); | ||
88 | *num_ret = key_count; | ||
89 | return keys; | ||
90 | } | ||
91 | |||
92 | Ecore_Config_Type | ||
93 | _ecore_config_db_key_type_get(Ecore_Config_DB_File *db, const char *key) | ||
94 | { | ||
95 | char *data; | ||
96 | int size; | ||
97 | |||
98 | data = eet_read(db->ef, (char*)key, &size); | ||
99 | if (data) | ||
100 | { | ||
101 | if (size <= 2) | ||
102 | { | ||
103 | free(data); | ||
104 | return ECORE_CONFIG_NIL; | ||
105 | } | ||
106 | if (data[size - 1] != 0) | ||
107 | { | ||
108 | free(data); | ||
109 | return ECORE_CONFIG_NIL; | ||
110 | } | ||
111 | return (Ecore_Config_Type) data[0]; | ||
112 | } | ||
113 | return ECORE_CONFIG_NIL; | ||
114 | } | ||
115 | |||
116 | int | ||
117 | _ecore_config_db_read(Ecore_Config_DB_File *db, const char *key) | ||
118 | { | ||
119 | char *data, *value; | ||
120 | int size; | ||
121 | Ecore_Config_Type type; | ||
122 | |||
123 | data = eet_read(db->ef, (char*)key, &size); | ||
124 | if (data) | ||
125 | { | ||
126 | int l; | ||
127 | char *prev_locale; | ||
128 | |||
129 | if (size <= 2) | ||
130 | { | ||
131 | free(data); | ||
132 | return 0; | ||
133 | } | ||
134 | if (data[size - 1] != 0) | ||
135 | { | ||
136 | free(data); | ||
137 | return 0; | ||
138 | } | ||
139 | /* "type" NIL 1242 NIL */ | ||
140 | l = strlen(data); | ||
141 | if (l >= (size - 1)) | ||
142 | { | ||
143 | free(data); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | type = data[0]; | ||
148 | value = data + l + 1; | ||
149 | |||
150 | switch (type) | ||
151 | { | ||
152 | case ECORE_CONFIG_INT: | ||
153 | case ECORE_CONFIG_BLN: | ||
154 | { | ||
155 | int tmp; | ||
156 | prev_locale = setlocale(LC_NUMERIC, "C"); | ||
157 | tmp = atoi(value); | ||
158 | if (prev_locale) setlocale(LC_NUMERIC, prev_locale); | ||
159 | |||
160 | ecore_config_typed_set(key, (void *)&tmp, type); | ||
161 | break; | ||
162 | } | ||
163 | case ECORE_CONFIG_FLT: | ||
164 | { | ||
165 | float tmp; | ||
166 | prev_locale = setlocale(LC_NUMERIC, "C"); | ||
167 | tmp = atof(value); | ||
168 | if (prev_locale) setlocale(LC_NUMERIC, prev_locale); | ||
169 | |||
170 | ecore_config_typed_set(key, (void *)&tmp, type); | ||
171 | break; | ||
172 | } | ||
173 | case ECORE_CONFIG_RGB: | ||
174 | ecore_config_argbstr_set(key, value); | ||
175 | break; | ||
176 | case ECORE_CONFIG_STR: | ||
177 | case ECORE_CONFIG_THM: | ||
178 | ecore_config_typed_set(key, (void *)value, type); | ||
179 | break; | ||
180 | case ECORE_CONFIG_SCT: | ||
181 | INF("loading struct %s", key); | ||
182 | break; | ||
183 | default: | ||
184 | WRN("Type %d not handled", type); | ||
185 | } | ||
186 | free(data); | ||
187 | return 1; | ||
188 | } | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | void * | ||
194 | _ecore_config_db_key_data_get(Ecore_Config_DB_File *db, const char *key, int *size_ret) | ||
195 | { | ||
196 | char *data; | ||
197 | int size; | ||
198 | |||
199 | data = eet_read(db->ef, (char*)key, &size); | ||
200 | if (data) | ||
201 | { | ||
202 | int l; | ||
203 | char *dat; | ||
204 | |||
205 | if (size <= 2) | ||
206 | { | ||
207 | free(data); | ||
208 | return NULL; | ||
209 | } | ||
210 | if (data[size - 1] != 0) | ||
211 | { | ||
212 | free(data); | ||
213 | return NULL; | ||
214 | } | ||
215 | * "type" NIL data_goes_here NIL * | ||
216 | l = strlen(data); | ||
217 | if (l >= (size - 1)) | ||
218 | { | ||
219 | free(data); | ||
220 | return NULL; | ||
221 | } | ||
222 | dat = malloc(size - (l + 2)); | ||
223 | memcpy(dat, data + l + 1, size - (l + 2)); | ||
224 | free(data); | ||
225 | *size_ret = size - (l + 2); | ||
226 | return dat; | ||
227 | } | ||
228 | return NULL; | ||
229 | }*/ | ||
230 | |||
231 | void | ||
232 | _ecore_config_db_write(Ecore_Config_DB_File *db, Ecore_Config_Prop *e) | ||
233 | { | ||
234 | char *prev_locale= NULL; | ||
235 | char *val = NULL; | ||
236 | char *r = NULL; | ||
237 | int num; | ||
238 | |||
239 | prev_locale = setlocale(LC_NUMERIC, "C"); | ||
240 | |||
241 | switch (e->type) | ||
242 | { | ||
243 | case ECORE_CONFIG_INT: | ||
244 | esprintf(&val, "%i", _ecore_config_int_get(e)); | ||
245 | break; | ||
246 | case ECORE_CONFIG_BLN: | ||
247 | esprintf(&val, "%i", _ecore_config_boolean_get(e)); | ||
248 | break; | ||
249 | case ECORE_CONFIG_FLT: | ||
250 | esprintf(&val, "%16.16f", _ecore_config_float_get(e)); | ||
251 | break; | ||
252 | case ECORE_CONFIG_STR: | ||
253 | val = _ecore_config_string_get(e); | ||
254 | break; | ||
255 | case ECORE_CONFIG_THM: | ||
256 | val = _ecore_config_theme_get(e); | ||
257 | break; | ||
258 | case ECORE_CONFIG_RGB: | ||
259 | val = _ecore_config_argbstr_get(e); | ||
260 | break; | ||
261 | default: | ||
262 | WRN("Type %d not handled", e->type); | ||
263 | } | ||
264 | |||
265 | if (prev_locale) | ||
266 | { | ||
267 | setlocale(LC_NUMERIC, prev_locale); | ||
268 | } | ||
269 | |||
270 | if(val) | ||
271 | { | ||
272 | num = esprintf(&r, "%c%c%s%c", (char) e->type, 0, val, 0); | ||
273 | if(num) | ||
274 | eet_write(db->ef, e->key, r, num, 1); | ||
275 | free(r); | ||
276 | } | ||
277 | |||
278 | free(val); | ||
279 | } | ||
280 | /* | ||
281 | void | ||
282 | _ecore_config_db_key_data_set(Ecore_Config_DB_File *db, const char *key, void *data, int data_size) | ||
283 | { | ||
284 | char *buf; | ||
285 | int num; | ||
286 | |||
287 | num = 1 + 1 + data_size + 1; | ||
288 | buf = malloc(num); | ||
289 | if (!buf) return; | ||
290 | buf[0] = (char) ECORE_CONFIG_BIN; | ||
291 | buf[1] = 0; | ||
292 | memcpy(buf + 2, data, data_size); | ||
293 | buf[num - 1] = 0; | ||
294 | eet_write(db->ef, (char*)key, buf, num, 1); | ||
295 | free(buf); | ||
296 | }*/ | ||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_extra.c b/libraries/ecore/src/lib/ecore_config/ecore_config_extra.c new file mode 100644 index 0000000..a134952 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_extra.c | |||
@@ -0,0 +1,803 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <string.h> | ||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | |||
9 | #include <sys/types.h> | ||
10 | #include <sys/stat.h> | ||
11 | |||
12 | #include "Ecore_Config.h" | ||
13 | #include "Ecore.h" | ||
14 | #include "ecore_config_private.h" | ||
15 | typedef struct __Ecore_Config_Arg_Callback _Ecore_Config_Arg_Callback; | ||
16 | struct __Ecore_Config_Arg_Callback | ||
17 | { | ||
18 | char short_opt; | ||
19 | char *long_opt; | ||
20 | char *description; | ||
21 | void *data; | ||
22 | void (*func)(char *val, void *data); | ||
23 | Ecore_Config_Type type; | ||
24 | _Ecore_Config_Arg_Callback *next; | ||
25 | }; | ||
26 | |||
27 | char *__ecore_config_app_description; | ||
28 | _Ecore_Config_Arg_Callback *_ecore_config_arg_callbacks; | ||
29 | |||
30 | /* shorthand prop setup code to make client apps a little smaller ;) */ | ||
31 | |||
32 | /** | ||
33 | * Creates a new property, if it does not already exist, and sets its | ||
34 | * attributes to those given. | ||
35 | * | ||
36 | * The type of the property is guessed from the key and the value | ||
37 | * given. | ||
38 | * | ||
39 | * @param key The property key. | ||
40 | * @param val Pointer to default value of key. | ||
41 | * @param short_opt Short option used to set the property from command | ||
42 | * line. | ||
43 | * @param long_opt Long option used to set the property from command line. | ||
44 | * @param desc String description of property. | ||
45 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
46 | * @ingroup Ecore_Config_Create_Group | ||
47 | */ | ||
48 | int | ||
49 | ecore_config_create(const char *key, void *val, char short_opt, char *long_opt, | ||
50 | char *desc) | ||
51 | { | ||
52 | int type = ecore_config_type_guess(key, val); | ||
53 | |||
54 | return ecore_config_typed_create(key, val, type, short_opt, long_opt, desc); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Creates a new property, if it does not already exist, and sets its | ||
59 | * attributes to those given. | ||
60 | * @param key The property key. | ||
61 | * @param val Pointer to default value of key. | ||
62 | * @param type Type of the property. | ||
63 | * @param short_opt Short option used to set the property from | ||
64 | * command line. | ||
65 | * @param long_opt Long option used to set the property from command line. | ||
66 | * @param desc String description of property. | ||
67 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
68 | * @ingroup Ecore_Config_Create_Group | ||
69 | */ | ||
70 | int | ||
71 | ecore_config_typed_create(const char *key, void *val, int type, char short_opt, | ||
72 | char *long_opt, char *desc) | ||
73 | { | ||
74 | int ret; | ||
75 | |||
76 | if ((ret = | ||
77 | ecore_config_typed_default(key, val, type)) != ECORE_CONFIG_ERR_SUCC) | ||
78 | return ret; | ||
79 | if ((ret = | ||
80 | ecore_config_short_opt_set(key, short_opt)) != ECORE_CONFIG_ERR_SUCC) | ||
81 | return ret; | ||
82 | if ((ret = | ||
83 | ecore_config_long_opt_set(key, long_opt)) != ECORE_CONFIG_ERR_SUCC) | ||
84 | return ret; | ||
85 | ret = ecore_config_describe(key, desc); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | /** | ||
90 | * Creates a new boolean property, if it does not already exist, and sets its | ||
91 | * attributes to those given. | ||
92 | * @param key The property key. | ||
93 | * @param val Default boolean value of key. | ||
94 | * @param short_opt Short option used to set the property from command | ||
95 | * line. | ||
96 | * @param long_opt Long option used to set the property from command line. | ||
97 | * @param desc String description of property. | ||
98 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
99 | * @ingroup Ecore_Config_Create_Group | ||
100 | */ | ||
101 | int | ||
102 | ecore_config_boolean_create(const char *key, int val, char short_opt, | ||
103 | char *long_opt, char *desc) | ||
104 | { | ||
105 | return | ||
106 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_BLN, short_opt, long_opt, | ||
107 | desc); | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * Creates a new integer property, if it does not already exist, and sets its | ||
112 | * attributes to those given. | ||
113 | * @param key The property key. | ||
114 | * @param val Default integer value of key. | ||
115 | * @param short_opt Short option used to set the property from command | ||
116 | * line. | ||
117 | * @param long_opt Long option used to set the property from command line. | ||
118 | * @param desc String description of property. | ||
119 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
120 | * @ingroup Ecore_Config_Create_Group | ||
121 | */ | ||
122 | int | ||
123 | ecore_config_int_create(const char *key, int val, char short_opt, | ||
124 | char *long_opt, char *desc) | ||
125 | { | ||
126 | return | ||
127 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_INT, short_opt, long_opt, | ||
128 | desc); | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Creates a new integer property, if it does not already exist, and sets its | ||
133 | * attributes to those given. | ||
134 | * @param key The property key. | ||
135 | * @param val Default integer value of key. | ||
136 | * @param low Lowest valid integer value for the property. | ||
137 | * @param high Highest valid integer value for the property. | ||
138 | * @param step Increment value for the property. | ||
139 | * @param short_opt Short option used to set the property from command | ||
140 | * line. | ||
141 | * @param long_opt Long option used to set the property from command line. | ||
142 | * @param desc String description of property. | ||
143 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
144 | * @ingroup Ecore_Config_Create_Group | ||
145 | */ | ||
146 | int | ||
147 | ecore_config_int_create_bound(const char *key, int val, int low, int high, | ||
148 | int step, char short_opt, char *long_opt, | ||
149 | char *desc) | ||
150 | { | ||
151 | Ecore_Config_Prop *e; | ||
152 | int ret; | ||
153 | |||
154 | ret = | ||
155 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_INT, short_opt, long_opt, | ||
156 | desc); | ||
157 | if (ret != ECORE_CONFIG_ERR_SUCC) | ||
158 | return ret; | ||
159 | e = ecore_config_get(key); | ||
160 | if (e) | ||
161 | { | ||
162 | e->step = step; | ||
163 | e->flags |= ECORE_CONFIG_FLAG_BOUNDS; | ||
164 | e->lo = low; | ||
165 | e->hi = high; | ||
166 | ecore_config_bound(e); | ||
167 | } | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * Creates a new string property, if it does not already exist, and sets its | ||
173 | * attributes to those given. | ||
174 | * @param key The property key. | ||
175 | * @param val Default value of key. | ||
176 | * @param short_opt Short option used to set the property from command | ||
177 | * line. | ||
178 | * @param long_opt Long option used to set the property from command line. | ||
179 | * @param desc String description of property. | ||
180 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
181 | * @ingroup Ecore_Config_Create_Group | ||
182 | */ | ||
183 | int | ||
184 | ecore_config_string_create(const char *key, char *val, char short_opt, | ||
185 | char *long_opt, char *desc) | ||
186 | { | ||
187 | return | ||
188 | ecore_config_typed_create(key, (void *)val, ECORE_CONFIG_STR, short_opt, long_opt, | ||
189 | desc); | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * Creates a new float property, if it does not already exist, and sets its | ||
194 | * attributes to those given. | ||
195 | * @param key The property key. | ||
196 | * @param val Default float value of key. | ||
197 | * @param short_opt Short option used to set the property from command | ||
198 | * line. | ||
199 | * @param long_opt Long option used to set the property from command line. | ||
200 | * @param desc String description of property. | ||
201 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
202 | * @ingroup Ecore_Config_Create_Group | ||
203 | */ | ||
204 | int | ||
205 | ecore_config_float_create(const char *key, float val, char short_opt, | ||
206 | char *long_opt, char *desc) | ||
207 | { | ||
208 | return | ||
209 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_FLT, short_opt, long_opt, | ||
210 | desc); | ||
211 | } | ||
212 | |||
213 | /** | ||
214 | * Creates a new float property, if it does not already exist, and sets its | ||
215 | * attributes to those given. | ||
216 | * @param key The property key. | ||
217 | * @param val Default float value of key. | ||
218 | * @param low Lowest valid float value for the property. | ||
219 | * @param high Highest valid float value for the property. | ||
220 | * @param step Increment value for the property. | ||
221 | * @param short_opt Short option used to set the property from command | ||
222 | * line. | ||
223 | * @param long_opt Long option used to set the property from command line. | ||
224 | * @param desc String description of property. | ||
225 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
226 | * @ingroup Ecore_Config_Create_Group | ||
227 | */ | ||
228 | int | ||
229 | ecore_config_float_create_bound(const char *key, float val, float low, | ||
230 | float high, float step, char short_opt, | ||
231 | char *long_opt, char *desc) | ||
232 | { | ||
233 | Ecore_Config_Prop *e; | ||
234 | int ret; | ||
235 | |||
236 | ret = | ||
237 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_FLT, short_opt, long_opt, | ||
238 | desc); | ||
239 | e = ecore_config_get(key); | ||
240 | if (e) | ||
241 | { | ||
242 | e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION); | ||
243 | e->flags |= ECORE_CONFIG_FLAG_BOUNDS; | ||
244 | e->lo = (int)(low * ECORE_CONFIG_FLOAT_PRECISION); | ||
245 | e->hi = (int)(high * ECORE_CONFIG_FLOAT_PRECISION); | ||
246 | ecore_config_bound(e); | ||
247 | } | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * Creates a new color property, if it does not already exist, and sets its | ||
253 | * attributes to those given. | ||
254 | * @param key The property key. | ||
255 | * @param val Default color value of key, as a hexadecimal string. | ||
256 | * @param short_opt Short option used to set the property from command | ||
257 | * line. | ||
258 | * @param long_opt Long option used to set the property from command line. | ||
259 | * @param desc String description of property. | ||
260 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
261 | * @ingroup Ecore_Config_Create_Group | ||
262 | */ | ||
263 | int | ||
264 | ecore_config_argb_create(const char *key, char *val, char short_opt, | ||
265 | char *long_opt, char *desc) | ||
266 | { | ||
267 | return | ||
268 | ecore_config_typed_create(key, (void *)val, ECORE_CONFIG_RGB, short_opt, long_opt, | ||
269 | desc); | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * Creates a new theme property, if it does not already exist, and sets its | ||
274 | * attributes to those given. | ||
275 | * @param key The property key. | ||
276 | * @param val Default theme name for the property. | ||
277 | * @param short_opt Short option used to set the property from command | ||
278 | * line. | ||
279 | * @param long_opt Long option used to set the property from command line. | ||
280 | * @param desc String description of property. | ||
281 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
282 | * @ingroup Ecore_Config_Create_Group | ||
283 | */ | ||
284 | int | ||
285 | ecore_config_theme_create(const char *key, char *val, char short_opt, | ||
286 | char *long_opt, char *desc) | ||
287 | { | ||
288 | return | ||
289 | ecore_config_typed_create(key, (void *)val, ECORE_CONFIG_THM, short_opt, long_opt, | ||
290 | desc); | ||
291 | } | ||
292 | |||
293 | /* this should only be built if evas is present */ | ||
294 | |||
295 | /** | ||
296 | * Calls evas_font_path_append on @p evas for each of the font names stored | ||
297 | * in the property "/e/font/path". | ||
298 | * @param evas Evas object to append the font names to. | ||
299 | * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA | ||
300 | * is returned if the property has not been set. | ||
301 | */ | ||
302 | int | ||
303 | ecore_config_evas_font_path_apply(Evas * evas) | ||
304 | { | ||
305 | char *font_path, *font_path_tmp, *ptr, *end; | ||
306 | |||
307 | font_path = ecore_config_string_get("/e/font/path"); | ||
308 | |||
309 | if (!font_path) | ||
310 | return ECORE_CONFIG_ERR_NODATA; | ||
311 | ptr = font_path; | ||
312 | end = font_path + strlen(font_path); | ||
313 | font_path_tmp = font_path; | ||
314 | while (ptr && ptr < end) | ||
315 | { | ||
316 | while (*ptr != '|' && ptr < end) | ||
317 | ptr++; | ||
318 | if (ptr < end) | ||
319 | *ptr = '\0'; | ||
320 | |||
321 | evas_font_path_append(evas, font_path_tmp); | ||
322 | ptr++; | ||
323 | font_path_tmp = ptr; | ||
324 | } | ||
325 | |||
326 | free(font_path); | ||
327 | |||
328 | return ECORE_CONFIG_ERR_SUCC; | ||
329 | } | ||
330 | |||
331 | /** | ||
332 | * Retrieves the default theme search path. | ||
333 | * | ||
334 | * @return The default theme search path. | ||
335 | */ | ||
336 | char * | ||
337 | ecore_config_theme_default_path_get(void) | ||
338 | { | ||
339 | char *path, *home; | ||
340 | int len; | ||
341 | |||
342 | home = getenv("HOME"); | ||
343 | len = strlen(PACKAGE_DATA_DIR "/../") + strlen(__ecore_config_app_name) + | ||
344 | strlen("/themes/") + 1; | ||
345 | if (home) | ||
346 | len += strlen(home) + strlen("/.e/apps/") + | ||
347 | strlen(__ecore_config_app_name) + | ||
348 | strlen("/themes/|"); /* no \0, as that is above */ | ||
349 | |||
350 | if (!(path = malloc(len))) | ||
351 | return NULL; | ||
352 | |||
353 | *path = '\0'; | ||
354 | if (home) | ||
355 | { | ||
356 | strcat(path, home); | ||
357 | strcat(path, "/.e/apps/"); | ||
358 | strcat(path, __ecore_config_app_name); | ||
359 | strcat(path, "/themes/|"); | ||
360 | } | ||
361 | strcat(path, PACKAGE_DATA_DIR "/../"); | ||
362 | strcat(path, __ecore_config_app_name); | ||
363 | strcat(path, "/themes/"); | ||
364 | |||
365 | return path; | ||
366 | } | ||
367 | |||
368 | /** | ||
369 | * Retrieves the search path used to find themes. | ||
370 | * | ||
371 | * The search path is stored in the property "/e/themes/search_path". If | ||
372 | * the property has not been set, the default path used is | ||
373 | * "/usr/local/share/<app_name>/themes|~/.e/apps/<app_name>/themes". | ||
374 | * See @ref ecore_config_theme_default_path_get for more information about | ||
375 | * the default path. | ||
376 | * | ||
377 | * @return The search path. @c NULL is returned if there is no memory left. | ||
378 | */ | ||
379 | char * | ||
380 | ecore_config_theme_search_path_get(void) | ||
381 | { | ||
382 | char *search_path; | ||
383 | search_path = ecore_config_string_get("/e/themes/search_path"); | ||
384 | |||
385 | /* this should no longer be the case, as it is defaulted in init */ | ||
386 | if (!search_path) | ||
387 | { | ||
388 | search_path = ecore_config_theme_default_path_get(); | ||
389 | if (search_path) | ||
390 | { | ||
391 | ecore_config_string_default("/e/themes/search_path", search_path); | ||
392 | free(search_path); | ||
393 | } | ||
394 | } | ||
395 | return search_path; | ||
396 | } | ||
397 | |||
398 | /** | ||
399 | * Adds the given path to the search path used to find themes. | ||
400 | * | ||
401 | * If the search path is successfully, the new search path will be saved | ||
402 | * into the property "/e/themes/search_path". Therefore, this function | ||
403 | * should be called @b after @ref ecore_config_load to allow a user to | ||
404 | * override the default search path. | ||
405 | * | ||
406 | * @param path The given | ||
407 | * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL | ||
408 | * will be returned if @p path already exists in the search path. | ||
409 | * @c ECORE_CONFIG_ERR_FAIL is returned if @p path is @c NULL. | ||
410 | */ | ||
411 | int | ||
412 | ecore_config_theme_search_path_append(const char *path) | ||
413 | { | ||
414 | char *search_path, *loc, *new_search_path; | ||
415 | int len, search_len; | ||
416 | Ecore_Config_Prop *prop; | ||
417 | |||
418 | if (!path) | ||
419 | return ECORE_CONFIG_ERR_NODATA; | ||
420 | search_path = ecore_config_theme_search_path_get(); | ||
421 | |||
422 | loc = strstr(search_path, path); | ||
423 | len = strlen(path); | ||
424 | search_len = strlen(search_path); | ||
425 | |||
426 | if (!loc || (loc != search_path && *(loc - 1) != '|') || | ||
427 | (loc != (search_path + search_len - len) && *(loc + len - 1) != '|')) | ||
428 | { | ||
429 | new_search_path = malloc(search_len + len + 2); /* 2 = \0 + | */ | ||
430 | strcpy(new_search_path, search_path); | ||
431 | strncat(new_search_path, "|", 1); | ||
432 | strncat(new_search_path, path, len); | ||
433 | |||
434 | ecore_config_string_set("/e/themes/search_path", new_search_path); | ||
435 | prop = ecore_config_get("/e/themes/search_path"); | ||
436 | if (prop) | ||
437 | prop->flags &= ~ECORE_CONFIG_FLAG_MODIFIED; | ||
438 | |||
439 | free(new_search_path); | ||
440 | |||
441 | return ECORE_CONFIG_ERR_SUCC; | ||
442 | } | ||
443 | return ECORE_CONFIG_ERR_FAIL; | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * Retrieve a theme file's full path. | ||
448 | * | ||
449 | * The search path for theme files is given by @ref | ||
450 | * ecore_config_theme_search_path_get . | ||
451 | * | ||
452 | * @param name The name of the theme. | ||
453 | * @return A full path to the theme on success. @c NULL will be returned | ||
454 | * if @p name is @c NULL or no theme matching the given name could | ||
455 | * be found. | ||
456 | */ | ||
457 | char * | ||
458 | ecore_config_theme_with_path_from_name_get(char *name) | ||
459 | { | ||
460 | char *search_path, *search_path_tmp, *ptr, *end, *file; | ||
461 | struct stat st; | ||
462 | |||
463 | if (!name) | ||
464 | return NULL; /* no theme specified (nor a default) */ | ||
465 | |||
466 | search_path = ecore_config_theme_search_path_get(); | ||
467 | ptr = search_path; | ||
468 | end = search_path + strlen(search_path); | ||
469 | search_path_tmp = search_path; | ||
470 | while (ptr && ptr < end) | ||
471 | { | ||
472 | while (*ptr != '|' && ptr < end) | ||
473 | ptr++; | ||
474 | if (ptr < end) | ||
475 | *ptr = '\0'; | ||
476 | |||
477 | file = malloc(strlen(search_path_tmp) + strlen(name) + 6); | ||
478 | /* 6 = / + .edj + \0 */ | ||
479 | |||
480 | snprintf(file, strlen(search_path_tmp) + strlen(name) + 6, | ||
481 | "%s/%s.edj", search_path_tmp, name); | ||
482 | |||
483 | if (stat(file, &st) == 0) | ||
484 | { | ||
485 | free(search_path); | ||
486 | return file; | ||
487 | } | ||
488 | free(file); | ||
489 | ptr++; | ||
490 | search_path_tmp = ptr; | ||
491 | } | ||
492 | |||
493 | free(search_path); | ||
494 | |||
495 | return NULL; /* we could not find the theme with that name in search path */ | ||
496 | } | ||
497 | |||
498 | /** | ||
499 | * Retrieves the full path to the theme file of the theme stored in the | ||
500 | * given property. | ||
501 | * | ||
502 | * The search path for themes is given by @ref | ||
503 | * ecore_config_theme_search_path_get . | ||
504 | * | ||
505 | * @param key The given property. | ||
506 | * @return A full path to the theme on success, or @c NULL on failure. | ||
507 | * This function will fail if no key is specified or not theme | ||
508 | * matching that given by the property @p key could be found. | ||
509 | */ | ||
510 | char * | ||
511 | ecore_config_theme_with_path_get(const char *key) | ||
512 | { | ||
513 | return | ||
514 | ecore_config_theme_with_path_from_name_get(ecore_config_theme_get(key)); | ||
515 | } | ||
516 | |||
517 | static const char *_ecore_config_short_types[] = | ||
518 | { " ", "<int> ", "<flt> ", "<str> ", "<rgb> ", "<str> ", "<bool>" }; | ||
519 | |||
520 | /** | ||
521 | * Prints the property list of the local configuration bundle to output. | ||
522 | */ | ||
523 | void | ||
524 | ecore_config_args_display(void) | ||
525 | { | ||
526 | Ecore_Config_Prop *props; | ||
527 | _Ecore_Config_Arg_Callback *callbacks; | ||
528 | |||
529 | if (__ecore_config_app_description) | ||
530 | ERR("%s\n\n", __ecore_config_app_description); | ||
531 | ERR("Supported Options:"); | ||
532 | ERR(" -h, --help\t Print this text"); | ||
533 | if (!__ecore_config_bundle_local) | ||
534 | return; | ||
535 | props = __ecore_config_bundle_local->data; | ||
536 | while (props) | ||
537 | { | ||
538 | /* if it is a system prop, or cannot be set on command line hide it */ | ||
539 | if (props->flags & ECORE_CONFIG_FLAG_SYSTEM || (!props->short_opt && !props->long_opt)) | ||
540 | { | ||
541 | props = props->next; | ||
542 | continue; | ||
543 | } | ||
544 | INF(" %c%c%c --%s\t%s %s", props->short_opt ? '-' : ' ', | ||
545 | props->short_opt ? props->short_opt : ' ', | ||
546 | props->short_opt ? ',' : ' ', | ||
547 | props->long_opt ? props->long_opt : props->key, | ||
548 | _ecore_config_short_types[props->type], | ||
549 | props->description ? props->description : | ||
550 | "(no description available)"); | ||
551 | |||
552 | props = props->next; | ||
553 | } | ||
554 | callbacks = _ecore_config_arg_callbacks; | ||
555 | while (callbacks) | ||
556 | { | ||
557 | INF(" %c%c%c --%s\t%s %s", callbacks->short_opt ? '-' : ' ', | ||
558 | callbacks->short_opt ? callbacks->short_opt : ' ', | ||
559 | callbacks->short_opt ? ',' : ' ', | ||
560 | callbacks->long_opt ? callbacks->long_opt : "", | ||
561 | _ecore_config_short_types[callbacks->type], | ||
562 | callbacks->description ? callbacks->description : | ||
563 | "(no description available)"); | ||
564 | |||
565 | callbacks = callbacks->next; | ||
566 | } | ||
567 | } | ||
568 | |||
569 | static int | ||
570 | ecore_config_parse_set(Ecore_Config_Prop * prop, char *arg, char *opt, | ||
571 | char opt2) | ||
572 | { | ||
573 | if (!arg) | ||
574 | { | ||
575 | if (opt) | ||
576 | ERR("Missing expected argument for option --%s", opt); | ||
577 | else | ||
578 | ERR("Missing expected argument for option -%c", opt2); | ||
579 | return ECORE_CONFIG_PARSE_EXIT; | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | ecore_config_set(prop->key, arg); | ||
584 | prop->flags |= ECORE_CONFIG_FLAG_CMDLN; | ||
585 | } | ||
586 | return ECORE_CONFIG_PARSE_CONTINUE; | ||
587 | } | ||
588 | |||
589 | static void | ||
590 | ecore_config_args_callback_add(char short_opt, char *long_opt, char *desc, | ||
591 | void (*func)(char *val, void *data), | ||
592 | void *data, Ecore_Config_Type type) { | ||
593 | _Ecore_Config_Arg_Callback *new_cb; | ||
594 | |||
595 | new_cb = malloc(sizeof(_Ecore_Config_Arg_Callback)); | ||
596 | new_cb->short_opt = short_opt; | ||
597 | if (long_opt) | ||
598 | new_cb->long_opt = strdup(long_opt); | ||
599 | if (desc) | ||
600 | new_cb->description = strdup(desc); | ||
601 | new_cb->data = data; | ||
602 | new_cb->func = func; | ||
603 | new_cb->type = type; | ||
604 | |||
605 | new_cb->next = _ecore_config_arg_callbacks; | ||
606 | _ecore_config_arg_callbacks = new_cb; | ||
607 | } | ||
608 | |||
609 | void | ||
610 | ecore_config_args_callback_str_add(char short_opt, char *long_opt, char *desc, | ||
611 | void (*func)(char *val, void *data), | ||
612 | void *data) { | ||
613 | ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, ECORE_CONFIG_STR); | ||
614 | } | ||
615 | |||
616 | void | ||
617 | ecore_config_args_callback_noarg_add(char short_opt, char *long_opt, char *desc, | ||
618 | void (*func)(char *val, void *data), | ||
619 | void *data) { | ||
620 | ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, ECORE_CONFIG_NIL); | ||
621 | } | ||
622 | |||
623 | /** | ||
624 | * Parse the arguments set by @ref ecore_app_args_set and set properties | ||
625 | * accordingly. | ||
626 | * | ||
627 | * @return @c ECORE_CONFIG_PARSE_CONTINUE if successful. | ||
628 | * @c ECORE_CONFIG_PARSE_EXIT is returned if an unrecognised option | ||
629 | * is found. @c ECORE_CONFIG_PARSE_HELP is returned if help was | ||
630 | * displayed. | ||
631 | */ | ||
632 | int | ||
633 | ecore_config_args_parse(void) | ||
634 | { | ||
635 | int argc; | ||
636 | char **argv; | ||
637 | int nextarg, next_short_opt, found, ret; | ||
638 | char *arg; | ||
639 | char *long_opt, short_opt; | ||
640 | Ecore_Config_Prop *prop; | ||
641 | _Ecore_Config_Arg_Callback *callback; | ||
642 | |||
643 | ecore_app_args_get(&argc, &argv); | ||
644 | nextarg = 1; | ||
645 | while (nextarg < argc) | ||
646 | { | ||
647 | arg = argv[nextarg]; | ||
648 | |||
649 | if (*arg != '-') | ||
650 | { | ||
651 | ERR("Unexpected attribute \"%s\"", arg); | ||
652 | nextarg++; | ||
653 | continue; | ||
654 | } | ||
655 | |||
656 | next_short_opt = 1; | ||
657 | short_opt = *(arg + next_short_opt); | ||
658 | |||
659 | if (short_opt == '-') | ||
660 | { | ||
661 | long_opt = arg + 2; | ||
662 | |||
663 | if (!strcmp(long_opt, "help")) | ||
664 | { | ||
665 | ecore_config_args_display(); | ||
666 | return ECORE_CONFIG_PARSE_HELP; | ||
667 | } | ||
668 | |||
669 | found = 0; | ||
670 | prop = __ecore_config_bundle_local->data; | ||
671 | while (prop) | ||
672 | { | ||
673 | if ((prop->long_opt && !strcmp(long_opt, prop->long_opt)) | ||
674 | || !strcmp(long_opt, prop->key)) | ||
675 | { | ||
676 | found = 1; | ||
677 | if ((ret = | ||
678 | ecore_config_parse_set(prop, argv[++nextarg], | ||
679 | long_opt, | ||
680 | '\0')) != | ||
681 | ECORE_CONFIG_PARSE_CONTINUE) | ||
682 | return ret; | ||
683 | break; | ||
684 | } | ||
685 | prop = prop->next; | ||
686 | } | ||
687 | if (!found) | ||
688 | { | ||
689 | callback = _ecore_config_arg_callbacks; | ||
690 | while (callback) | ||
691 | { | ||
692 | if ((callback->long_opt && | ||
693 | !strcmp(long_opt, callback->long_opt))) | ||
694 | { | ||
695 | found = 1; | ||
696 | if (callback->type == ECORE_CONFIG_NIL) | ||
697 | { | ||
698 | callback->func(NULL, callback->data); | ||
699 | } | ||
700 | else | ||
701 | { | ||
702 | if (!argv[++nextarg]) | ||
703 | { | ||
704 | ERR("Missing expected argument for option --%s", long_opt); | ||
705 | return ECORE_CONFIG_PARSE_EXIT; | ||
706 | } | ||
707 | callback->func(argv[nextarg], callback->data); | ||
708 | } | ||
709 | break; | ||
710 | } | ||
711 | callback = callback->next; | ||
712 | } | ||
713 | } | ||
714 | if (!found) | ||
715 | { | ||
716 | ERR("Unrecognised option \"%s\"", long_opt); | ||
717 | ERR("Try using -h or --help for more information.\n"); | ||
718 | return ECORE_CONFIG_PARSE_EXIT; | ||
719 | } | ||
720 | } | ||
721 | else | ||
722 | { | ||
723 | while (short_opt) | ||
724 | { | ||
725 | if (short_opt == 'h') | ||
726 | { | ||
727 | ecore_config_args_display(); | ||
728 | return ECORE_CONFIG_PARSE_HELP; | ||
729 | } | ||
730 | else | ||
731 | { | ||
732 | found = 0; | ||
733 | prop = __ecore_config_bundle_local->data; | ||
734 | while (prop) | ||
735 | { | ||
736 | if (short_opt == prop->short_opt) | ||
737 | { | ||
738 | found = 1; | ||
739 | if ((ret = | ||
740 | ecore_config_parse_set(prop, | ||
741 | argv[++nextarg], | ||
742 | NULL, | ||
743 | short_opt)) != | ||
744 | ECORE_CONFIG_PARSE_CONTINUE) | ||
745 | return ret; | ||
746 | break; | ||
747 | } | ||
748 | prop = prop->next; | ||
749 | } | ||
750 | |||
751 | if (!found) | ||
752 | { | ||
753 | callback = _ecore_config_arg_callbacks; | ||
754 | while (callback) | ||
755 | { | ||
756 | if (short_opt == callback->short_opt) | ||
757 | { | ||
758 | found = 1; | ||
759 | if (callback->type == ECORE_CONFIG_NIL) | ||
760 | { | ||
761 | callback->func(NULL, callback->data); | ||
762 | } | ||
763 | else | ||
764 | { | ||
765 | if (!argv[++nextarg]) | ||
766 | { | ||
767 | ERR("Missing expected argument for option -%c", short_opt); | ||
768 | return ECORE_CONFIG_PARSE_EXIT; | ||
769 | } | ||
770 | callback->func(argv[nextarg], callback->data); | ||
771 | } | ||
772 | break; | ||
773 | } | ||
774 | callback = callback->next; | ||
775 | } | ||
776 | } | ||
777 | if (!found) | ||
778 | { | ||
779 | ERR("Unrecognised option '%c'", short_opt); | ||
780 | ERR("Try using -h or --help for more information.\n"); | ||
781 | return ECORE_CONFIG_PARSE_EXIT; | ||
782 | } | ||
783 | } | ||
784 | short_opt = *(arg + ++next_short_opt); | ||
785 | } | ||
786 | } | ||
787 | nextarg++; | ||
788 | } | ||
789 | |||
790 | return ECORE_CONFIG_PARSE_CONTINUE; | ||
791 | } | ||
792 | |||
793 | /** | ||
794 | * Sets the description string used by @ref ecore_config_args_display . | ||
795 | * @param description Description of application. | ||
796 | */ | ||
797 | void | ||
798 | ecore_config_app_describe(char *description) | ||
799 | { | ||
800 | if (__ecore_config_app_description) | ||
801 | free(__ecore_config_app_description); | ||
802 | __ecore_config_app_description = strdup(description); | ||
803 | } | ||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_ipc.h b/libraries/ecore/src/lib/ecore_config/ecore_config_ipc.h new file mode 100644 index 0000000..7b3dea1 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_ipc.h | |||
@@ -0,0 +1,50 @@ | |||
1 | #include <Ecore_Ipc.h> | ||
2 | #include "Ecore_Config.h" | ||
3 | |||
4 | typedef enum | ||
5 | { | ||
6 | IPC_NONE, | ||
7 | IPC_PROP_LIST, | ||
8 | IPC_PROP_DESC, | ||
9 | IPC_PROP_GET, | ||
10 | IPC_PROP_SET, /* end of the codes shared by evidence and econf */ | ||
11 | |||
12 | IPC_GLOBAL_PROP_LIST, | ||
13 | |||
14 | IPC_BUNDLE_LIST, | ||
15 | IPC_BUNDLE_NEW, | ||
16 | IPC_BUNDLE_LABEL_GET, | ||
17 | IPC_BUNDLE_LABEL_SET, | ||
18 | IPC_BUNDLE_LABEL_FIND, | ||
19 | |||
20 | IPC_LAST | ||
21 | } Ecore_Config_Ipc_Call; | ||
22 | |||
23 | Ecore_Config_Server *_ecore_config_ipc_init(const char *pipe_name); | ||
24 | int _ecore_config_ipc_exit(void); | ||
25 | |||
26 | Ecore_Config_Server *_ecore_config_server_convert(void *srv); | ||
27 | |||
28 | char *_ecore_config_ipc_prop_list(Ecore_Config_Server * srv, | ||
29 | const long serial); | ||
30 | char *_ecore_config_ipc_prop_desc(Ecore_Config_Server * srv, | ||
31 | const long serial, | ||
32 | const char *key); | ||
33 | char *_ecore_config_ipc_prop_get(Ecore_Config_Server * srv, | ||
34 | const long serial, | ||
35 | const char *key); | ||
36 | int _ecore_config_ipc_prop_set(Ecore_Config_Server * srv, | ||
37 | const long serial, | ||
38 | const char *key, | ||
39 | const char *val); | ||
40 | |||
41 | char *_ecore_config_ipc_bundle_list(Ecore_Config_Server * srv); | ||
42 | int _ecore_config_ipc_bundle_new(Ecore_Config_Server * srv, | ||
43 | const char *); | ||
44 | char *_ecore_config_ipc_bundle_label_get(Ecore_Config_Server * | ||
45 | srv, const long); | ||
46 | int _ecore_config_ipc_bundle_label_set(Ecore_Config_Server * | ||
47 | srv, const long, | ||
48 | const char *); | ||
49 | long _ecore_config_ipc_bundle_label_find(Ecore_Config_Server * | ||
50 | srv, const char *); | ||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c b/libraries/ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c new file mode 100644 index 0000000..b1622f3 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c | |||
@@ -0,0 +1,384 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | /* by Azundris, with thanks to Corey Donohoe <atmos@atmos.org> */ | ||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <string.h> | ||
9 | #include <errno.h> | ||
10 | #include <limits.h> | ||
11 | #include <sys/types.h> | ||
12 | #include <sys/stat.h> | ||
13 | #include <unistd.h> | ||
14 | #include <ctype.h> | ||
15 | |||
16 | #include <Ecore.h> | ||
17 | #include "ecore_private.h" | ||
18 | #include <Ecore_Ipc.h> | ||
19 | |||
20 | #include "ecore_config_ipc.h" | ||
21 | #include "ecore_config_util.h" | ||
22 | #include "ecore_config_private.h" | ||
23 | |||
24 | #include "Ecore_Config.h" | ||
25 | |||
26 | |||
27 | /*****************************************************************************/ | ||
28 | |||
29 | static int | ||
30 | _ecore_config_ipc_ecore_string_get(char **m, char **r) | ||
31 | { | ||
32 | char *q; | ||
33 | int l = 0; | ||
34 | |||
35 | if (!m || !*m) | ||
36 | return ECORE_CONFIG_ERR_NODATA; | ||
37 | if (!r) | ||
38 | return ECORE_CONFIG_ERR_FAIL; | ||
39 | q = *m; | ||
40 | if (*q != 's') | ||
41 | return ECORE_CONFIG_ERR_TYPEMISMATCH; | ||
42 | q++; | ||
43 | l = (*(q++)) << 8; | ||
44 | l += *(q++); | ||
45 | *r = q; | ||
46 | q += l; | ||
47 | *m = q; | ||
48 | WRN("IPC/eCore: got string-%d \"%s\"", l, *r); | ||
49 | return ECORE_CONFIG_ERR_SUCC; | ||
50 | } | ||
51 | |||
52 | static char * | ||
53 | _ecore_config_ipc_global_prop_list(Ecore_Config_Server * srv __UNUSED__, long serial __UNUSED__) | ||
54 | { | ||
55 | Ecore_Config_DB_File *db; | ||
56 | char **keys; | ||
57 | int key_count, x; | ||
58 | estring *s; | ||
59 | int f; | ||
60 | char buf[PATH_MAX], *p; | ||
61 | // char *data; UNUSED | ||
62 | Ecore_Config_Type type; | ||
63 | |||
64 | db = NULL; | ||
65 | s = estring_new(8192); | ||
66 | f = 0; | ||
67 | if ((p = getenv("HOME"))) | ||
68 | { | ||
69 | snprintf(buf, sizeof(buf), "%s/.e/config.eet", p); | ||
70 | if (!(db = _ecore_config_db_open_read(buf))) | ||
71 | { | ||
72 | strcpy(buf, PACKAGE_DATA_DIR"/system.eet"); | ||
73 | if (!(db = _ecore_config_db_open_read(buf))) | ||
74 | return NULL; | ||
75 | } | ||
76 | } | ||
77 | if (!db) return NULL; | ||
78 | key_count = 0; | ||
79 | keys = _ecore_config_db_keys_get(db, &key_count); | ||
80 | if (keys) | ||
81 | { | ||
82 | for (x = 0; x < key_count; x++) | ||
83 | { | ||
84 | type = _ecore_config_db_key_type_get(db, keys[x]); | ||
85 | switch (type) | ||
86 | { | ||
87 | case ECORE_CONFIG_INT: | ||
88 | estring_appendf(s, "%s%s: integer", f ? "\n" : "", keys[x]); | ||
89 | break; | ||
90 | case ECORE_CONFIG_BLN: | ||
91 | estring_appendf(s, "%s%s: boolean", f ? "\n" : "", keys[x]); | ||
92 | break; | ||
93 | case ECORE_CONFIG_FLT: | ||
94 | estring_appendf(s, "%s%s: float", f ? "\n" : "", keys[x]); | ||
95 | break; | ||
96 | case ECORE_CONFIG_STR: | ||
97 | estring_appendf(s, "%s%s: string", f ? "\n" : "", keys[x]); | ||
98 | break; | ||
99 | case ECORE_CONFIG_RGB: | ||
100 | estring_appendf(s, "%s%s: colour", f ? "\n" : "", keys[x]); | ||
101 | break; | ||
102 | case ECORE_CONFIG_THM: | ||
103 | estring_appendf(s, "%s%s: theme", f ? "\n" : "", keys[x]); | ||
104 | break; | ||
105 | case ECORE_CONFIG_SCT: | ||
106 | estring_appendf(s, "%s%s: structure", f ? "\n" : "", keys[x]); | ||
107 | break; | ||
108 | default: | ||
109 | estring_appendf(s, "%s%s: unknown", f ? "\n" : "", keys[x]); | ||
110 | continue; | ||
111 | } | ||
112 | f = 1; | ||
113 | } | ||
114 | } | ||
115 | _ecore_config_db_close(db); | ||
116 | if (keys) | ||
117 | { | ||
118 | for (x = 0; x < key_count; x++) | ||
119 | { | ||
120 | free(keys[x]); | ||
121 | } | ||
122 | free(keys); | ||
123 | } | ||
124 | |||
125 | return estring_disown(s); | ||
126 | } | ||
127 | |||
128 | /*****************************************************************************/ | ||
129 | |||
130 | static int | ||
131 | _ecore_config_ipc_ecore_send(Ecore_Ipc_Event_Client_Data * e, int code, | ||
132 | char *reply) | ||
133 | { | ||
134 | static int our_ref = 0; | ||
135 | int len = reply ? strlen(reply) + 1 : 0; | ||
136 | |||
137 | our_ref++; | ||
138 | WRN("IPC/eCore: replying [0,0] %d IRT %d => %d {\"%s\":%d}", our_ref, | ||
139 | e->ref, code, reply ? reply : "", len); | ||
140 | return ecore_ipc_client_send(e->client, 0, 0, our_ref, e->ref, code, reply, | ||
141 | len); | ||
142 | } | ||
143 | |||
144 | /*****************************************************************************/ | ||
145 | |||
146 | static int | ||
147 | _ecore_config_ipc_ecore_handle_request(Ecore_Ipc_Server * server, | ||
148 | Ecore_Ipc_Event_Client_Data * e) | ||
149 | { | ||
150 | Ecore_Config_Server *srv; | ||
151 | long serial; | ||
152 | int ret; | ||
153 | char *r, *k, *v, *m; | ||
154 | |||
155 | srv = _ecore_config_server_convert(server); | ||
156 | serial = e->minor; | ||
157 | r = NULL; | ||
158 | m = (char *)e->data; | ||
159 | INF("IPC/eCore: client sent: [%d,%d] #%d (%d) @ %p", e->major, e->minor, | ||
160 | e->ref, e->size, server); | ||
161 | |||
162 | switch (e->major) | ||
163 | { | ||
164 | case IPC_PROP_LIST: | ||
165 | if (srv == __ecore_config_server_global) | ||
166 | r = _ecore_config_ipc_global_prop_list(srv, serial); | ||
167 | else | ||
168 | r = _ecore_config_ipc_prop_list(srv, serial); | ||
169 | break; | ||
170 | case IPC_PROP_DESC: | ||
171 | if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) | ||
172 | r = _ecore_config_ipc_prop_desc(srv, serial, k); | ||
173 | break; | ||
174 | case IPC_PROP_GET: | ||
175 | if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) | ||
176 | r = _ecore_config_ipc_prop_get(srv, serial, k); | ||
177 | break; | ||
178 | case IPC_PROP_SET: | ||
179 | if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) | ||
180 | { | ||
181 | if (_ecore_config_ipc_ecore_string_get(&m, &v) == | ||
182 | ECORE_CONFIG_ERR_SUCC) | ||
183 | return _ecore_config_ipc_ecore_send(e, | ||
184 | _ecore_config_ipc_prop_set | ||
185 | (srv, serial, k, v), NULL); | ||
186 | } | ||
187 | break; | ||
188 | |||
189 | case IPC_BUNDLE_LIST: | ||
190 | r = _ecore_config_ipc_bundle_list(srv); | ||
191 | break; | ||
192 | case IPC_BUNDLE_NEW: | ||
193 | if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) | ||
194 | return _ecore_config_ipc_ecore_send(e, | ||
195 | k ? | ||
196 | _ecore_config_ipc_bundle_new(srv, | ||
197 | k) : | ||
198 | ECORE_CONFIG_ERR_FAIL, NULL); | ||
199 | break; | ||
200 | case IPC_BUNDLE_LABEL_SET: | ||
201 | if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) | ||
202 | return _ecore_config_ipc_ecore_send(e, | ||
203 | k ? | ||
204 | _ecore_config_ipc_bundle_label_set | ||
205 | (srv, serial, | ||
206 | k) : ECORE_CONFIG_ERR_FAIL, | ||
207 | NULL); | ||
208 | break; | ||
209 | case IPC_BUNDLE_LABEL_FIND: | ||
210 | if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) | ||
211 | return _ecore_config_ipc_ecore_send(e, | ||
212 | _ecore_config_ipc_bundle_label_find | ||
213 | (srv, k), NULL); | ||
214 | break; | ||
215 | case IPC_BUNDLE_LABEL_GET: | ||
216 | r = _ecore_config_ipc_bundle_label_get(srv, serial); | ||
217 | break; | ||
218 | } | ||
219 | |||
220 | ret = | ||
221 | _ecore_config_ipc_ecore_send(e, | ||
222 | r ? ECORE_CONFIG_ERR_SUCC : | ||
223 | ECORE_CONFIG_ERR_FAIL, r); | ||
224 | if (r) | ||
225 | { | ||
226 | free(r); | ||
227 | return ret; | ||
228 | } | ||
229 | return ECORE_CONFIG_ERR_NOTFOUND; | ||
230 | } | ||
231 | |||
232 | /*****************************************************************************/ | ||
233 | |||
234 | static Eina_Bool | ||
235 | _ecore_config_ipc_client_add(void *data, int type __UNUSED__, void *event) | ||
236 | { | ||
237 | Ecore_Ipc_Server **server; | ||
238 | Ecore_Ipc_Event_Client_Data *e; | ||
239 | |||
240 | server = (Ecore_Ipc_Server **) data; | ||
241 | e = (Ecore_Ipc_Event_Client_Data *) event; | ||
242 | |||
243 | if (*server != ecore_ipc_client_server_get(e->client)) | ||
244 | return EINA_TRUE; | ||
245 | |||
246 | INF("IPC/eCore: Client connected. @ %p", server); | ||
247 | return EINA_TRUE; | ||
248 | } | ||
249 | |||
250 | static Eina_Bool | ||
251 | _ecore_config_ipc_client_del(void *data, int type __UNUSED__, void *event) | ||
252 | { | ||
253 | Ecore_Ipc_Server **server; | ||
254 | Ecore_Ipc_Event_Client_Data *e; | ||
255 | |||
256 | server = (Ecore_Ipc_Server **) data; | ||
257 | e = (Ecore_Ipc_Event_Client_Data *) event; | ||
258 | |||
259 | if (*server != ecore_ipc_client_server_get(e->client)) | ||
260 | return EINA_TRUE; | ||
261 | |||
262 | INF("IPC/eCore: Client disconnected. @ %p", server); | ||
263 | return EINA_TRUE; | ||
264 | } | ||
265 | |||
266 | static Eina_Bool | ||
267 | _ecore_config_ipc_client_sent(void *data, int type __UNUSED__, void *event) | ||
268 | { | ||
269 | Ecore_Ipc_Server **server; | ||
270 | Ecore_Ipc_Event_Client_Data *e; | ||
271 | |||
272 | server = (Ecore_Ipc_Server **) data; | ||
273 | e = (Ecore_Ipc_Event_Client_Data *) event; | ||
274 | |||
275 | if (*server != ecore_ipc_client_server_get(e->client)) | ||
276 | return EINA_TRUE; | ||
277 | |||
278 | _ecore_config_ipc_ecore_handle_request(*server, e); | ||
279 | return EINA_TRUE; | ||
280 | } | ||
281 | |||
282 | /*****************************************************************************/ | ||
283 | |||
284 | int | ||
285 | _ecore_config_ipc_ecore_init(const char *pipe_name, void **data) | ||
286 | { | ||
287 | Ecore_Ipc_Server **server; | ||
288 | struct stat st; | ||
289 | char *p; | ||
290 | int port; | ||
291 | char socket[PATH_MAX]; | ||
292 | |||
293 | server = (Ecore_Ipc_Server **) data; | ||
294 | port = 0; | ||
295 | if (!server) | ||
296 | return ECORE_CONFIG_ERR_FAIL; | ||
297 | |||
298 | /* if(*server) | ||
299 | return ECORE_CONFIG_ERR_IGNORED; */ | ||
300 | |||
301 | ecore_init(); | ||
302 | if (ecore_ipc_init() < 1) | ||
303 | return ECORE_CONFIG_ERR_FAIL; | ||
304 | |||
305 | if ((p = getenv("HOME"))) | ||
306 | { /* debug-only ### FIXME */ | ||
307 | int stale; | ||
308 | |||
309 | stale = 1; | ||
310 | while (stale) | ||
311 | { | ||
312 | snprintf(socket, PATH_MAX, "%s/.ecore/%s/%d", p, pipe_name, port); | ||
313 | |||
314 | if (!stat(socket, &st)) | ||
315 | { | ||
316 | INF("IPC/eCore: pipe \"%s\" already exists!?", socket); | ||
317 | /* if(unlink(buf)) | ||
318 | E(0,"IPC/eCore: could not remove pipe \"%s\": %d\n",buf,errno); }}*/ | ||
319 | port++; | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | stale = 0; | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | *server = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, pipe_name, port, NULL); | ||
328 | ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, | ||
329 | _ecore_config_ipc_client_add, server); | ||
330 | ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, | ||
331 | _ecore_config_ipc_client_del, server); | ||
332 | ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, | ||
333 | _ecore_config_ipc_client_sent, server); | ||
334 | |||
335 | if (*server) | ||
336 | { | ||
337 | INF("IPC/eCore: Server is listening on %s.", pipe_name); | ||
338 | } | ||
339 | |||
340 | return ECORE_CONFIG_ERR_SUCC; | ||
341 | } | ||
342 | |||
343 | int | ||
344 | _ecore_config_ipc_ecore_exit(void **data) | ||
345 | { | ||
346 | int ret; | ||
347 | Ecore_Ipc_Server **server; | ||
348 | |||
349 | ret = ECORE_CONFIG_ERR_SUCC; | ||
350 | server = (Ecore_Ipc_Server **) data; | ||
351 | |||
352 | if (!server) | ||
353 | return ECORE_CONFIG_ERR_FAIL; | ||
354 | |||
355 | if (*server) | ||
356 | { | ||
357 | ecore_ipc_server_del(*server); | ||
358 | *server = NULL; | ||
359 | } | ||
360 | |||
361 | ecore_ipc_shutdown(); | ||
362 | ecore_shutdown(); | ||
363 | |||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | /*****************************************************************************/ | ||
368 | |||
369 | int | ||
370 | _ecore_config_ipc_ecore_poll(void **data) | ||
371 | { | ||
372 | Ecore_Ipc_Server **server; | ||
373 | |||
374 | server = (Ecore_Ipc_Server **) data; | ||
375 | |||
376 | if (!server) | ||
377 | return ECORE_CONFIG_ERR_FAIL; | ||
378 | |||
379 | ecore_main_loop_iterate(); | ||
380 | |||
381 | return ECORE_CONFIG_ERR_SUCC; | ||
382 | } | ||
383 | |||
384 | /*****************************************************************************/ | ||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_ipc_main.c b/libraries/ecore/src/lib/ecore_config/ecore_config_ipc_main.c new file mode 100644 index 0000000..35bd783 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_ipc_main.c | |||
@@ -0,0 +1,275 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | /* ############## bad */ | ||
6 | #define HAVE_EVAS2 | ||
7 | |||
8 | #include <signal.h> | ||
9 | #include <dlfcn.h> | ||
10 | #include <stdio.h> | ||
11 | #include <glob.h> | ||
12 | #include <sys/param.h> | ||
13 | #include <limits.h> | ||
14 | #include <string.h> | ||
15 | #include <stdlib.h> /* malloc(), free() */ | ||
16 | |||
17 | #include "Ecore.h" | ||
18 | #include "Ecore_Config.h" | ||
19 | #include "ecore_config_util.h" | ||
20 | #include "ecore_config_ipc.h" | ||
21 | |||
22 | #include "ecore_config_private.h" | ||
23 | |||
24 | static Ecore_Config_Server *__ecore_config_servers; | ||
25 | Ecore_Timer *ipc_timer = NULL; | ||
26 | |||
27 | Ecore_Config_Server * | ||
28 | _ecore_config_server_convert(void *srv) | ||
29 | { | ||
30 | Ecore_Config_Server *srv_tmp; | ||
31 | |||
32 | srv_tmp = __ecore_config_servers; | ||
33 | while (srv_tmp) | ||
34 | { | ||
35 | if (srv_tmp->server == srv) | ||
36 | return srv_tmp; | ||
37 | srv_tmp = srv_tmp->next; | ||
38 | } | ||
39 | |||
40 | return __ecore_config_server_global; | ||
41 | } | ||
42 | |||
43 | /*****************************************************************************/ | ||
44 | /* INTERFACE FOR IPC MODULES */ | ||
45 | /*****************************/ | ||
46 | |||
47 | char * | ||
48 | _ecore_config_ipc_prop_list(Ecore_Config_Server * srv, const long serial) | ||
49 | { | ||
50 | Ecore_Config_Bundle *theme; | ||
51 | Ecore_Config_Prop *e; | ||
52 | estring *s; | ||
53 | int f; | ||
54 | |||
55 | theme = ecore_config_bundle_by_serial_get(srv, serial); | ||
56 | e = theme ? theme->data : NULL; | ||
57 | s = estring_new(8192); | ||
58 | f = 0; | ||
59 | while (e) | ||
60 | { | ||
61 | /* ignore system properties in listings, unless they have been overridden */ | ||
62 | if (e->flags & ECORE_CONFIG_FLAG_SYSTEM && !(e->flags & ECORE_CONFIG_FLAG_MODIFIED)) | ||
63 | { | ||
64 | e = e->next; | ||
65 | continue; | ||
66 | } | ||
67 | estring_appendf(s, "%s%s: %s", f ? "\n" : "", e->key, | ||
68 | ecore_config_type_get(e)); | ||
69 | if (e->flags & ECORE_CONFIG_FLAG_BOUNDS) | ||
70 | { | ||
71 | if (e->type == ECORE_CONFIG_FLT) | ||
72 | estring_appendf(s, ", range %le..%le", | ||
73 | (float)e->lo / ECORE_CONFIG_FLOAT_PRECISION, | ||
74 | (float)e->hi / ECORE_CONFIG_FLOAT_PRECISION); | ||
75 | else | ||
76 | estring_appendf(s, ", range %d..%d", e->lo, e->hi); | ||
77 | } | ||
78 | if (e->type == ECORE_CONFIG_THM) | ||
79 | estring_appendf(s, ", group %s", e->data ? e->data : "Main"); | ||
80 | f = 1; | ||
81 | e = e->next; | ||
82 | } | ||
83 | |||
84 | return estring_disown(s); | ||
85 | } | ||
86 | |||
87 | char * | ||
88 | _ecore_config_ipc_prop_desc(Ecore_Config_Server * srv, const long serial, | ||
89 | const char *key) | ||
90 | { | ||
91 | #ifdef HAVE_EVAS2 | ||
92 | Ecore_Config_Prop *e; | ||
93 | |||
94 | e = ecore_config_get(key); | ||
95 | if (e) | ||
96 | { | ||
97 | estring *s = estring_new(512); | ||
98 | |||
99 | estring_appendf(s, "%s: %s", e->key, ecore_config_type_get(e)); | ||
100 | if (e->flags & ECORE_CONFIG_FLAG_BOUNDS) | ||
101 | estring_appendf(s, ", range %d..%d", e->lo, e->hi); | ||
102 | return estring_disown(s); | ||
103 | } | ||
104 | #endif | ||
105 | return strdup("<undefined>"); | ||
106 | } | ||
107 | |||
108 | char * | ||
109 | _ecore_config_ipc_prop_get(Ecore_Config_Server * srv, const long serial, | ||
110 | const char *key) | ||
111 | { | ||
112 | #ifdef HAVE_EVAS2 | ||
113 | char *ret; | ||
114 | |||
115 | if ((ret = ecore_config_as_string_get(key))) | ||
116 | return ret; | ||
117 | #endif | ||
118 | return strdup("<undefined>"); | ||
119 | } | ||
120 | |||
121 | int | ||
122 | _ecore_config_ipc_prop_set(Ecore_Config_Server * srv, const long serial, | ||
123 | const char *key, const char *val) | ||
124 | { | ||
125 | #ifdef HAVE_EVAS2 | ||
126 | int ret; | ||
127 | Ecore_Config_Bundle *theme; | ||
128 | |||
129 | theme = ecore_config_bundle_by_serial_get(srv, serial); | ||
130 | ret = ecore_config_set(key, (char *)val); | ||
131 | ERR("ipc.prop.set(%s->%s,\"%s\") => %d\n", theme ? theme->identifier : "", | ||
132 | key, val, ret); | ||
133 | return ret; | ||
134 | #else | ||
135 | return ECORE_CONFIG_ERR_NOTSUPP; | ||
136 | #endif | ||
137 | } | ||
138 | |||
139 | /*****************************************************************************/ | ||
140 | |||
141 | char * | ||
142 | _ecore_config_ipc_bundle_list(Ecore_Config_Server * srv) | ||
143 | { | ||
144 | Ecore_Config_Bundle *ns; | ||
145 | estring *s; | ||
146 | int f; | ||
147 | |||
148 | ns = ecore_config_bundle_1st_get(srv); | ||
149 | s = estring_new(8192); | ||
150 | f = 0; | ||
151 | if (!ns) | ||
152 | return strdup("<no_bundles_created>"); | ||
153 | |||
154 | while (ns) | ||
155 | { | ||
156 | estring_appendf(s, "%s%d: %s", f ? "\n" : "", | ||
157 | ecore_config_bundle_serial_get(ns), | ||
158 | ecore_config_bundle_label_get(ns)); | ||
159 | f = 1; | ||
160 | ns = ecore_config_bundle_next_get(ns); | ||
161 | } | ||
162 | |||
163 | return estring_disown(s); | ||
164 | } | ||
165 | |||
166 | int | ||
167 | _ecore_config_ipc_bundle_new(Ecore_Config_Server * srv, const char *label) | ||
168 | { | ||
169 | if (ecore_config_bundle_new(srv, label)) | ||
170 | return ECORE_CONFIG_ERR_SUCC; | ||
171 | return ECORE_CONFIG_ERR_FAIL; | ||
172 | } | ||
173 | |||
174 | char * | ||
175 | _ecore_config_ipc_bundle_label_get(Ecore_Config_Server * srv, const long serial) | ||
176 | { | ||
177 | Ecore_Config_Bundle *ns; | ||
178 | char *label; | ||
179 | |||
180 | ns = ecore_config_bundle_by_serial_get(srv, serial); | ||
181 | label = ecore_config_bundle_label_get(ns); | ||
182 | return strdup(label ? label : "<no such bundle>"); | ||
183 | } | ||
184 | |||
185 | int | ||
186 | _ecore_config_ipc_bundle_label_set(Ecore_Config_Server * srv, const long serial, | ||
187 | const char *label) | ||
188 | { | ||
189 | Ecore_Config_Bundle *ns; | ||
190 | |||
191 | ns = ecore_config_bundle_by_serial_get(srv, serial); | ||
192 | if (!(ns->identifier = malloc(sizeof(label)))) | ||
193 | return ECORE_CONFIG_ERR_OOM; | ||
194 | memcpy(ns->identifier, label, sizeof(label)); | ||
195 | return ECORE_CONFIG_ERR_SUCC; | ||
196 | } | ||
197 | |||
198 | long | ||
199 | _ecore_config_ipc_bundle_label_find(Ecore_Config_Server * srv, | ||
200 | const char *label) | ||
201 | { | ||
202 | Ecore_Config_Bundle *ns; | ||
203 | |||
204 | ns = ecore_config_bundle_by_label_get(srv, label); | ||
205 | return ns ? ecore_config_bundle_serial_get(ns) : -1; | ||
206 | } | ||
207 | |||
208 | static Eina_Bool | ||
209 | _ecore_config_ipc_poll(void *data __UNUSED__) | ||
210 | { | ||
211 | Ecore_Config_Server *s; | ||
212 | |||
213 | s = __ecore_config_servers; | ||
214 | while (s) | ||
215 | { | ||
216 | _ecore_config_ipc_ecore_poll(&s->server); | ||
217 | s = s->next; | ||
218 | } | ||
219 | |||
220 | return EINA_TRUE; | ||
221 | } | ||
222 | |||
223 | int | ||
224 | _ecore_config_ipc_exit(void) | ||
225 | { | ||
226 | Ecore_Config_Server *l; | ||
227 | |||
228 | if (ipc_timer) | ||
229 | ecore_timer_del(ipc_timer); | ||
230 | |||
231 | l = __ecore_config_servers; | ||
232 | while (l) | ||
233 | { | ||
234 | _ecore_config_ipc_ecore_exit(&l->server); | ||
235 | if (l->name) | ||
236 | free(l->name); | ||
237 | l = l->next; | ||
238 | } | ||
239 | |||
240 | return ECORE_CONFIG_ERR_SUCC; | ||
241 | } | ||
242 | |||
243 | Ecore_Config_Server * | ||
244 | _ecore_config_ipc_init(const char *pipe_name) | ||
245 | { | ||
246 | int ret; | ||
247 | Ecore_Config_Server *list; | ||
248 | Ecore_Config_Server *ret_srv; | ||
249 | |||
250 | list = NULL; | ||
251 | ret_srv = NULL; | ||
252 | list = NULL; | ||
253 | |||
254 | list = calloc(1, sizeof(Ecore_Config_Server)); | ||
255 | if ((ret = _ecore_config_ipc_ecore_init(pipe_name, &list->server)) != ECORE_CONFIG_ERR_SUCC) | ||
256 | { | ||
257 | ERR("_ecore_config_ipc_init: failed to register %s, code %d", | ||
258 | pipe_name, ret); | ||
259 | } | ||
260 | |||
261 | ERR("_ecore_config_ipc_init: registered \"%s\"...", pipe_name); | ||
262 | |||
263 | list->name = strdup(pipe_name); | ||
264 | list->next = __ecore_config_servers; | ||
265 | |||
266 | __ecore_config_servers = list; | ||
267 | if (!ret_srv) | ||
268 | ret_srv = list; | ||
269 | |||
270 | if (!ipc_timer) | ||
271 | ipc_timer = ecore_timer_add(100, _ecore_config_ipc_poll, NULL); | ||
272 | |||
273 | return ret_srv; | ||
274 | } | ||
275 | /*****************************************************************************/ | ||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_private.h b/libraries/ecore/src/lib/ecore_config/ecore_config_private.h new file mode 100644 index 0000000..b97f695 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_private.h | |||
@@ -0,0 +1,70 @@ | |||
1 | #ifndef _ECORE_CONFIG_PRIVATE_H | ||
2 | # define _ECORE_CONFIG_PRIVATE_H | ||
3 | #ifdef ECORE_CONFIG_DEFAULT_LOG_COLOR | ||
4 | # undef ECORE_CONFIG_DEFAULT_LOG_COLOR | ||
5 | #endif | ||
6 | #define ECORE_CONFIG_DEFAULT_LOG_COLOR EINA_COLOR_BLUE | ||
7 | /* eina_log related things */ | ||
8 | |||
9 | extern int _ecore_config_log_dom; | ||
10 | #ifdef ERR | ||
11 | # undef ERR | ||
12 | #endif | ||
13 | #define ERR(...) EINA_LOG_DOM_ERR(_ecore_config_log_dom, __VA_ARGS__) | ||
14 | |||
15 | #ifdef DBG | ||
16 | # undef DBG | ||
17 | #endif | ||
18 | #define DBG(...) EINA_LOG_DOM_DBG(_ecore_config_log_dom, __VA_ARGS__) | ||
19 | |||
20 | #ifdef INF | ||
21 | # undef INF | ||
22 | #endif | ||
23 | #define INF(...) EINA_LOG_DOM_INFO(_ecore_config_log_dom, __VA_ARGS__) | ||
24 | |||
25 | #ifdef WRN | ||
26 | # undef WRN | ||
27 | #endif | ||
28 | #define WRN(...) EINA_LOG_DOM_WARN(_ecore_config_log_dom, __VA_ARGS__) | ||
29 | |||
30 | #ifdef CRIT | ||
31 | # undef CRIT | ||
32 | #endif | ||
33 | #define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_config_log_dom, __VA_ARGS__) | ||
34 | |||
35 | /* debug */ | ||
36 | extern int DEBUG; | ||
37 | |||
38 | |||
39 | typedef struct _Ecore_Config_DB_File Ecore_Config_DB_File; | ||
40 | |||
41 | int _ecore_config_mod_init(const char *pipe_name, void **data); | ||
42 | int _ecore_config_mod_exit(void **data); | ||
43 | int _ecore_config_mod_poll(void **data); | ||
44 | |||
45 | Ecore_Config_DB_File *_ecore_config_db_open_read(const char *file); | ||
46 | Ecore_Config_DB_File *_ecore_config_db_open_write(const char *file); | ||
47 | void _ecore_config_db_close(Ecore_Config_DB_File *db); | ||
48 | char **_ecore_config_db_keys_get(Ecore_Config_DB_File *db, int *num_ret); | ||
49 | Ecore_Config_Type _ecore_config_db_key_type_get(Ecore_Config_DB_File *db, const char *key); | ||
50 | int _ecore_config_db_read(Ecore_Config_DB_File *db, const char *key); | ||
51 | void _ecore_config_db_write(Ecore_Config_DB_File *db, Ecore_Config_Prop *e); | ||
52 | |||
53 | int _ecore_config_boolean_get(Ecore_Config_Prop *e); | ||
54 | char *_ecore_config_string_get(Ecore_Config_Prop *e); | ||
55 | long _ecore_config_int_get(Ecore_Config_Prop *e); | ||
56 | int _ecore_config_argb_get(Ecore_Config_Prop *e, int *a, int *r, | ||
57 | int *g, int *b); | ||
58 | char *_ecore_config_argbstr_get(Ecore_Config_Prop *e); | ||
59 | long _ecore_config_argbint_get(Ecore_Config_Prop *e); | ||
60 | float _ecore_config_float_get(Ecore_Config_Prop *e); | ||
61 | char *_ecore_config_theme_get(Ecore_Config_Prop *e); | ||
62 | |||
63 | int _ecore_config_ipc_ecore_init(const char *pipe_name, void **data); | ||
64 | int _ecore_config_ipc_ecore_exit(void **data); | ||
65 | int _ecore_config_ipc_ecore_poll(void **data); | ||
66 | |||
67 | #include "Ecore.h" | ||
68 | #include "ecore_private.h" | ||
69 | |||
70 | #endif | ||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_storage.c b/libraries/ecore/src/lib/ecore_config/ecore_config_storage.c new file mode 100644 index 0000000..d059645 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_storage.c | |||
@@ -0,0 +1,176 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <stdlib.h> | ||
6 | #include <stdio.h> | ||
7 | #include <string.h> | ||
8 | #include <limits.h> | ||
9 | |||
10 | #include <sys/param.h> | ||
11 | #include <sys/types.h> | ||
12 | #include <sys/stat.h> | ||
13 | #include <unistd.h> | ||
14 | |||
15 | #include "Ecore_Config.h" | ||
16 | #include "ecore_config_private.h" | ||
17 | |||
18 | /** | ||
19 | * Loads the default configuration. | ||
20 | * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA | ||
21 | * is returned if the file cannot be loaded. | ||
22 | * @ingroup Ecore_Config_File_Group | ||
23 | */ | ||
24 | EAPI int | ||
25 | ecore_config_load(void) | ||
26 | { | ||
27 | char file[PATH_MAX]; | ||
28 | |||
29 | if (!__ecore_config_app_name) | ||
30 | return ECORE_CONFIG_ERR_FAIL; | ||
31 | |||
32 | snprintf(file, PATH_MAX, "%s/.e/apps/%s/config.eet", getenv("HOME"), | ||
33 | __ecore_config_app_name); | ||
34 | return ecore_config_file_load(file); | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * Saves the current configuration to the default file. | ||
39 | * @return @c ECORE_CONFIG_ERR_SUCC is returned on success. | ||
40 | * @c ECORE_CONFIG_ERR_FAIL is returned if the data cannot be | ||
41 | * saved. | ||
42 | * @ingroup Ecore_Config_File_Group | ||
43 | */ | ||
44 | EAPI int | ||
45 | ecore_config_save(void) | ||
46 | { | ||
47 | char file[PATH_MAX]; | ||
48 | |||
49 | if (!__ecore_config_app_name) | ||
50 | return ECORE_CONFIG_ERR_FAIL; | ||
51 | |||
52 | snprintf(file, PATH_MAX, "%s/.e/apps/%s/config.eet", getenv("HOME"), | ||
53 | __ecore_config_app_name); | ||
54 | return ecore_config_file_save(file); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Load the given configuration file to the local configuration. | ||
59 | * @param file Name of the file to load. | ||
60 | * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA | ||
61 | * is returned if the file cannot be loaded. | ||
62 | * @ingroup Ecore_Config_File_Group | ||
63 | */ | ||
64 | EAPI int | ||
65 | ecore_config_file_load(const char *file) | ||
66 | { | ||
67 | Ecore_Config_DB_File *db; | ||
68 | char **keys; | ||
69 | int key_count; | ||
70 | int x; | ||
71 | // double ftmp; UNUSED | ||
72 | // int pt; UNUSED | ||
73 | // int itmp; UNUSED | ||
74 | // Ecore_Config_Type type; UNUSED | ||
75 | char *data; | ||
76 | |||
77 | db = NULL; | ||
78 | data = NULL; | ||
79 | |||
80 | db = _ecore_config_db_open_read(file); | ||
81 | if (!db) | ||
82 | { | ||
83 | ERR("Cannot open database from file %s!", file); | ||
84 | return ECORE_CONFIG_ERR_NODATA; | ||
85 | } | ||
86 | key_count = 0; | ||
87 | keys = _ecore_config_db_keys_get(db, &key_count); | ||
88 | if (keys) | ||
89 | { | ||
90 | for (x = 0; x < key_count; x++) | ||
91 | { | ||
92 | _ecore_config_db_read(db, keys[x]); | ||
93 | } | ||
94 | } | ||
95 | _ecore_config_db_close(db); | ||
96 | if (keys) | ||
97 | { | ||
98 | for (x = 0; x < key_count; x++) | ||
99 | { | ||
100 | free(keys[x]); | ||
101 | } | ||
102 | free(keys); | ||
103 | } | ||
104 | return ECORE_CONFIG_ERR_SUCC; | ||
105 | } | ||
106 | |||
107 | static void | ||
108 | _ecore_config_recurse_mkdir(const char *file) | ||
109 | { | ||
110 | char *file_ptr; | ||
111 | char *file_tmp; | ||
112 | struct stat status; | ||
113 | |||
114 | file_tmp = strdup(file); | ||
115 | file_ptr = file_tmp + strlen(file_tmp); | ||
116 | while (*file_ptr != '/' && file_ptr > file_tmp) | ||
117 | file_ptr--; | ||
118 | *file_ptr = '\0'; | ||
119 | |||
120 | if ((file_tmp[0] != 0) && stat(file_tmp, &status)) | ||
121 | { | ||
122 | _ecore_config_recurse_mkdir(file_tmp); | ||
123 | mkdir(file_tmp, S_IRUSR | S_IWUSR | S_IXUSR); | ||
124 | } | ||
125 | free(file_tmp); | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * Saves the local configuration to the given file. | ||
130 | * @param file Name of the file to save to. | ||
131 | * @return @c ECORE_CONFIG_ERR_SUCC is returned on success. | ||
132 | * @c ECORE_CONFIG_ERR_FAIL is returned if the data cannot be | ||
133 | * saved. | ||
134 | * @ingroup Ecore_Config_File_Group | ||
135 | */ | ||
136 | EAPI int | ||
137 | ecore_config_file_save(const char *file) | ||
138 | { | ||
139 | Ecore_Config_Prop *next; | ||
140 | Ecore_Config_DB_File *db; | ||
141 | struct stat status; | ||
142 | |||
143 | next = __ecore_config_bundle_local->data; | ||
144 | db = NULL; | ||
145 | |||
146 | /* if file does not exist check to see if the dirs exist, creating if not */ | ||
147 | if (stat(file, &status)) | ||
148 | _ecore_config_recurse_mkdir(file); | ||
149 | |||
150 | db = _ecore_config_db_open_write(file); | ||
151 | if (!db) | ||
152 | { | ||
153 | ERR("Cannot open database from file %s!", file); | ||
154 | return ECORE_CONFIG_ERR_FAIL; | ||
155 | } | ||
156 | |||
157 | while (next) | ||
158 | { | ||
159 | /* let the config_db deal with this | ||
160 | * handyande: hmm, not sure that it ever does - reinstating until | ||
161 | * further discussions satisfy me! | ||
162 | */ | ||
163 | if (!(next->flags & ECORE_CONFIG_FLAG_MODIFIED) || next->flags & ECORE_CONFIG_FLAG_CMDLN) | ||
164 | { | ||
165 | next = next->next; | ||
166 | continue; | ||
167 | } | ||
168 | |||
169 | _ecore_config_db_write(db, next); | ||
170 | |||
171 | next = next->next; | ||
172 | } | ||
173 | |||
174 | _ecore_config_db_close(db); | ||
175 | return ECORE_CONFIG_ERR_SUCC; | ||
176 | } | ||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_util.c b/libraries/ecore/src/lib/ecore_config/ecore_config_util.c new file mode 100644 index 0000000..6156936 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_util.c | |||
@@ -0,0 +1,129 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | /* azundris */ | ||
6 | |||
7 | #include <sys/types.h> | ||
8 | #include <stdlib.h> /* malloc(), free() */ | ||
9 | #include <stdio.h> | ||
10 | #include <string.h> /* str...() */ | ||
11 | |||
12 | #include <stdarg.h> /* varargs in sprintf/appendf */ | ||
13 | |||
14 | #include "Ecore.h" | ||
15 | #include "ecore_private.h" | ||
16 | |||
17 | #include "Ecore_Config.h" | ||
18 | #include "ecore_config_util.h" | ||
19 | |||
20 | #include "ecore_config_private.h" | ||
21 | |||
22 | #define CHUNKLEN 4096 | ||
23 | |||
24 | /*****************************************************************************/ | ||
25 | /* STRINGS */ | ||
26 | /***********/ | ||
27 | |||
28 | estring * | ||
29 | estring_new(int size) | ||
30 | { | ||
31 | estring *e = malloc(sizeof(estring)); | ||
32 | |||
33 | if (e) | ||
34 | { | ||
35 | memset(e, 0, sizeof(estring)); | ||
36 | if ((size > 0) && (e->str = malloc(size))) | ||
37 | e->alloc = size; | ||
38 | } | ||
39 | return e; | ||
40 | } | ||
41 | |||
42 | char * | ||
43 | estring_disown(estring * e) | ||
44 | { | ||
45 | if (e) | ||
46 | { | ||
47 | char *r = e->str; | ||
48 | |||
49 | free(e); | ||
50 | return r; | ||
51 | } | ||
52 | return NULL; | ||
53 | } | ||
54 | |||
55 | int | ||
56 | estring_appendf(estring * e, const char *fmt, ...) | ||
57 | { | ||
58 | int need; | ||
59 | va_list ap; | ||
60 | char *p; | ||
61 | |||
62 | if (!e) | ||
63 | return ECORE_CONFIG_ERR_FAIL; | ||
64 | |||
65 | if (!e->str) | ||
66 | { | ||
67 | e->used = e->alloc = 0; | ||
68 | if (!(e->str = (char *)malloc(e->alloc = CHUNKLEN))) | ||
69 | return ECORE_CONFIG_ERR_OOM; | ||
70 | } | ||
71 | |||
72 | va_start(ap, fmt); | ||
73 | need = vsnprintf(NULL, 0, fmt, ap); | ||
74 | va_end(ap); | ||
75 | |||
76 | if (need >= (e->alloc - e->used)) | ||
77 | { | ||
78 | e->alloc = e->used + need + (CHUNKLEN - (need % CHUNKLEN)); | ||
79 | |||
80 | if (!(p = (char *)realloc(e->str, e->alloc))) | ||
81 | { | ||
82 | free(e->str); | ||
83 | e->alloc = e->used = 0; | ||
84 | return ECORE_CONFIG_ERR_OOM; | ||
85 | } | ||
86 | e->str = p; | ||
87 | } | ||
88 | |||
89 | va_start(ap, fmt); | ||
90 | need = vsnprintf(e->str + e->used, e->alloc - e->used, fmt, ap); | ||
91 | va_end(ap); | ||
92 | |||
93 | return e->used += need; | ||
94 | } | ||
95 | |||
96 | int | ||
97 | esprintf(char **result, const char *fmt, ...) | ||
98 | { | ||
99 | va_list ap; | ||
100 | size_t need; | ||
101 | char *n; | ||
102 | |||
103 | if (!result) | ||
104 | return ECORE_CONFIG_ERR_FAIL; | ||
105 | |||
106 | va_start(ap, fmt); | ||
107 | need = vsnprintf(NULL, 0, fmt, ap) + 1; | ||
108 | va_end(ap); | ||
109 | n = malloc(need + 1); | ||
110 | |||
111 | if (n) | ||
112 | { | ||
113 | va_start(ap, fmt); | ||
114 | need = vsnprintf(n, need, fmt, ap); | ||
115 | va_end(ap); | ||
116 | |||
117 | n[need] = 0; | ||
118 | |||
119 | if(*result) | ||
120 | free(result); | ||
121 | *result = n; | ||
122 | |||
123 | return need; | ||
124 | } | ||
125 | |||
126 | return ECORE_CONFIG_ERR_OOM; | ||
127 | } | ||
128 | |||
129 | /*****************************************************************************/ | ||
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_util.h b/libraries/ecore/src/lib/ecore_config/ecore_config_util.h new file mode 100644 index 0000000..5bee9d6 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_util.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #define TIMER_STOP 0 | ||
2 | #define TIMER_CONT 1 | ||
3 | |||
4 | typedef struct _estring | ||
5 | { | ||
6 | char *str; | ||
7 | int alloc, used; | ||
8 | } estring; | ||
9 | |||
10 | estring *estring_new(int size); | ||
11 | char *estring_disown(estring * e); | ||
12 | int estring_appendf(estring * e, const char *fmt, ...); | ||
13 | |||
14 | int esprintf(char **result, const char *fmt, ...); | ||