move around - flatter.
[profile/ivi/ecore.git] / src / lib / ecore_con / ecore_con.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include <sys/stat.h>
6 #include <arpa/inet.h>
7 #include <sys/socket.h>
8 #include <sys/un.h>
9 #include <errno.h>
10
11 #include <config.h>
12
13 #if USE_OPENSSL
14 #include <time.h>
15 #endif
16
17 #include "Ecore.h"
18 #include "ecore_private.h"
19 #include "Ecore_Con.h"
20 #include "ecore_con_private.h"
21
22 #ifdef HAVE_NETINET_IN_H
23 # include <netinet/in.h>
24 #endif
25 #ifdef HAVE_WINSOCK2_H
26 # include <winsock2.h>
27 #endif
28
29 static void _ecore_con_cb_dns_lookup(void *data, struct hostent *he);
30 static void _ecore_con_server_free(Ecore_Con_Server *svr);
31 static void _ecore_con_client_free(Ecore_Con_Client *cl);
32 static int _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler);
33 static int _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
34 static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
35 static void _ecore_con_server_flush(Ecore_Con_Server *svr);
36 static void _ecore_con_client_flush(Ecore_Con_Client *cl);
37 static void _ecore_con_event_client_add_free(void *data, void *ev);
38 static void _ecore_con_event_client_del_free(void *data, void *ev);
39 static void _ecore_con_event_client_data_free(void *data, void *ev);
40 static void _ecore_con_event_server_add_free(void *data, void *ev);
41 static void _ecore_con_event_server_del_free(void *data, void *ev);
42 static void _ecore_con_event_server_data_free(void *data, void *ev);
43
44 EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0;
45 EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0;
46 EAPI int ECORE_CON_EVENT_SERVER_ADD = 0;
47 EAPI int ECORE_CON_EVENT_SERVER_DEL = 0;
48 EAPI int ECORE_CON_EVENT_CLIENT_DATA = 0;
49 EAPI int ECORE_CON_EVENT_SERVER_DATA = 0;
50
51 static Ecore_List *servers = NULL;
52 static int init_count = 0;
53 #if USE_OPENSSL
54 static int ssl_init_count = 0;
55 #endif
56
57 #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
58 #define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
59
60 /**
61  * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions
62  *
63  * Utility functions that set up and shut down the Ecore Connection
64  * library.
65  */
66
67 /**
68  * Initialises the Ecore_Con library.
69  * @return  Number of times the library has been initialised without being
70  *          shut down.
71  * @ingroup Ecore_Con_Lib_Group
72  */
73 EAPI int
74 ecore_con_init(void)
75 {
76    if (++init_count != 1) return init_count;
77
78    ecore_init();
79    ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new();
80    ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new();
81    ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new();
82    ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new();
83    ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new();
84    ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new();
85
86    /* TODO Remember return value, if it fails, use gethostbyname() */
87    ecore_con_dns_init();
88
89    servers = ecore_list_new();
90
91    return init_count;
92 }
93
94 /**
95  * Shuts down the Ecore_Con library.
96  * @return  Number of times the library has been initialised without being
97  *          shut down.
98  * @ingroup Ecore_Con_Lib_Group
99  */
100 EAPI int
101 ecore_con_shutdown(void)
102 {
103    if (--init_count != 0) return init_count;
104
105    while (!ecore_list_empty_is(servers))
106      _ecore_con_server_free(ecore_list_first_remove(servers));
107    ecore_list_destroy(servers);
108    servers = NULL;
109
110    ecore_con_dns_shutdown();
111
112    ecore_shutdown();
113
114    return init_count;
115 }
116
117 /**
118  * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions
119  *
120  * Functions that operate on Ecore server objects.
121  */
122
123 /**
124  * Creates a server to listen for connections.
125  *
126  * The socket on which the server listens depends on the connection
127  * type:
128  * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the server will listen on
129  *     the Unix socket "~/.ecore/[name]/[port]".
130  * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen
131  *     on Unix socket "/tmp/.ecore_service|[name]|[port]".
132  * @li If @a compl_type is @c ECORE_CON_REMOTE_SYSTEM, the server will listen
133  *     on TCP port @c port.
134  *
135  * @param  compl_type The connection type.
136  * @param  name       Name to associate with the socket.  It is used when
137  *                    generating the socket name of a Unix socket.  Though
138  *                    it is not used for the TCP socket, it still needs to
139  *                    be a valid character array.  @c NULL will not be
140  *                    accepted.
141  * @param  port       Number to identify socket.  When a Unix socket is used,
142  *                    it becomes part of the socket name.  When a TCP socket
143  *                    is used, it is used as the TCP port.
144  * @param  data       Data to associate with the created Ecore_Con_Server
145  *                    object.
146  * @return A new Ecore_Con_Server.
147  * @ingroup Ecore_Con_Server_Group
148  */
149 EAPI Ecore_Con_Server *
150 ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port,
151                      const void *data)
152 {
153    Ecore_Con_Server   *svr;
154    Ecore_Con_Type      type;
155    struct sockaddr_in  socket_addr;
156    struct sockaddr_un  socket_unix;
157    struct linger       lin;
158    char                buf[4096];
159
160    if (port < 0) return NULL;
161    /* local  user   socket: FILE:   ~/.ecore/[name]/[port] */
162    /* local  system socket: FILE:   /tmp/.ecore_service|[name]|[port] */
163    /* remote system socket: TCP/IP: [name]:[port] */
164    svr = calloc(1, sizeof(Ecore_Con_Server));
165    if (!svr) return NULL;
166
167    type = compl_type;
168 #if USE_OPENSSL
169    /* unset the SSL flag for the following checks */
170    type &= ECORE_CON_TYPE;
171 #endif
172
173    if ((type == ECORE_CON_LOCAL_USER) || (type == ECORE_CON_LOCAL_SYSTEM) ||
174        (type == ECORE_CON_LOCAL_ABSTRACT))
175      {
176         const char *homedir;
177         struct stat st;
178         mode_t pmode, mask;
179         int socket_unix_len;
180
181         if (!name) goto error;
182         mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
183
184         if (type == ECORE_CON_LOCAL_USER)
185           {
186              homedir = getenv("HOME");
187              if (!homedir) homedir = getenv("TMP");
188              if (!homedir) homedir = "/tmp";
189              mask = S_IRUSR | S_IWUSR | S_IXUSR;
190              snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
191              if (stat(buf, &st) < 0) mkdir(buf, mask);
192              snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, name);
193              if (stat(buf, &st) < 0) mkdir(buf, mask);
194              snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, name, port);
195              mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
196           }
197         else if (type == ECORE_CON_LOCAL_SYSTEM)
198           {
199              mask = 0;
200              if (name[0] == '/')
201                {
202                   if (port >= 0)
203                     snprintf(buf, sizeof(buf), "%s|%i", name, port);
204                   else
205                     snprintf(buf, sizeof(buf), "%s", name);
206                }
207              else
208                snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", name, port);
209           }
210         else if (type == ECORE_CON_LOCAL_ABSTRACT)
211           strncpy(buf, name, sizeof(buf));
212         pmode = umask(mask);
213         start:
214         svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
215         if (svr->fd < 0)
216           {
217              umask(pmode);
218              goto error;
219           }
220         if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
221           {
222              umask(pmode);
223              goto error;
224           }
225         if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
226           {
227              umask(pmode);
228              goto error;
229           }
230         lin.l_onoff = 1;
231         lin.l_linger = 0;
232         if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0)
233           {
234              umask(pmode);
235              goto error;
236           }
237         socket_unix.sun_family = AF_UNIX;
238         if (type == ECORE_CON_LOCAL_ABSTRACT)
239           {
240 #ifdef HAVE_ABSTRACT_SOCKET
241              /* . is a placeholder */
242              snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s", name);
243              /* first char null indicates abstract namespace */
244              socket_unix.sun_path[0] = '\0';
245              socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, name);
246 #else
247              fprintf(stderr, "Your system does not support abstract sockets!\n");
248              umask(pmode);
249              goto error;
250 #endif
251           }
252         else
253           {
254              strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
255              socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
256           }
257         if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
258           {
259              if (connect(svr->fd, (struct sockaddr *)&socket_unix,
260                          socket_unix_len) < 0)
261                {
262                   if ((type == ECORE_CON_LOCAL_USER) || 
263                       (type == ECORE_CON_LOCAL_SYSTEM))
264                     {
265                        if (unlink(buf) < 0)
266                          {
267                             umask(pmode);
268                             goto error;
269                          }
270                        else
271                          goto start;
272                     }
273                   else
274                     {
275                        umask(pmode);
276                        goto error;
277                     }
278                }
279              else
280                {
281                   umask(pmode);
282                   goto error;
283                }
284           }
285         if (listen(svr->fd, 4096) < 0)
286           {
287              umask(pmode);
288              goto error;
289           }
290         svr->path = strdup(buf);
291         if (!svr->path)
292           {
293              umask(pmode);
294              goto error;
295           }
296         svr->fd_handler = 
297           ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
298                                     _ecore_con_svr_handler, svr, NULL, NULL);
299         umask(pmode);
300         if (!svr->fd_handler) goto error;
301      }
302    else if (type == ECORE_CON_REMOTE_SYSTEM)
303      {
304         svr->fd = socket(AF_INET, SOCK_STREAM, 0);
305         if (svr->fd < 0) goto error;
306         if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
307         if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
308         lin.l_onoff = 1;
309         lin.l_linger = 0;
310         if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) goto error;
311         socket_addr.sin_family = AF_INET;
312         socket_addr.sin_port = htons(port);
313         socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);
314         if (bind(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0) goto error;
315         if (listen(svr->fd, 4096) < 0) goto error;
316         svr->fd_handler = 
317           ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
318                                     _ecore_con_svr_handler, svr, NULL, NULL);
319         if (!svr->fd_handler) goto error;
320      }
321
322 #if USE_OPENSSL
323    if (compl_type & ECORE_CON_SSL)
324      {
325         if (!ssl_init_count)
326           {
327              SSL_library_init();
328              SSL_load_error_strings();
329           }
330         ssl_init_count++;
331
332         switch (compl_type & ECORE_CON_SSL)
333           {
334            case ECORE_CON_USE_SSL2:
335               if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
336                 goto error;
337               break;
338            case ECORE_CON_USE_SSL3:
339               if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
340                 goto error;
341               break;
342            case ECORE_CON_USE_TLS:
343               if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
344                 goto error;
345               break;
346           }
347
348         if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
349           goto error;
350
351         SSL_set_fd(svr->ssl, svr->fd);
352      }
353 #endif
354
355    svr->name = strdup(name);
356    if (!svr->name) goto error;
357    svr->type = type;
358    svr->port = port;
359    svr->data = (void *)data;
360    svr->created = 1;
361    svr->reject_excess_clients = 0;
362    svr->client_limit = -1;
363    svr->clients = ecore_list_new();
364    svr->ppid = getpid();
365    ecore_list_append(servers, svr);
366    ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
367    return svr;
368
369    error:
370    if (svr->name) free(svr->name);
371    if (svr->path) free(svr->path);
372    if (svr->fd >= 0) close(svr->fd);
373    if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
374    if (svr->write_buf) free(svr->write_buf);
375    if (svr->ip) free(svr->ip);
376 #if USE_OPENSSL
377    if (svr->ssl) SSL_free(svr->ssl);
378    if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
379 #endif
380    free(svr);
381    return NULL;
382 }
383
384 /**
385  * Creates a server object to represent the server listening at the
386  * given port.
387  *
388  * The socket to which the server connects depends on the connection type:
389  * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the function will
390  *     connect to the server listening on the Unix socket
391  *     "~/.ecore/[name]/[port]".
392  * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the function will
393  *     connect to the server listening on the Unix socket
394  *     "/tmp/.ecore_service|[name]|[port]".
395  * @li If @a compl_type is @c ECORE_CON_REMOTE_SYSTEM, the function will
396  *     connect to the server listening on the TCP port "[name]:[port]".
397  *
398  * @param  compl_type The connection type.
399  * @param  name       Name used when determining what socket to connect to.
400  *                    It is used to generate the socket name when the socket
401  *                    is a Unix socket.  It is used as the hostname when
402  *                    connecting with a TCP socket.
403  * @param  port       Number to identify the socket to connect to.  Used when
404  *                    generating the socket name for a Unix socket, or as the
405  *                    TCP port when connecting to a TCP socket.
406  * @param  data       Data to associate with the created Ecore_Con_Server
407  *                    object.
408  * @return A new Ecore_Con_Server.
409  * @ingroup Ecore_Con_Server_Group
410  */
411 EAPI Ecore_Con_Server *
412 ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port,
413                          const void *data)
414 {
415    Ecore_Con_Server   *svr;
416    Ecore_Con_Type      type;
417    struct sockaddr_un  socket_unix;
418    int                 curstate = 0;
419    char                buf[4096];
420
421    if (!name) return NULL;
422    /* local  user   socket: FILE:   ~/.ecore/[name]/[port] */
423    /* local  system socket: FILE:   /tmp/.ecore_service|[name]|[port] */
424    /* remote system socket: TCP/IP: [name]:[port] */
425    svr = calloc(1, sizeof(Ecore_Con_Server));
426    if (!svr) return NULL;
427
428    type = compl_type;
429 #if USE_OPENSSL
430    /* unset the SSL flag for the following checks */
431    type &= ECORE_CON_TYPE;
432 #endif
433    if ((type == ECORE_CON_REMOTE_SYSTEM) && (port < 0)) return NULL;
434
435    if ((type == ECORE_CON_LOCAL_USER) || (type == ECORE_CON_LOCAL_SYSTEM) ||
436        (type == ECORE_CON_LOCAL_ABSTRACT))
437      {
438         const char *homedir;
439         int socket_unix_len;
440
441         if (type == ECORE_CON_LOCAL_USER)
442           {
443              homedir = getenv("HOME");
444              if (!homedir) homedir = getenv("TMP");
445              if (!homedir) homedir = "/tmp";
446              snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, name, port);
447           }
448         else if (type == ECORE_CON_LOCAL_SYSTEM)
449           {
450              if (port < 0)
451                {
452                   if (name[0] == '/')
453                     strncpy(buf, name, sizeof(buf));
454                   else
455                     snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s", name);
456                }
457              else
458                {
459                   if (name[0] == '/')
460                     snprintf(buf, sizeof(buf), "%s|%i", name, port);
461                   else
462                     snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", name, port);
463                }
464           }
465         else if (type == ECORE_CON_LOCAL_ABSTRACT)
466           strncpy(buf, name, sizeof(buf));
467
468         svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
469         if (svr->fd < 0) goto error;
470         if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
471         if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
472         if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error;
473         socket_unix.sun_family = AF_UNIX;
474
475         if (type == ECORE_CON_LOCAL_ABSTRACT)
476           {
477 #ifdef HAVE_ABSTRACT_SOCKETS
478              /* copy name insto sun_path, prefixed by null to indicate abstract namespace */
479              snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s", name);
480              socket_unix.sun_path[0] = '\0';
481              socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, name);
482 #else
483              fprintf(stderr, "Your system does not support abstract sockets!\n");
484              goto error;
485 #endif
486           }
487         else
488           {
489              strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
490              socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
491           }
492
493         if (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) goto error;
494         svr->path = strdup(buf);
495         if (!svr->path) goto error;
496         svr->fd_handler = 
497           ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
498                                     _ecore_con_cl_handler, svr, NULL, NULL);
499         if (!svr->fd_handler) goto error;
500
501         if (!svr->delete_me)
502           {
503              /* we got our server! */
504              Ecore_Con_Event_Server_Add *e;
505
506              e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
507              if (e)
508                {
509                   svr->event_count++;
510                   e->server = svr;
511                   ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e,
512                                   _ecore_con_event_server_add_free, NULL);
513                }
514           }
515      }
516
517    svr->name = strdup(name);
518    if (!svr->name) goto error;
519    svr->type = compl_type;
520    svr->port = port;
521    svr->data = (void *)data;
522    svr->created = 0;
523    svr->reject_excess_clients = 0;
524    svr->client_limit = -1;
525    svr->clients = ecore_list_new();
526    ecore_list_append(servers, svr);
527    ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
528
529    if (type == ECORE_CON_REMOTE_SYSTEM)
530      {
531         if (!ecore_con_dns_lookup(svr->name, _ecore_con_cb_dns_lookup, svr))
532           goto error;
533      }
534
535    return svr;
536
537    error:
538    if (svr->name) free(svr->name);
539    if (svr->path) free(svr->path);
540    if (svr->fd >= 0) close(svr->fd);
541    if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
542 #if USE_OPENSSL
543    if (svr->ssl) SSL_free(svr->ssl);
544    if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
545 #endif
546    free(svr);
547    return NULL;
548 }
549
550 /**
551  * Closes the connection and frees the given server.
552  * @param   svr The given server.
553  * @return  Data associated with the server when it was created.
554  * @ingroup Ecore_Con_Server_Group
555  */
556 EAPI void *
557 ecore_con_server_del(Ecore_Con_Server *svr)
558 {
559    void *data;
560
561    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
562      {
563         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del");
564         return NULL;
565      }
566    data = svr->data;
567    svr->data = NULL;
568    svr->delete_me = 1;
569    if (svr->event_count > 0)
570      {
571         if (svr->fd_handler)
572           {
573              ecore_main_fd_handler_del(svr->fd_handler);
574              svr->fd_handler = NULL;
575           }
576      }
577    else
578      {
579         _ecore_con_server_free(svr);
580         if (ecore_list_goto(servers, svr)) ecore_list_remove(servers);
581      }
582    return data;
583 }
584
585 /**
586  * Retrieves the data associated with the given server.
587  * @param   svr The given server.
588  * @return  The associated data.
589  * @ingroup Ecore_Con_Server_Group
590  */
591 EAPI void *
592 ecore_con_server_data_get(Ecore_Con_Server *svr)
593 {
594    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
595      {
596         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get");
597         return NULL;
598      }
599    return svr->data;
600 }
601
602 /**
603  * Retrieves whether the given server is currently connected.
604  * @todo Check that this function does what the documenter believes it does.
605  * @param   svr The given server.
606  * @return  @c 1 if the server is connected.  @c 0 otherwise.
607  * @ingroup Ecore_Con_Server_Group
608  */
609 EAPI int
610 ecore_con_server_connected_get(Ecore_Con_Server *svr)
611 {
612    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
613      {
614         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_connected_get");
615         return 0;
616      }
617    if (svr->connecting) return 0;
618    return 1;
619 }
620
621 /**
622  * Retrieves the current list of clients.
623  * @param   svr The given server.
624  * @return  The list of clients on this server.
625  * @ingroup Ecore_Con_Server_Group
626  */
627 EAPI Ecore_List *
628 ecore_con_server_clients_get(Ecore_Con_Server *svr)
629 {
630    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
631      {
632         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_clients_get");
633         return NULL;
634      }
635    return svr->clients;
636 }
637
638 /**
639  * Sends the given data to the given server.
640  * @param   svr  The given server.
641  * @param   data The given data.
642  * @param   size Length of the data, in bytes, to send.
643  * @return  The number of bytes sent.  @c 0 will be returned if there is an
644  *          error.
645  * @ingroup Ecore_Con_Server_Group
646  */
647 EAPI int
648 ecore_con_server_send(Ecore_Con_Server *svr, const void *data, int size)
649 {
650    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
651      {
652         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_send");
653         return 0;
654      }
655    if (svr->dead) return 0;
656    if (!data) return 0;
657    if (size < 1) return 0;
658    if (svr->fd_handler)
659      ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
660    if (svr->write_buf)
661      {
662         unsigned char *newbuf;
663
664         newbuf = realloc(svr->write_buf, svr->write_buf_size + size);
665         if (newbuf) svr->write_buf = newbuf;
666         else return 0;
667         memcpy(svr->write_buf + svr->write_buf_size, data, size);
668         svr->write_buf_size += size;
669      }
670    else
671      {
672         svr->write_buf = malloc(size);
673         if (!svr->write_buf) return 0;
674         svr->write_buf_size = size;
675         memcpy(svr->write_buf, data, size);
676      }
677    return size;
678 }
679
680 /**
681  * Sets a limit on the number of clients that can be handled concurrently
682  * by the given server, and a policy on what to do if excess clients try to
683  * connect.
684  * Beware that if you set this once ecore is already running, you may
685  * already have pending CLIENT_ADD events in your event queue.  Those
686  * clients have already connected and will not be affected by this call.
687  * Only clients subsequently trying to connect will be affected.
688  * @param   svr           The given server.
689  * @param   client_limit  The maximum number of clients to handle
690  *                        concurrently.  -1 means unlimited (default).  0
691  *                        effectively disables the server.
692  * @param   reject_excess_clients  Set to 1 to automatically disconnect
693  *                        excess clients as soon as they connect if you are
694  *                        already handling client_limit clients.  Set to 0
695  *                        (default) to just hold off on the "accept()"
696  *                        system call until the number of active clients
697  *                        drops. This causes the kernel to queue up to 4096
698  *                        connections (or your kernel's limit, whichever is
699  *                        lower).
700  * @ingroup Ecore_Con_Server_Group
701  */
702 EAPI void
703 ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients)
704 {
705    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
706      {
707         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_client_limit_set");
708         return;
709      }
710    svr->client_limit = client_limit;
711    svr->reject_excess_clients = reject_excess_clients;
712 }
713
714 /**
715  * Gets the IP address of a server that has been connected to.
716  *
717  * @param   svr           The given server.
718  * @return  A pointer to an internal string that contains the IP address of
719  *          the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
720  *          This string should not be modified or trusted to stay valid after
721  *          deletion for the @p svr object. If no IP is known NULL is returned.
722  * @ingroup Ecore_Con_Server_Group
723  */
724 EAPI char *
725 ecore_con_server_ip_get(Ecore_Con_Server *svr)
726 {
727    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
728      {
729         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_ip_get");
730         return NULL;
731      }
732    return svr->ip;
733 }
734
735 /**
736  * Flushes all pending data to the given server. Will return when done.
737  *
738  * @param   svr           The given server.
739  * @ingroup Ecore_Con_Server_Group
740  */
741 EAPI void
742 ecore_con_server_flush(Ecore_Con_Server *svr)
743 {
744    if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
745      {
746         ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_flush");
747         return;
748      }
749    _ecore_con_server_flush(svr);
750 }
751
752 /**
753  * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions
754  *
755  * Functions that operate on Ecore connection client objects.
756  */
757
758 /**
759  * Sends the given data to the given client.
760  * @param   cl   The given client.
761  * @param   data The given data.
762  * @param   size Length of the data, in bytes, to send.
763  * @return  The number of bytes sent.  @c 0 will be returned if there is an
764  *          error.
765  * @ingroup Ecore_Con_Client_Group
766  */
767 EAPI int
768 ecore_con_client_send(Ecore_Con_Client *cl, const void *data, int size)
769 {
770    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
771      {
772         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_send");
773         return 0;
774      }
775    if (cl->dead) return 0;
776    if (!data) return 0;
777    if (size < 1) return 0;
778    if (cl->fd_handler)
779      ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
780    if (cl->buf)
781      {
782         unsigned char *newbuf;
783
784         newbuf = realloc(cl->buf, cl->buf_size + size);
785         if (newbuf) cl->buf = newbuf;
786         else return 0;
787         memcpy(cl->buf + cl->buf_size, data, size);
788         cl->buf_size += size;
789      }
790    else
791      {
792         cl->buf = malloc(size);
793         if (!cl->buf) return 0;
794         cl->buf_size = size;
795         memcpy(cl->buf, data, size);
796      }
797    return size;
798 }
799
800 /**
801  * Retrieves the server representing the socket the client has
802  * connected to.
803  * @param   cl The given client.
804  * @return  The server that the client connected to.
805  * @ingroup Ecore_Con_Client_Group
806  */
807 EAPI Ecore_Con_Server *
808 ecore_con_client_server_get(Ecore_Con_Client *cl)
809 {
810    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
811      {
812         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_server_get");
813         return NULL;
814      }
815    return cl->server;
816 }
817
818 /**
819  * Closes the connection and frees memory allocated to the given client.
820  * @param   cl The given client.
821  * @return  Data associated with the client.
822  * @ingroup Ecore_Con_Client_Group
823  */
824 EAPI void *
825 ecore_con_client_del(Ecore_Con_Client *cl)
826 {
827    void *data;
828
829    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
830      {
831         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del");
832         return NULL;
833      }
834    data = cl->data;
835    cl->data = NULL;
836    cl->delete_me = 1;
837    if (cl->event_count > 0)
838      {
839         if (cl->fd_handler)
840           {
841              ecore_main_fd_handler_del(cl->fd_handler);
842              cl->fd_handler = NULL;
843           }
844      }
845    else
846      {
847         if (ecore_list_goto(cl->server->clients, cl))
848           ecore_list_remove(cl->server->clients);
849         _ecore_con_client_free(cl);
850      }
851    return data;
852 }
853
854 /**
855  * Sets the data associated with the given client to @p data.
856  * @param   cl   The given client.
857  * @param   data What to set the data to.
858  * @ingroup Ecore_Con_Client_Group
859  */
860 EAPI void
861 ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data)
862 {
863    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
864      {
865         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_set");
866         return;
867      }
868    cl->data = (void *)data;
869 }
870
871 /**
872  * Retrieves the data associated with the given client.
873  * @param   cl The given client.
874  * @return  The data associated with @p cl.
875  * @ingroup Ecore_Con_Client_Group
876  */
877 EAPI void *
878 ecore_con_client_data_get(Ecore_Con_Client *cl)
879 {
880    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
881      {
882         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_get");
883         return NULL;
884      }
885    return cl->data;
886 }
887
888 /**
889  * Gets the IP address of a cleint that has connected.
890  *
891  * @param   cl            The given client.
892  * @return  A pointer to an internal string that contains the IP address of
893  *          the connected client in the form "XXX.YYY.ZZZ.AAA" IP notation.
894  *          This string should not be modified or trusted to stay valid after
895  *          deletion for the @p cl object. If no IP is known NULL is returned.
896  * @ingroup Ecore_Con_Client_Group
897  */
898 EAPI char *
899 ecore_con_client_ip_get(Ecore_Con_Client *cl)
900 {
901    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
902      {
903         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_ip_get");
904         return NULL;
905      }
906    return cl->ip;
907 }
908
909 /**
910  * Flushes all pending data to the given client. Will return when done.
911  *
912  * @param   cl            The given client.
913  * @ingroup Ecore_Con_Client_Group
914  */
915 EAPI void
916 ecore_con_client_flush(Ecore_Con_Client *cl)
917 {
918    if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
919      {
920         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_flush");
921         return;
922      }
923    _ecore_con_client_flush(cl);
924 }
925
926 /**
927  * Returns if SSL support is available
928  * @return  1 if SSL is available, 0 if it is not.
929  * @ingroup Ecore_Con_Client_Group
930  */
931 EAPI int
932 ecore_con_ssl_available_get(void)
933 {
934 #if USE_OPENSSL
935    return 1;
936 #else
937    return 0;
938 #endif
939 }
940
941 static void
942 _ecore_con_server_free(Ecore_Con_Server *svr)
943 {
944    double t_start, t;
945
946    ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
947    t_start = ecore_time_get();
948    while ((svr->write_buf) && (!svr->dead))
949      {
950         _ecore_con_server_flush(svr);
951         t = ecore_time_get();
952         if ((t - t_start) > 0.5)
953           {
954              printf("ECORE_CON: EEK - stuck in _ecore_con_server_free() trying\n"
955                     "  to flush data out from the server, and have been for\n"
956                     "  %1.1f seconds. This is taking too long. Aborting flush.\n",
957                     (t - t_start));
958              break;
959           }
960      }
961    if (svr->write_buf) free(svr->write_buf);
962    while (!ecore_list_empty_is(svr->clients))
963      _ecore_con_client_free(ecore_list_first_remove(svr->clients));
964    ecore_list_destroy(svr->clients);
965    if ((svr->created) && (svr->path) && (svr->ppid == getpid())) 
966      unlink(svr->path);
967    if (svr->fd >= 0) close(svr->fd);
968 #if USE_OPENSSL
969    if (svr->ssl)
970      {
971         SSL_shutdown(svr->ssl);
972         SSL_free(svr->ssl);
973      }
974    if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
975 #endif
976    if (svr->name) free(svr->name);
977    if (svr->path) free(svr->path);
978    if (svr->ip) free(svr->ip);
979    if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
980    free(svr);
981 }
982
983 static void
984 _ecore_con_client_free(Ecore_Con_Client *cl)
985 {
986    double t_start, t;
987
988    ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
989    t_start = ecore_time_get();
990    while ((cl->buf) && (!cl->dead))
991      {
992         _ecore_con_client_flush(cl);
993         t = ecore_time_get();
994         if ((t - t_start) > 0.5)
995           {
996              printf("ECORE_CON: EEK - stuck in _ecore_con_client_free() trying\n"
997                     "  to flush data out from the client, and have been for\n"
998                     "  %1.1f seconds. This is taking too long. Aborting flush.\n",
999                     (t - t_start));
1000              break;
1001           }
1002      }
1003    if (cl->buf) free(cl->buf);
1004    if (cl->fd >= 0) close(cl->fd);
1005    if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler);
1006    if (cl->ip) free(cl->ip);
1007    free(cl);
1008 }
1009
1010 static int
1011 _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
1012 {
1013    Ecore_Con_Server   *svr;
1014    int                 new_fd;
1015    struct sockaddr_in  incoming;
1016    size_t              size_in;
1017
1018    svr = data;
1019    if (svr->dead) return 1;
1020    if (svr->delete_me) return 1;
1021    if ((svr->client_limit >= 0) && (!svr->reject_excess_clients))
1022      {
1023         if (ecore_list_count(svr->clients) >= svr->client_limit) return 1;
1024      }
1025    /* a new client */
1026    size_in = sizeof(struct sockaddr_in);
1027    new_fd = accept(svr->fd, (struct sockaddr *)&incoming, (socklen_t *)&size_in);
1028    if (new_fd >= 0)
1029      {
1030         Ecore_Con_Client *cl;
1031         char buf[64];
1032         uint32_t ip;
1033
1034         if ((svr->client_limit >= 0) && (svr->reject_excess_clients))
1035           {
1036              close(new_fd);
1037              return 1;
1038           }
1039
1040         cl = calloc(1, sizeof(Ecore_Con_Client));
1041         if (!cl)
1042           {
1043              close(new_fd);
1044              return 1;
1045           }
1046         fcntl(new_fd, F_SETFL, O_NONBLOCK);
1047         fcntl(new_fd, F_SETFD, FD_CLOEXEC);
1048         cl->fd = new_fd;
1049         cl->server = svr;
1050         cl->fd_handler = 
1051           ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
1052                                     _ecore_con_svr_cl_handler, cl, NULL, NULL);
1053         ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
1054         ecore_list_append(svr->clients, cl);
1055         if (!svr->path)
1056           {
1057              ip = incoming.sin_addr.s_addr;
1058              snprintf(buf, sizeof(buf),
1059                       "%i.%i.%i.%i",
1060                       (ip      ) & 0xff,
1061                       (ip >> 8 ) & 0xff,
1062                       (ip >> 16) & 0xff,
1063                       (ip >> 24) & 0xff);
1064              cl->ip = strdup(buf);
1065           }
1066         if (!cl->delete_me)
1067           {
1068              Ecore_Con_Event_Client_Add *e;
1069
1070              e = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
1071              if (e)
1072                {
1073                   cl->event_count++;
1074                   e->client = cl;
1075                   ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, e,
1076                                   _ecore_con_event_client_add_free, NULL);
1077                }
1078           }
1079      }
1080    return 1;
1081 }
1082
1083 #if USE_OPENSSL
1084 /* Tries to connect an Ecore_Con_Server to an SSL host.
1085  * Returns 1 on success, -1 on fatal errors and 0 if the caller
1086  * should try again later.
1087  */
1088 static int
1089 svr_try_connect_ssl(Ecore_Con_Server *svr)
1090 {
1091    int res, ssl_err, flag = 0;
1092
1093    if (!ssl_init_count)
1094      {
1095         SSL_library_init();
1096         SSL_load_error_strings();
1097      }
1098    ssl_init_count++;
1099
1100    res = SSL_connect(svr->ssl);
1101    if (res == 1) return 1;
1102    ssl_err = SSL_get_error(svr->ssl, res);
1103
1104    if (ssl_err == SSL_ERROR_NONE) return 1;
1105    if (ssl_err == SSL_ERROR_WANT_READ)       flag = ECORE_FD_READ;
1106    else if (ssl_err == SSL_ERROR_WANT_WRITE) flag = ECORE_FD_WRITE;
1107    else return -1;
1108    if (svr->fd_handler)
1109      {
1110         if (flag) ecore_main_fd_handler_active_set(svr->fd_handler, flag);
1111      }
1112    return 0;
1113 }
1114 #endif
1115
1116 static void
1117 kill_server(Ecore_Con_Server *svr)
1118 {
1119    if (!svr->delete_me)
1120      {
1121         Ecore_Con_Event_Server_Del *e;
1122
1123         e = calloc(1, sizeof(Ecore_Con_Event_Server_Del));
1124         if (e)
1125           {
1126              svr->event_count++;
1127              e->server = svr;
1128              ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e,
1129                              _ecore_con_event_server_del_free, NULL);
1130           }
1131      }
1132
1133    svr->dead = 1;
1134    if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
1135    svr->fd_handler = NULL;
1136 }
1137
1138 static void
1139 _ecore_con_cb_dns_lookup(void *data, struct hostent *he)
1140 {
1141    Ecore_Con_Server   *svr;
1142    struct sockaddr_in  socket_addr;
1143    int                 curstate = 0;
1144    char                buf[64];
1145    uint32_t            ip;
1146
1147    svr = data;
1148
1149    if (!he) goto error;
1150    svr->fd = socket(AF_INET, SOCK_STREAM, 0);
1151    if (svr->fd < 0) goto error;
1152    if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1153    if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1154    if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) 
1155      goto error;
1156    socket_addr.sin_family = AF_INET;
1157    socket_addr.sin_port = htons(svr->port);
1158    memcpy((struct in_addr *)&socket_addr.sin_addr,
1159           he->h_addr, sizeof(struct in_addr));
1160    if (connect(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0)
1161      {
1162         if (errno != EINPROGRESS)
1163           goto error;
1164         svr->connecting = 1;
1165         svr->fd_handler = 
1166           ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
1167                                     _ecore_con_cl_handler, svr, NULL, NULL);
1168      }
1169    else
1170      svr->fd_handler = 
1171      ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1172                                _ecore_con_cl_handler, svr, NULL, NULL);
1173
1174    if (!svr->fd_handler) goto error;
1175    ip = socket_addr.sin_addr.s_addr;
1176    snprintf(buf, sizeof(buf),
1177             "%i.%i.%i.%i",
1178             (ip      ) & 0xff,
1179             (ip >> 8 ) & 0xff,
1180             (ip >> 16) & 0xff,
1181             (ip >> 24) & 0xff);
1182    svr->ip = strdup(buf);
1183
1184 #if USE_OPENSSL
1185    if (svr->type & ECORE_CON_SSL)
1186      {
1187         if (!ssl_init_count)
1188           {
1189              SSL_library_init();
1190              SSL_load_error_strings();
1191           }
1192         ssl_init_count++;
1193
1194         switch (svr->type & ECORE_CON_SSL)
1195           {
1196            case ECORE_CON_USE_SSL2:
1197               if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
1198                 goto error;
1199               break;
1200            case ECORE_CON_USE_SSL3:
1201               if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
1202                 goto error;
1203               break;
1204            case ECORE_CON_USE_TLS:
1205               if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
1206                 goto error;
1207               break;
1208           }
1209
1210         if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
1211           goto error;
1212
1213         SSL_set_fd(svr->ssl, svr->fd);
1214      }
1215 #endif
1216
1217    return;
1218
1219    error:
1220    kill_server(svr);
1221 }
1222
1223 static int
1224 svr_try_connect_plain(Ecore_Con_Server *svr)
1225 {
1226    int so_err = 0;
1227    unsigned int size = sizeof(int);
1228
1229    if (getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, &so_err, &size) < 0)
1230      so_err = -1;
1231
1232    if (so_err != 0)
1233      {
1234         /* we lost our server! */
1235         kill_server(svr);
1236      }
1237    else
1238      {
1239         if (!svr->delete_me)
1240           {
1241              /* we got our server! */
1242              Ecore_Con_Event_Server_Add *e;
1243
1244              svr->connecting = 0;
1245              e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
1246              if (e)
1247                {
1248                   svr->event_count++;
1249                   e->server = svr;
1250                   ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e,
1251                                   _ecore_con_event_server_add_free, NULL);
1252                }
1253           }
1254         if (svr->fd_handler)
1255           {
1256              if (!svr->write_buf)
1257                ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1258           }
1259      }
1260    return (!svr->dead);
1261 }
1262
1263 /* returns 1 on success, 0 on failure */
1264 static int svr_try_connect(Ecore_Con_Server *svr)
1265 {
1266 #if USE_OPENSSL
1267    if (!svr->ssl)
1268      {
1269 #endif
1270         return svr_try_connect_plain(svr);
1271 #if USE_OPENSSL
1272      }
1273    else
1274      switch (svr_try_connect_ssl(svr)) {
1275       case 1:
1276         return svr_try_connect_plain(svr);
1277       case -1:
1278         kill_server(svr);
1279         return 0;
1280       default:
1281         return 0;
1282      }
1283 #endif
1284 }
1285
1286
1287 static int
1288 _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
1289 {
1290    Ecore_Con_Server   *svr;
1291 #if USE_OPENSSL
1292    int ssl_err = SSL_ERROR_NONE;
1293 #endif
1294
1295    svr = data;
1296    if (svr->dead) return 1;
1297    if (svr->delete_me) return 1;
1298    if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
1299      {
1300         unsigned char *inbuf = NULL;
1301         int            inbuf_num = 0;
1302
1303         if (svr->connecting && !svr_try_connect(svr))
1304            return 1;
1305
1306         for (;;)
1307           {
1308              int num, lost_server;
1309              char buf[READBUFSIZ];
1310
1311              lost_server = 0;
1312 #if USE_OPENSSL
1313              if (!svr->ssl)
1314                {
1315 #endif
1316                   if ((num = read(svr->fd, buf, READBUFSIZ)) < 1)
1317                     {
1318                        lost_server = ((errno == EIO) ||
1319                                       (errno == EBADF) ||
1320                                       (errno == EPIPE) ||
1321                                       (errno == EINVAL) ||
1322                                       (errno == ENOSPC) ||
1323                                       (num == 0));
1324                        /* is num == 0 is right - when the server closes us
1325                         * off we will get this (as this is called when select
1326                         * tells us there is data to read!)
1327                         */
1328                     }
1329 #if USE_OPENSSL
1330                }
1331              else
1332                {
1333                   num = SSL_read(svr->ssl, buf, READBUFSIZ);
1334                   if (num < 1)
1335                     {
1336                        ssl_err = SSL_get_error(svr->ssl, num);
1337                        lost_server = (ssl_err == SSL_ERROR_ZERO_RETURN);
1338                        if (ssl_err == SSL_ERROR_SYSCALL)
1339                          {
1340                             if (num == 0) lost_server = 1;
1341                             else
1342                               {
1343                                  lost_server = ((errno == EIO) ||
1344                                                 (errno == EBADF) ||
1345                                                 (errno == EPIPE) ||
1346                                                 (errno == EINVAL) ||
1347                                                 (errno == ENOSPC) ||
1348                                                 (errno == ECONNRESET));
1349                               }
1350                          }
1351                     }
1352                   else
1353                     ssl_err = SSL_ERROR_NONE;
1354                }
1355 #endif
1356              if (num < 1)
1357                {
1358                   if (inbuf)
1359                     {
1360                        if (!svr->delete_me)
1361                          {
1362                             Ecore_Con_Event_Server_Data *e;
1363
1364                             e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
1365                             if (e)
1366                               {
1367                                  svr->event_count++;
1368                                  e->server = svr;
1369                                  e->data = inbuf;
1370                                  e->size = inbuf_num;
1371                                  ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
1372                                                  _ecore_con_event_server_data_free,
1373                                                  NULL);
1374                               }
1375                          }
1376                     }
1377                   if (lost_server)
1378                     {
1379                        /* we lost our server! */
1380                        kill_server(svr);
1381                        return 1;
1382                     }
1383                   break;
1384                }
1385              else
1386                {
1387                   inbuf = realloc(inbuf, inbuf_num + num);
1388                   memcpy(inbuf + inbuf_num, buf, num);
1389                   inbuf_num += num;
1390                }
1391           }
1392
1393 #if USE_OPENSSL
1394         if (svr->fd_handler)
1395           {
1396              if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ)
1397                ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1398              else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE)
1399                ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
1400           }
1401 #endif
1402      }
1403    else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
1404      {
1405         if (svr->connecting && !svr_try_connect (svr))
1406            return 1;
1407         _ecore_con_server_flush(svr);
1408      }
1409
1410    return 1;
1411 }
1412
1413 static int
1414 _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
1415 {
1416    Ecore_Con_Client   *cl;
1417
1418    cl = data;
1419    if (cl->dead) return 1;
1420    if (cl->delete_me) return 1;
1421    if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
1422      {
1423         unsigned char *inbuf = NULL;
1424         int            inbuf_num = 0;
1425
1426         for (;;)
1427           {
1428              char buf[65536];
1429              int num;
1430
1431              errno = 0;
1432              num = read(cl->fd, buf, 65536);
1433              if (num < 1)
1434                {
1435                   if (inbuf)
1436                     {
1437                        if (!cl->delete_me)
1438                          {
1439                             Ecore_Con_Event_Client_Data *e;
1440
1441                             e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
1442                             if (e)
1443                               {
1444                                  cl->event_count++;
1445                                  e->client = cl;
1446                                  e->data = inbuf;
1447                                  e->size = inbuf_num;
1448                                  ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
1449                                                  _ecore_con_event_client_data_free,
1450                                                  NULL);
1451                               }
1452                          }
1453                     }
1454                   if ((errno == EIO) ||  (errno == EBADF) ||
1455                       (errno == EPIPE) || (errno == EINVAL) ||
1456                       (errno == ENOSPC) || (num == 0)/* is num == 0 right? */)
1457                     {
1458                        if (!cl->delete_me)
1459                          {
1460                             /* we lost our client! */
1461                             Ecore_Con_Event_Client_Del *e;
1462
1463                             e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
1464                             if (e)
1465                               {
1466                                  cl->event_count++;
1467                                  e->client = cl;
1468                                  ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
1469                                                  _ecore_con_event_client_del_free,
1470                                                  NULL);
1471                               }
1472                          }
1473                        cl->dead = 1;
1474                        if (cl->fd_handler)
1475                          ecore_main_fd_handler_del(cl->fd_handler);
1476                        cl->fd_handler = NULL;
1477                     }
1478                   break;
1479                }
1480              else
1481                {
1482                   inbuf = realloc(inbuf, inbuf_num + num);
1483                   memcpy(inbuf + inbuf_num, buf, num);
1484                   inbuf_num += num;
1485                }
1486           }
1487      }
1488    else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
1489      _ecore_con_client_flush(cl);
1490    return 1;
1491 }
1492
1493 static void
1494 _ecore_con_server_flush(Ecore_Con_Server *svr)
1495 {
1496    int count, num, lost_server = 0;
1497 #if USE_OPENSSL
1498    int ssl_err = SSL_ERROR_NONE;
1499 #endif
1500
1501    if (!svr->write_buf) return;
1502
1503    /* check whether we need to write anything at all.
1504         * we must not write zero bytes with SSL_write() since it
1505         * causes undefined behaviour
1506         */
1507    if (svr->write_buf_size == svr->write_buf_offset)
1508       return;
1509
1510    num = svr->write_buf_size - svr->write_buf_offset;
1511 #if USE_OPENSSL
1512    if (!svr->ssl)
1513      {
1514 #endif
1515         count = write(svr->fd, svr->write_buf + svr->write_buf_offset, num);
1516         if (count < 1)
1517           lost_server = (errno == EIO || errno == EBADF ||
1518                          errno == EPIPE || errno == EINVAL || errno == ENOSPC);
1519 #if USE_OPENSSL
1520      }
1521    else
1522      {
1523         count = SSL_write(svr->ssl, svr->write_buf + svr->write_buf_offset, num);
1524
1525         if (count < 1)
1526           {
1527              ssl_err = SSL_get_error(svr->ssl, count);
1528              lost_server = (ssl_err == SSL_ERROR_ZERO_RETURN);
1529           }
1530      }
1531 #endif
1532
1533    if (lost_server)
1534      {
1535         /* we lost our server! */
1536         kill_server(svr);
1537         return;
1538      }
1539
1540    if (count < 1)
1541      {
1542 #if USE_OPENSSL
1543         if (svr->fd_handler)
1544           {
1545              if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ)
1546                ecore_main_fd_handler_active_set(svr->fd_handler,
1547                                                 ECORE_FD_READ);
1548              else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE)
1549                ecore_main_fd_handler_active_set(svr->fd_handler,
1550                                                 ECORE_FD_WRITE);
1551           }
1552 #endif
1553         return;
1554      }
1555
1556    svr->write_buf_offset += count;
1557    if (svr->write_buf_offset >= svr->write_buf_size)
1558      {
1559         svr->write_buf_size = 0;
1560         svr->write_buf_offset = 0;
1561         free(svr->write_buf);
1562         svr->write_buf = NULL;
1563         if (svr->fd_handler)
1564           ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1565      }
1566 }
1567
1568 static void
1569 _ecore_con_client_flush(Ecore_Con_Client *cl)
1570 {
1571    int count, num;
1572
1573    if (!cl->buf) return;
1574    num = cl->buf_size - cl->buf_offset;
1575    count = write(cl->fd, cl->buf + cl->buf_offset, num);
1576    if (count < 1)
1577      {
1578         if ((errno == EIO) || (errno == EBADF) || (errno == EPIPE) ||
1579             (errno == EINVAL) || (errno == ENOSPC))
1580           {
1581              if (!cl->delete_me)
1582                {
1583                   /* we lost our client! */
1584                   Ecore_Con_Event_Client_Del *e;
1585
1586                   e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
1587                   if (e)
1588                     {
1589                        cl->event_count++;
1590                        e->client = cl;
1591                        ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
1592                                        _ecore_con_event_client_del_free, NULL);
1593                     }
1594                   cl->dead = 1;
1595                   if (cl->fd_handler)
1596                     ecore_main_fd_handler_del(cl->fd_handler);
1597                   cl->fd_handler = NULL;
1598                }
1599           }
1600         return;
1601      }
1602    cl->buf_offset += count;
1603    if (cl->buf_offset >= cl->buf_size)
1604      {
1605         cl->buf_size = 0;
1606         cl->buf_offset = 0;
1607         free(cl->buf);
1608         cl->buf = NULL;
1609         if (cl->fd_handler)
1610           ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
1611      }
1612 }
1613
1614 static void
1615 _ecore_con_event_client_add_free(void *data __UNUSED__, void *ev)
1616 {
1617    Ecore_Con_Event_Client_Add *e;
1618
1619    e = ev;
1620    e->client->event_count--;
1621    if ((e->client->event_count == 0) && (e->client->delete_me))
1622      ecore_con_client_del(e->client);
1623    free(e);
1624 }
1625
1626 static void
1627 _ecore_con_event_client_del_free(void *data __UNUSED__, void *ev)
1628 {
1629    Ecore_Con_Event_Client_Del *e;
1630
1631    e = ev;
1632    e->client->event_count--;
1633    if ((e->client->event_count == 0) && (e->client->delete_me))
1634      ecore_con_client_del(e->client);
1635    free(e);
1636 }
1637
1638 static void
1639 _ecore_con_event_client_data_free(void *data __UNUSED__, void *ev)
1640 {
1641    Ecore_Con_Event_Client_Data *e;
1642
1643    e = ev;
1644    e->client->event_count--;
1645    if (e->data) free(e->data);
1646    if ((e->client->event_count == 0) && (e->client->delete_me))
1647      ecore_con_client_del(e->client);
1648    free(e);
1649 }
1650
1651 static void
1652 _ecore_con_event_server_add_free(void *data __UNUSED__, void *ev)
1653 {
1654    Ecore_Con_Event_Server_Add *e;
1655
1656    e = ev;
1657    e->server->event_count--;
1658    if ((e->server->event_count == 0) && (e->server->delete_me))
1659      ecore_con_server_del(e->server);
1660    free(e);
1661 }
1662
1663 static void
1664 _ecore_con_event_server_del_free(void *data __UNUSED__, void *ev)
1665 {
1666    Ecore_Con_Event_Server_Del *e;
1667
1668    e = ev;
1669    e->server->event_count--;
1670    if ((e->server->event_count == 0) && (e->server->delete_me))
1671      ecore_con_server_del(e->server);
1672    free(e);
1673 }
1674
1675 static void
1676 _ecore_con_event_server_data_free(void *data __UNUSED__, void *ev)
1677 {
1678    Ecore_Con_Event_Server_Data *e;
1679
1680    e = ev;
1681    e->server->event_count--;
1682    if (e->data) free(e->data);
1683    if ((e->server->event_count == 0) && (e->server->delete_me))
1684      ecore_con_server_del(e->server);
1685    free(e);
1686 }