static Eina_Bool _ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handler *wh) { Ecore_Con_Client *obj = data; Ecore_Con_Client_Data *cl = eo_data_scope_get(obj, ECORE_CON_CLIENT_CLASS); Ecore_Con_Server_Data *host_svr = eo_data_scope_get(cl->host_server, ECORE_CON_SERVER_CLASS); #if 0 char *msg; #endif if (!ResetEvent(host_svr->event_peek)) return ECORE_CALLBACK_RENEW; #if 0 msg = evil_last_error_get(); if (msg) { ecore_con_event_server_error(host_svr, msg); free(msg); } #endif _ecore_con_server_kill(cl->host_server); return ECORE_CALLBACK_CANCEL; ecore_main_win32_handler_del(wh); return ECORE_CALLBACK_DONE; }
static Eina_Bool _ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handler *wh) { Ecore_Con_Client *cl; #if 0 char *msg; #endif cl = (Ecore_Con_Client *)data; if (!ResetEvent(cl->host_server->event_peek)) return ECORE_CALLBACK_RENEW; #if 0 msg = evil_last_error_get(); if (msg) { ecore_con_event_server_error(cl->host_server, msg); free(msg); } #endif if (!cl->host_server->delete_me) ecore_con_event_server_del(cl->host_server); cl->host_server->dead = EINA_TRUE; return ECORE_CALLBACK_CANCEL; ecore_main_win32_handler_del(wh); return ECORE_CALLBACK_DONE; }
static Eina_Bool _ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handler *wh) { Ecore_Con_Server *svr; void *buf; DWORD n; Eina_Bool broken_pipe = EINA_FALSE; svr = (Ecore_Con_Server *)data; if (!ResetEvent(svr->event_read)) return ECORE_CALLBACK_RENEW; buf = malloc(svr->nbr_bytes); if (!buf) return ECORE_CALLBACK_RENEW; if (ReadFile(svr->pipe, buf, svr->nbr_bytes, &n, NULL)) { if (!svr->delete_me) ecore_con_event_server_data(svr, buf, svr->nbr_bytes, EINA_FALSE); svr->want_write = 1; } else { if (GetLastError() == ERROR_BROKEN_PIPE) broken_pipe = EINA_TRUE; } if (broken_pipe) { #if 0 char *msg; msg = evil_last_error_get(); if (msg) { ecore_con_event_server_error(svr, msg); free(msg); } #endif if (!svr->delete_me) ecore_con_event_server_del(svr); svr->dead = EINA_TRUE; return ECORE_CALLBACK_CANCEL; } if (svr->want_write) ecore_con_local_win32_server_flush(svr); ecore_main_win32_handler_del(wh); return ECORE_CALLBACK_DONE; }
Eina_Bool ecore_con_local_win32_server_flush(Ecore_Con_Server *svr) { int num; BOOL res; DWORD written; /* This check should never be true */ if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) return EINA_TRUE; if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) return EINA_FALSE; num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset; if (num <= 0) return EINA_TRUE; res = WriteFile(svr->pipe, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num, &written, NULL); if (!res) { char *msg; msg = evil_last_error_get(); if (msg) { ecore_con_event_server_error(svr, msg); free(msg); } if (!svr->delete_me) ecore_con_event_server_del(svr); svr->dead = EINA_TRUE; } svr->write_buf_offset += written; if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf)) { svr->write_buf_offset = 0; eina_binbuf_free(svr->buf); svr->buf = NULL; svr->want_write = 0; } else if (written < (DWORD)num) svr->want_write = 1; return EINA_TRUE; }
static Eina_Bool _ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handler *wh) { Ecore_Con_Server *obj = data; Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS); void *buf; DWORD n; Eina_Bool broken_pipe = EINA_FALSE; if (!ResetEvent(svr->event_read)) return ECORE_CALLBACK_RENEW; buf = malloc(svr->nbr_bytes); if (!buf) return ECORE_CALLBACK_RENEW; if (ReadFile(svr->pipe, buf, svr->nbr_bytes, &n, NULL)) { if (!svr->delete_me) ecore_con_event_server_data(obj, buf, svr->nbr_bytes, EINA_FALSE); svr->want_write = 1; } else { if (GetLastError() == ERROR_BROKEN_PIPE) broken_pipe = EINA_TRUE; } if (broken_pipe) { #if 0 ecore_con_event_server_error(svr, evil_last_error_get()); #endif _ecore_con_server_kill(obj); return ECORE_CALLBACK_CANCEL; } if (svr->want_write) ecore_con_local_win32_server_flush(obj); ecore_main_win32_handler_del(wh); return ECORE_CALLBACK_DONE; }
static Eina_Bool _ecore_con_local_win32_client_peek_server_handler(void *data, Ecore_Win32_Handler *wh) { Ecore_Con_Server *obj = data; Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS); #if 0 char *msg; #endif if (!ResetEvent(svr->event_peek)) return ECORE_CALLBACK_RENEW; #if 0 ecore_con_event_server_error(svr, evil_last_error_get()); #endif _ecore_con_server_kill(obj); return ECORE_CALLBACK_CANCEL; ecore_main_win32_handler_del(wh); return ECORE_CALLBACK_DONE; }
Eina_Bool ecore_con_local_win32_server_flush(Ecore_Con_Server *obj) { Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS); size_t num; BOOL res; DWORD written; /* This check should never be true */ if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) return EINA_TRUE; if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) return EINA_FALSE; num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset; if (num == 0) return EINA_TRUE; res = WriteFile(svr->pipe, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num, &written, NULL); if (!res) { ecore_con_event_server_error(obj, evil_last_error_get()); _ecore_con_server_kill(obj); } svr->write_buf_offset += written; if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf)) { svr->write_buf_offset = 0; eina_binbuf_free(svr->buf); svr->buf = NULL; svr->want_write = 0; } else if (written < (DWORD)num) svr->want_write = 1; return EINA_TRUE; }
static Eina_Bool _ecore_con_socks_svr_init_v4(Ecore_Con_Server *svr, Ecore_Con_Socks_v4 *v4) { size_t addrlen, buflen, ulen = 1; unsigned char *sbuf; addrlen = v4->lookup ? strlen(svr->name) + 1 : 0; if (v4->username) ulen += v4->ulen; buflen = sizeof(char) * (8 + ulen + addrlen); sbuf = malloc(buflen); if (!sbuf) { ecore_con_event_server_error(svr, "Memory allocation failure!"); _ecore_con_server_kill(svr); return EINA_FALSE; } /* http://en.wikipedia.org/wiki/SOCKS */ sbuf[0] = 4; sbuf[1] = v4->bind ? 2 : 1; sbuf[2] = svr->port >> 8; sbuf[3] = svr->port & 0xff; if (addrlen) { sbuf[4] = sbuf[5] = sbuf[6] = 0; sbuf[7] = 1; } else /* SOCKSv4 only handles IPV4, so addrlen is always 4 */ memcpy(sbuf + 4, svr->ecs_addr, 4); if (v4->username) memcpy(sbuf + 8, v4->username, ulen); else sbuf[8] = 0; if (addrlen) memcpy(sbuf + 8 + ulen, svr->name, addrlen); svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen); return EINA_TRUE; }
static Eina_Bool _ecore_con_socks_svr_init_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5) { size_t buflen; unsigned int x; unsigned char *sbuf; if (v5->username) buflen = sizeof(char) * (2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS); else buflen = 3; sbuf = malloc(buflen); if (!sbuf) { ecore_con_event_server_error(svr, "Memory allocation failure!"); _ecore_con_server_kill(svr); return EINA_FALSE; } /* http://en.wikipedia.org/wiki/SOCKS * http://tools.ietf.org/html/rfc1928 */ sbuf[0] = 5; if (v5->username) { sbuf[1] = ECORE_CON_SOCKS_V5_TOTAL_METHODS; for (x = 2; x < 2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS; x++) sbuf[x] = ECORE_CON_SOCKS_V5_METHODS[x - 2]; } else { sbuf[1] = 1; sbuf[2] = ECORE_CON_SOCKS_V5_METHOD_NONE; } svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen); return EINA_TRUE; }
static void _ecore_con_info_readdata(CB_Data *cbdata) { Ecore_Con_Info container; Ecore_Con_Info *recv_info; unsigned char *torecv; int torecv_len; ssize_t size; size = read(ecore_main_fd_handler_fd_get(cbdata->fdh), &container, sizeof(Ecore_Con_Info)); if (size == sizeof(Ecore_Con_Info)) { torecv_len = container.size; torecv = malloc(torecv_len); memcpy(torecv, &container, sizeof(Ecore_Con_Info)); size = read(ecore_main_fd_handler_fd_get(cbdata->fdh), torecv + sizeof(Ecore_Con_Info), torecv_len - sizeof(Ecore_Con_Info)); if ((size > 0) && ((size_t)size == torecv_len - sizeof(Ecore_Con_Info))) { recv_info = (Ecore_Con_Info *)torecv; recv_info->info.ai_addr = (struct sockaddr *)(torecv + sizeof(Ecore_Con_Info)); if ((size_t)torecv_len != (sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen)) recv_info->info.ai_canonname = (char *) (torecv + sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen); else recv_info->info.ai_canonname = NULL; recv_info->info.ai_next = NULL; if (cbdata->data) { cbdata->cb_done(cbdata->data, recv_info); ecore_con_server_infos_del(cbdata->data, cbdata); } free(torecv); } else { if (cbdata->data) { cbdata->cb_done(cbdata->data, NULL); ecore_con_server_infos_del(cbdata->data, cbdata); } } } else { if (cbdata->data) { ecore_con_event_server_error(cbdata->data, strerror(errno)); cbdata->cb_done(cbdata->data, NULL); ecore_con_server_infos_del(cbdata->data, cbdata); } } cbdata->cb_done = NULL; }
EAPI int ecore_con_info_get(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data, struct addrinfo *hints) { CB_Data *cbdata; int fd[2]; if (pipe(fd) < 0) { ecore_con_event_server_error(svr, strerror(errno)); return 0; } _ecore_con_fd_close_on_exec(fd[0]); _ecore_con_fd_close_on_exec(fd[1]); cbdata = calloc(1, sizeof(CB_Data)); if (!cbdata) { close(fd[0]); close(fd[1]); return 0; } cbdata->cb_done = done_cb; cbdata->data = data; cbdata->fd2 = fd[1]; if (!(cbdata->fdh = ecore_main_fd_handler_add(fd[0], ECORE_FD_READ, _ecore_con_info_data_handler, cbdata, NULL, NULL))) { ecore_con_event_server_error(svr, "Memory allocation failure"); free(cbdata); close(fd[0]); close(fd[1]); return 0; } if ((cbdata->pid = fork()) == 0) { Ecore_Con_Info *container; struct addrinfo *result = NULL; char service[NI_MAXSERV] = {0}; char hbuf[NI_MAXHOST] = {0}; char sbuf[NI_MAXSERV] = {0}; unsigned char *tosend = NULL; int tosend_len; int canonname_len = 0; eina_convert_itoa(svr->ecs ? svr->ecs->port : svr->port, service); /* CHILD */ if (!getaddrinfo(svr->ecs ? svr->ecs->ip : svr->name, service, hints, &result) && result) { if (result->ai_canonname) canonname_len = strlen(result->ai_canonname) + 1; tosend_len = sizeof(Ecore_Con_Info) + result->ai_addrlen + canonname_len; tosend = alloca(tosend_len); memset(tosend, 0, tosend_len); container = (Ecore_Con_Info *)tosend; container->size = tosend_len; memcpy(&container->info, result, sizeof(struct addrinfo)); memcpy(tosend + sizeof(Ecore_Con_Info), result->ai_addr, result->ai_addrlen); if (result->ai_canonname) /* FIXME: else... */ memcpy(tosend + sizeof(Ecore_Con_Info) + result->ai_addrlen, result->ai_canonname, canonname_len); if (!getnameinfo(result->ai_addr, result->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { memcpy(container->ip, hbuf, sizeof(container->ip)); memcpy(container->service, sbuf, sizeof(container->service)); } if (write(fd[1], tosend, tosend_len) < 0) perror("write"); } if (result) freeaddrinfo(result); if (write(fd[1], "", 1) < 0) perror("write"); close(fd[1]); #if defined(__USE_ISOC99) && !defined(__UCLIBC__) _Exit(0); #else _exit(0); #endif } /* PARENT */ cbdata->handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _ecore_con_info_exit_handler, cbdata); close(fd[1]); if (!cbdata->handler) { ecore_main_fd_handler_del(cbdata->fdh); free(cbdata); close(fd[0]); return 0; } info_slaves = (CB_Data *)eina_inlist_append(EINA_INLIST_GET( info_slaves), EINA_INLIST_GET(cbdata)); svr->infos = eina_list_append(svr->infos, cbdata); return 1; }