static void _efl_net_control_technology_property_set(Eo *o, Efl_Net_Control_Technology_Data *pd, const char *name, const char *signature, ...) { Eldbus_Message *msg; Eldbus_Message_Iter *msg_itr, *var; Eldbus_Pending *p; va_list ap; msg = eldbus_proxy_method_call_new(pd->proxy, "SetProperty"); EINA_SAFETY_ON_NULL_RETURN(msg); msg_itr = eldbus_message_iter_get(msg); EINA_SAFETY_ON_NULL_GOTO(msg_itr, error_send); eldbus_message_iter_basic_append(msg_itr, 's', name); var = eldbus_message_iter_container_new(msg_itr, 'v', signature); va_start(ap, signature); eldbus_message_iter_arguments_vappend(var, signature, ap); va_end(ap); eldbus_message_iter_container_close(msg_itr, var); p = eldbus_proxy_send(pd->proxy, msg, _efl_net_control_technology_property_set_cb, o, DEFAULT_TIMEOUT); EINA_SAFETY_ON_NULL_GOTO(p, error_send); pd->pending = eina_list_append(pd->pending, p); DBG("Setting property %s", name); return; error_send: eldbus_message_unref(msg); }
int main(void) { Eina_Benchmark *bmk = NULL; /*=== Init ===*/ estate_init(); _fsm = estate_fsm_bench_load(); EINA_SAFETY_ON_NULL_GOTO(_fsm, fail); bmk = eina_benchmark_new("perf", "run"); EINA_SAFETY_ON_NULL_GOTO(bmk, fail); /* Tests will fail on purpose (to test worst cases). They * generate errors in eina_log.*/ eina_log_domain_level_set("estate", EINA_LOG_LEVEL_CRITICAL); eina_benchmark_register(bmk, "simple", _simple_benchmark_cb, 1, 100, 1); eina_benchmark_register(bmk, "fail", _fail_benchmark_cb, 1, 100, 1); eina_benchmark_run(bmk); /*=== Shutdown ===*/ estate_machine_free(_fsm); eina_benchmark_free(bmk); estate_shutdown(); return 0; fail: estate_machine_free(_fsm); eina_benchmark_free(bmk); estate_shutdown(); return 1; }
Eina_Bool alert_command_run(void *data) { Module_Alert_Command *mac = data; #define _EV(_a, _b, _c, _d) _a = ecore_event_handler_add(ECORE_EXE_EVENT_##_b, _c, _d) _EV(mac->ev.data, DATA, _alert_command_data, mac); EINA_SAFETY_ON_NULL_RETURN_VAL(mac->ev.data, EINA_TRUE); _EV(mac->ev.del, DEL, _alert_command_del, mac); EINA_SAFETY_ON_NULL_GOTO(mac->ev.del, del_data); _EV(mac->ev.error, ERROR, _alert_command_error, mac); EINA_SAFETY_ON_NULL_GOTO(mac->ev.error, del_del); #undef _EV mac->buf = eina_strbuf_new(); EINA_SAFETY_ON_NULL_GOTO(mac->buf, del_error); mac->exe = ecore_exe_pipe_run(mac->command->command, ECORE_EXE_PIPE_READ, mac); EINA_SAFETY_ON_NULL_GOTO(mac->exe, free_buf); ecore_exe_data_set(mac->exe, mac); return EINA_TRUE; free_buf: eina_strbuf_free(mac->buf); del_error: ecore_event_handler_del(mac->ev.error); del_del: ecore_event_handler_del(mac->ev.del); del_data: ecore_event_handler_del(mac->ev.data); return EINA_TRUE; }
Eina_Bool esql_reconnect_handler(Esql *e) { Esql *ev; int ret, fd; ev = e->pool_member ? (Esql *)e->pool_struct : e; /* use pool struct for events */ e->reconnect_timer = NULL; ret = e->backend.connect(e); EINA_SAFETY_ON_NULL_GOTO(e->backend.db, error); if (ret == ECORE_FD_ERROR) { ERR("Connection error: %s", e->backend.error_get(e)); goto error; } fd = e->backend.fd_get(e); if (fd != -1) { e->fdh = ecore_main_fd_handler_add(fd, ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR, (Ecore_Fd_Cb)esql_connect_handler, e, NULL, NULL); ecore_main_fd_handler_active_set(e->fdh, ret); e->current = ESQL_CONNECT_TYPE_INIT; if (ev->database) esql_database_set(e, ev->database); } return EINA_FALSE; error: ecore_event_add(ESQL_EVENT_DISCONNECT, ev, (Ecore_End_Cb)esql_fake_free, NULL); e->event_count++; return EINA_FALSE; }
EAPI Eina_Bool eldbus_signal_handler_match_extra_vset(Eldbus_Signal_Handler *sh, va_list ap) { const char *key = NULL, *read; DBusError err; ELDBUS_SIGNAL_HANDLER_CHECK_RETVAL(sh, EINA_FALSE); dbus_error_init(&err); dbus_bus_remove_match(sh->conn->dbus_conn, eina_strbuf_string_get(sh->match), &err); EINA_SAFETY_ON_TRUE_RETURN_VAL(dbus_error_is_set(&err), EINA_FALSE); for (read = va_arg(ap, char *); read; read = va_arg(ap, char *)) { Signal_Argument *arg; if (!key) { key = read; continue; } arg = calloc(1, sizeof(Signal_Argument)); EINA_SAFETY_ON_NULL_GOTO(arg, error); if (!strncmp(key, ARGX, strlen(ARGX))) { int id = atoi(key + strlen(ARGX)); arg->index = (unsigned short) id; arg->value = eina_stringshare_add(read); sh->args = eina_inlist_sorted_state_insert(sh->args, EINA_INLIST_GET(arg), _sort_arg, sh->state_args); _match_append(sh->match, key, read); } else { ERR("%s not supported", key); free(arg); } key = NULL; } dbus_error_init(&err); dbus_bus_add_match(sh->conn->dbus_conn, eina_strbuf_string_get(sh->match), &err); if (!dbus_error_is_set(&err)) return EINA_TRUE; ERR("Error setting new match."); return EINA_FALSE; error: dbus_error_init(&err); dbus_bus_add_match(sh->conn->dbus_conn, eina_strbuf_string_get(sh->match), &err); if (dbus_error_is_set(&err)) ERR("Error setting partial extra arguments."); return EINA_FALSE; }
Eldbus_Message * _eldbus_connection_send_and_block(Eldbus_Connection *conn, Eldbus_Message *msg, double timeout) { Eldbus_Message *reply = NULL; DBusError err; DBusMessage *dbus_msg; if (ecore_main_loop_nested_get()) WRN("Calling this function may result in dropped frames because the main loop is running"); dbus_error_init(&err); dbus_msg = dbus_connection_send_with_reply_and_block(conn->dbus_conn, msg->dbus_msg, timeout, &err); EINA_SAFETY_ON_TRUE_GOTO(dbus_error_is_set(&err), dbus_error_set); dbus_error_free(&err); reply = eldbus_message_new(EINA_FALSE); EINA_SAFETY_ON_NULL_GOTO(reply, fail); reply->dbus_msg = dbus_msg; dbus_message_iter_init(reply->dbus_msg, &reply->iterator->dbus_iterator); eldbus_message_unref(msg); return reply; dbus_error_set: reply = eldbus_message_error_new(msg, err.name, err.message); dbus_error_free(&err); fail: eldbus_message_unref(msg); return reply; }
/** * @brief Send arbitrary data to a connected server * * This function is used to send arbitrary data to a connected server using @p client through HTTP PUT. * It relies on the user to set required headers by operating on the client's #Azy_Net object. * @param client The client (NOT NULL) * @param send_data The data+length to send (NOT NULL) * @param data Optional data to pass to associated callbacks * @return The #Azy_Client_Call_Id of the transmission, to be used with azy_client_callback_set, * or 0 on failure * @see azy_net_header_set */ Azy_Client_Call_Id azy_client_put(Azy_Client *client, const Azy_Net_Data *send_data, void *data) { Eina_Strbuf *msg; Azy_Client_Handler_Data *hd; if (!AZY_MAGIC_CHECK(client, AZY_MAGIC_CLIENT)) { AZY_MAGIC_FAIL(client, AZY_MAGIC_CLIENT); return 0; } EINA_SAFETY_ON_NULL_RETURN_VAL(send_data, 0); EINA_SAFETY_ON_NULL_RETURN_VAL(send_data->data, 0); azy_net_message_length_set(client->net, send_data->size); azy_net_type_set(client->net, AZY_NET_TYPE_PUT); msg = azy_net_header_create(client->net); EINA_SAFETY_ON_NULL_GOTO(msg, error); #ifdef ISCOMFITOR DBG("\nSENDING >>>>>>>>>>>>>>>>>>>>>>>>\n%.*s%.*s\n>>>>>>>>>>>>>>>>>>>>>>>>", eina_strbuf_length_get(msg), eina_strbuf_string_get(msg), (int)send_data->size, send_data->data); #endif EINA_SAFETY_ON_TRUE_GOTO(!ecore_con_server_send(client->net->conn, eina_strbuf_string_get(msg), eina_strbuf_length_get(msg)), error); INFO("Send [1/2] complete! %zi bytes queued for sending.", eina_strbuf_length_get(msg)); eina_strbuf_free(msg); msg = NULL; EINA_SAFETY_ON_TRUE_GOTO(!ecore_con_server_send(client->net->conn, send_data->data, send_data->size), error); INFO("Send [2/2] complete! %" PRIi64 " bytes queued for sending.", send_data->size); ecore_con_server_flush(client->net->conn); EINA_SAFETY_ON_TRUE_RETURN_VAL(!(hd = calloc(1, sizeof(Azy_Client_Handler_Data))), 0); if (!client->conns) { client->recv = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, (Ecore_Event_Handler_Cb)_azy_client_handler_data, hd); ecore_con_server_data_set(client->net->conn, client); } hd->client = client; hd->content_data = data; hd->type = AZY_NET_TYPE_PUT; AZY_MAGIC_SET(hd, AZY_MAGIC_CLIENT_DATA_HANDLER); while (++azy_client_send_id__ < 1) ; hd->id = azy_client_send_id__; client->conns = eina_list_append(client->conns, hd); return azy_client_send_id__; error: if (msg) eina_strbuf_free(msg); return 0; }
static void cb_pending(DBusPendingCall *dbus_pending, void *user_data) { Eldbus_Message *msg; Eldbus_Pending *pending = user_data; if (!dbus_pending_call_get_completed(dbus_pending)) { INF("timeout to pending %p", pending); dbus_pending_call_cancel(dbus_pending); msg = eldbus_message_error_new(pending->msg_sent, ELDBUS_ERROR_PENDING_TIMEOUT, "This call was not completed in time."); eldbus_pending_dispatch(pending, msg); return; } msg = eldbus_message_new(EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN(msg); msg->dbus_msg = dbus_pending_call_steal_reply(dbus_pending); if (!msg->dbus_msg) { EINA_SAFETY_ON_NULL_GOTO(pending->cb, cleanup); msg->dbus_msg = dbus_message_new_error(NULL, "org.enlightenment.DBus.NoReply", "There was no reply to this method call."); EINA_SAFETY_ON_NULL_GOTO(msg->dbus_msg, cleanup); } dbus_message_iter_init(msg->dbus_msg, &msg->iterator->dbus_iterator); eldbus_pending_dispatch(pending, msg); return; cleanup: eldbus_message_unref(msg); }
Eldbus_Message *eldbus_message_new(Eina_Bool writable) { Eldbus_Message *msg = calloc(1, sizeof(Eldbus_Message)); EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL); EINA_MAGIC_SET(msg, ELDBUS_MESSAGE_MAGIC); msg->refcount = 1; msg->iterator = _message_iterator_new(writable); EINA_SAFETY_ON_NULL_GOTO(msg->iterator, fail); return msg; fail: eldbus_message_unref(msg); return NULL; }
EAPI Eldbus_Message * eldbus_message_method_call_new(const char *dest, const char *path, const char *iface, const char *method) { Eldbus_Message *msg; EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(method, NULL); #ifdef DBUS_SYNTAX_H // added to libdbus: // f426c6cddd158d6324923f28117bc8e512d6f64f Fri Feb 24 12:43:55 2012 +0000 if (!dbus_validate_bus_name(dest, NULL)) { ERR("Invalid bus name '%s'", dest); return NULL; } if (!dbus_validate_path(path, NULL)) { ERR("Invalid path '%s'", path); return NULL; } if (!dbus_validate_interface(iface, NULL)) { ERR("Invalid interface '%s'", iface); return NULL; } #endif msg = eldbus_message_new(EINA_TRUE); EINA_SAFETY_ON_NULL_GOTO(msg, fail); msg->dbus_msg = dbus_message_new_method_call(dest, path, iface, method); dbus_message_iter_init_append(msg->dbus_msg, &msg->iterator->dbus_iterator); return msg; fail: eldbus_message_unref(msg); return NULL; }
static Etui_Provider_Instance * _etui_provider_instance_new(const Etui_Provider_Descriptor *provider, Evas *evas, void *data) { Etui_Provider_Instance *inst; inst = calloc(1, sizeof(Etui_Provider_Instance)); EINA_SAFETY_ON_NULL_GOTO(inst, del_data); inst->provider = provider; inst->evas = evas; inst->data = data; EINA_REFCOUNT_INIT(inst); return inst; del_data: provider->shutdown(data); return NULL; }
Eina_Bool _alert_command_del(void *data, int type EINA_UNUSED, void *event) { Module_Alert_Command *mac = data; Ecore_Exe_Event_Del *del = event; const char *val; if (mac != ecore_exe_data_get(del->exe)) return EINA_TRUE; DBG("mac[%p] del[%p]", mac, del); val = gotham_citizen_var_get(mac->gotham->me, mac->command->name); DBG("val[%s] value[%s]", val, eina_strbuf_string_get(mac->buf)); if (!val) goto set_var; if (strcmp(val, eina_strbuf_string_get(mac->buf))) { Eina_Strbuf *buf = eina_strbuf_new(); EINA_SAFETY_ON_NULL_GOTO(buf, clean_mac); eina_strbuf_append_printf(buf, ".notification send %s Variable '%s' changed from '%s' to '%s'", strlen(mac->command->notification) ? mac->command->notification : "dev", mac->command->name, val, eina_strbuf_string_get(mac->buf)); gotham_citizen_send(mac->gotham->alfred, eina_strbuf_string_get(buf)); eina_strbuf_free(buf); } set_var: gotham_citizen_var_set(mac->gotham->me, mac->command->name, eina_strbuf_string_get(mac->buf)); clean_mac: _alert_command_clean(mac); return EINA_TRUE; }
/** * @brief Convert result to a binary blob * @param res Result * @return Allocated binary blob (must be freed) */ unsigned char * esql_res_to_blob(const Esql_Res *res, unsigned int *size) { const Esql_Row *row; const Eina_Value_Struct_Member *member; Eina_Value tmp, conv; Eina_Value_Blob blob; unsigned char *ret = NULL; if (size) *size = 0; EINA_SAFETY_ON_NULL_RETURN_VAL(res, NULL); EINA_SAFETY_ON_TRUE_RETURN_VAL(res->row_count > 1, NULL); if (!res->row_count) return NULL; row = EINA_INLIST_CONTAINER_GET(res->rows, Esql_Row); member = row->res->desc->members; if (!eina_value_struct_value_get(&(row->value), member->name, &tmp)) return NULL; if (!eina_value_setup(&conv, EINA_VALUE_TYPE_BLOB)) goto error_setup; if (!eina_value_convert(&tmp, &conv)) goto error; if (!eina_value_pget(&conv, &blob)) goto error; ret = malloc(blob.size); EINA_SAFETY_ON_NULL_GOTO(ret, error); memcpy(ret, blob.memory, blob.size); if (size) *size = blob.size; error: eina_value_flush(&conv); error_setup: eina_value_flush(&tmp); return ret; }
Command_Service * _command_service_new(Module_Services *services, const char *jid, const char *cmd, const char *service) { Command_Service *cs; const char *s; DBG("services[%p] jid[%s] cmd[%s] service[%s]", services, jid, cmd, service); cs = calloc(1, sizeof(Command_Service)); EINA_SAFETY_ON_NULL_RETURN_VAL(cs, NULL); cs->services = services; cs->jid = strdup(jid); EINA_SAFETY_ON_NULL_GOTO(cs->jid, free_cs); cs->buf = eina_strbuf_new(); EINA_SAFETY_ON_NULL_GOTO(cs->buf, free_jid); #define _EV(_a, _b, _c, _d) _a = ecore_event_handler_add(ECORE_EXE_EVENT_##_b, _c, _d) _EV(cs->ev.data, DATA, _command_data, cs); EINA_SAFETY_ON_NULL_GOTO(cs->ev.data, free_buf); _EV(cs->ev.del, DEL, _command_del, cs); EINA_SAFETY_ON_NULL_GOTO(cs->ev.del, del_data); _EV(cs->ev.error, ERROR, _command_error, cs); EINA_SAFETY_ON_NULL_GOTO(cs->ev.error, del_del); #undef _EV s = utils_strdupf(cmd, service); EINA_SAFETY_ON_NULL_GOTO(s, del_error); DBG("Running command [%s]", s); cs->exe = ecore_exe_pipe_run(s, ECORE_EXE_PIPE_READ, cs); EINA_SAFETY_ON_NULL_GOTO(cs->exe, free_s); ecore_exe_data_set(cs->exe, cs); free((char *)s); return cs; free_s: free((char *)s); del_error: ecore_event_handler_del(cs->ev.error); del_del: ecore_event_handler_del(cs->ev.del); del_data: ecore_event_handler_del(cs->ev.data); free_buf: eina_strbuf_free(cs->buf); free_jid: free((char *)cs->jid); free_cs: free(cs); return NULL; }
void esql_call_complete(Esql *e) { Esql *ev; DBG("(e=%p)", e); ev = e->pool_member ? (Esql *)e->pool_struct : e; switch (e->current) { case ESQL_CONNECT_TYPE_INIT: e->connected = EINA_TRUE; if (e->pool_member) { e->pool_struct->e_connected++; INFO("Pool connection %u created (%d/%d)", e->pool_id, e->pool_struct->e_connected, e->pool_struct->size); } else INFO("Connected"); if ((!e->pool_member) || (e->pool_member && (!e->pool_struct->connected) && (e->pool_struct->e_connected == e->pool_struct->size))) { if (e->pool_member) { e->pool_struct->connected = EINA_TRUE; INFO("[%d/%d] connections made for pool", e->pool_struct->size, e->pool_struct->size); } if (ev->connect_cb) ev->connect_cb(ev, ev->connect_cb_data); else { ecore_event_add(ESQL_EVENT_CONNECT, ev, (Ecore_End_Cb)esql_fake_free, NULL); e->event_count++; } } break; case ESQL_CONNECT_TYPE_DATABASE_SET: if (e->pool_member) INFO("Pool member %u: working database is now '%s'", e->pool_id, e->database); else INFO("Working database is now '%s'", e->database); break; case ESQL_CONNECT_TYPE_QUERY: DBG("(ev=%p, qid=%u)", ev, e->cur_id); e->query_end = ecore_time_get(); { Esql_Res *res; Esql_Query_Cb qcb; if (e->res) res = e->res; else { res = esql_res_calloc(1); EINA_SAFETY_ON_NULL_GOTO(res, out); res->e = e; e->backend.res(res); } ev->res = res; res->e = ev; res->refcount = 1; res->query = e->cur_query; e->cur_query = NULL; res->data = e->cur_data; res->qid = e->cur_id; qcb = eina_hash_find(esql_query_callbacks, &e->cur_id); if (qcb) { INFO("Executing callback for current query (%u)", res->qid); qcb(res, e->cur_data); e->query_start = e->query_end = 0.0; eina_hash_del_by_key(esql_query_callbacks, &e->cur_id); esql_res_free(NULL, res); } else { INFO("Emitting event for current query (%u)", res->qid); ecore_event_add(ESQL_EVENT_RESULT, res, (Ecore_End_Cb)esql_res_free, NULL); } e->res = ev->res = NULL; } break; default: break; } out: esql_next(e); }
/** * @brief Make an HTTP GET or POST request using a connected client with no HTTP BODY * * This function is used to make a GET or POST request using @p client to the uri of the client's * #Azy_Net object (azy_net_get(client)) using HTTP method @p type, content-type * defined by @p transport, and the optional deserialization function specified by @p cb. * @param client The client (NOT NULL) * @param type The HTTP method to use (NOT NULL) * @param netdata The HTTP BODY to send with a POST * @param cb The deserialization callback to use for the response * @param data The user data to be passed to resulting callbacks * @return The #Azy_Client_Call_Id of the transmission, to be used with azy_client_callback_set, * or 0 on failure */ Azy_Client_Call_Id azy_client_blank(Azy_Client *client, Azy_Net_Type type, Azy_Net_Data *netdata, Azy_Content_Cb cb, void *data) { Eina_Strbuf *msg; Azy_Client_Handler_Data *hd; DBG("(client=%p, net=%p)", client, client->net); if (!AZY_MAGIC_CHECK(client, AZY_MAGIC_CLIENT)) { AZY_MAGIC_FAIL(client, AZY_MAGIC_CLIENT); return 0; } EINA_SAFETY_ON_NULL_RETURN_VAL(client->net, 0); EINA_SAFETY_ON_TRUE_RETURN_VAL((type != AZY_NET_TYPE_GET) && (type != AZY_NET_TYPE_POST), 0); while (++azy_client_send_id__ < 1) ; client->net->type = type; if (!client->net->http.req.http_path) { WARN("NULL URI passed, defaulting to \"/\""); azy_net_uri_set(client->net, "/"); } if (netdata && netdata->size && (type == AZY_NET_TYPE_POST)) azy_net_message_length_set(client->net, netdata->size); msg = azy_net_header_create(client->net); EINA_SAFETY_ON_NULL_GOTO(msg, error); #ifdef ISCOMFITOR char buf[64]; snprintf(buf, sizeof(buf), "\nSENDING >>>>>>>>>>>>>>>>>>>>>>>>\n%%.%zus\n>>>>>>>>>>>>>>>>>>>>>>>>", eina_strbuf_length_get(msg)); DBG(buf, eina_strbuf_string_get(msg)); #endif EINA_SAFETY_ON_TRUE_GOTO(!ecore_con_server_send(client->net->conn, eina_strbuf_string_get(msg), eina_strbuf_length_get(msg)), error); if (netdata && netdata->size && (type == AZY_NET_TYPE_POST)) { INFO("Send [1/2] complete! %zu bytes queued for sending.", eina_strbuf_length_get(msg)); EINA_SAFETY_ON_TRUE_GOTO(!ecore_con_server_send(client->net->conn, netdata->data, netdata->size), error); INFO("Send [2/2] complete! %" PRIi64 " bytes queued for sending.", netdata->size); } else INFO("Send [1/1] complete! %zu bytes queued for sending.", eina_strbuf_length_get(msg)); eina_strbuf_free(msg); msg = NULL; ecore_con_server_flush(client->net->conn); hd = calloc(1, sizeof(Azy_Client_Handler_Data)); EINA_SAFETY_ON_NULL_RETURN_VAL(hd, 0); hd->client = client; hd->callback = cb; hd->type = type; hd->content_data = data; if (netdata && netdata->size && (type == AZY_NET_TYPE_POST)) { hd->send = eina_strbuf_new(); eina_strbuf_append_length(hd->send, (char *)netdata->data, netdata->size); } hd->id = azy_client_send_id__; AZY_MAGIC_SET(hd, AZY_MAGIC_CLIENT_DATA_HANDLER); if (!client->conns) { client->recv = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, (Ecore_Event_Handler_Cb)_azy_client_handler_data, hd); ecore_con_server_data_set(client->net->conn, client); } client->conns = eina_list_append(client->conns, hd); DBG("(client=%p, net=%p, hd=%p)", client, client->net, hd); return azy_client_send_id__; error: if (msg) eina_strbuf_free(msg); return 0; }
/** * @brief Make a method call using a connected client * * This function is used to make a method call on @p client as defined in * @p content, using content-type defined by @p transport and the deserialization * function specified by @p cb. This should generally not be used by users, as azy_parser * will automatically generate the correct calls from a .azy file. * @param client The client (NOT NULL) * @param content The content containing the method name and parameters (NOT NULL) * @param transport The content-type (xml/json/etc) to use * @param cb The deserialization callback to use for the response * @return The #Azy_Client_Call_Id of the transmission, to be used with azy_client_callback_set, * or 0 on failure */ Azy_Client_Call_Id azy_client_call(Azy_Client *client, Azy_Content *content, Azy_Net_Transport transport, Azy_Content_Cb cb) { Eina_Strbuf *msg; Azy_Client_Handler_Data *hd; DBG("(client=%p, net=%p, content=%p)", client, client->net, content); if (!AZY_MAGIC_CHECK(client, AZY_MAGIC_CLIENT)) { AZY_MAGIC_FAIL(client, AZY_MAGIC_CLIENT); return 0; } EINA_SAFETY_ON_NULL_RETURN_VAL(client->net, 0); EINA_SAFETY_ON_NULL_RETURN_VAL(content, 0); EINA_SAFETY_ON_NULL_RETURN_VAL(content->method, 0); INFO("New method call: '%s'", content->method); while (++azy_client_send_id__ < 1) ; content->id = azy_client_send_id__; azy_net_transport_set(client->net, transport); if (!azy_content_serialize_request(content, transport)) return 0; azy_net_type_set(client->net, AZY_NET_TYPE_POST); if (!client->net->http.req.http_path) { WARN("URI currently set to NULL, defaulting to \"/\""); azy_net_uri_set(client->net, "/"); } azy_net_message_length_set(client->net, content->length); msg = azy_net_header_create(client->net); EINA_SAFETY_ON_NULL_GOTO(msg, error); if (azy_rpc_log_dom >= 0) { char buf[64]; snprintf(buf, sizeof(buf), "\nSENDING >>>>>>>>>>>>>>>>>>>>>>>>\n%%.%is%%.%llis\n>>>>>>>>>>>>>>>>>>>>>>>>", eina_strbuf_length_get(msg), content->length); RPC_DBG(buf, eina_strbuf_string_get(msg), content->buffer); } EINA_SAFETY_ON_TRUE_GOTO(!ecore_con_server_send(client->net->conn, eina_strbuf_string_get(msg), eina_strbuf_length_get(msg)), error); INFO("Send [1/2] complete! %zu bytes queued for sending.", eina_strbuf_length_get(msg)); eina_strbuf_free(msg); msg = NULL; EINA_SAFETY_ON_TRUE_GOTO(!ecore_con_server_send(client->net->conn, content->buffer, content->length), error); INFO("Send [2/2] complete! %lli bytes queued for sending.", content->length); ecore_con_server_flush(client->net->conn); hd = calloc(1, sizeof(Azy_Client_Handler_Data)); EINA_SAFETY_ON_NULL_RETURN_VAL(hd, 0); hd->client = client; hd->method = eina_stringshare_ref(content->method); hd->callback = cb; hd->type = AZY_NET_TYPE_POST; hd->content_data = content->data; hd->send = eina_strbuf_new(); eina_strbuf_append_length(hd->send, (char *)content->buffer, content->length); hd->id = azy_client_send_id__; AZY_MAGIC_SET(hd, AZY_MAGIC_CLIENT_DATA_HANDLER); if (!client->conns) { client->recv = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, (Ecore_Event_Handler_Cb)_azy_client_handler_data, hd); ecore_con_server_data_set(client->net->conn, client); } client->conns = eina_list_append(client->conns, hd); DBG("(client=%p, net=%p, content=%p, hd=%p)", client, client->net, content, hd); return azy_client_send_id__; error: if (msg) eina_strbuf_free(msg); return 0; }
/** * Prepare the library for use through initialization of any required connections and / or * variables * * @return boolean EINA_TRUE for success, EINA_FALSE on error. */ Eina_Bool init(DB *db, Zrpcdb_Connect_Cb cb, Ecore_Event_Handler_Cb error_cb, Ecore_Event_Handler_Cb result_cb, zentific_config *conf){ Esql *e; if ((!db) || (!cb) || (!conf)) return EINA_FALSE; eina_init(); zrpcdb_log_dom = eina_log_domain_register("zrpcdb", EINA_COLOR_ORANGE); if (zrpcdb_log_dom < 0) { fprintf(stderr, "Could not init zrpcdb log domain\n"); goto err; } INF("Initializing source 'zrpcdb'"); if (!db_config_parse(db, conf->DB_MODULES_PATH)){ ERR("Could not parse config file"); goto log; } /* make sure that we have all config options */ if ((!db->config->backend) || (!db->config->username) || (!db->config->password) || (!db->config->database)) { ERR("Missing options in db->config file. Requires HOSTNAME, USERNAME, PASSWORD, and DATABASE fields."); goto cfg; } /* FIXME: better value here */ esql_init(); if (db->config->conns < 5){ WRN("DB init: DB pool size must be at least 5. Resizing to 5."); db->config->conns = 5; } e = esql_pool_new(db->config->conns, ESQL_TYPE_MYSQL); EINA_SAFETY_ON_NULL_GOTO(e, esql); esql_data_set(e, db); db->pool_size = db->config->conns; esql_connect_callback_set(e, (Esql_Connect_Cb)init_cb, cb); esql_database_set(e, db->config->database); if (!esql_connect(e, db->config->backend, db->config->username, db->config->password)){ ERR("Could not begin database connection!"); goto conn; } db->e = e; if (!init_count++){ ZRPCDB_EVENT_ERROR = ecore_event_type_new(); zrpc_err = ecore_event_handler_add(ZRPCDB_EVENT_ERROR, error_cb, db); ZRPCDB_EVENT_RESULT = ecore_event_type_new(); zrpc_res = ecore_event_handler_add(ZRPCDB_EVENT_RESULT, result_cb, db); type_cbs = eina_hash_int64_new(NULL); db_cbs = eina_hash_int64_new(NULL); db_cb_params = eina_hash_int64_new(NULL); } // eina_log_domain_level_set("zrpcdb", db->config->loglevel); return EINA_TRUE; conn: esql_free(e); esql: esql_shutdown(); cfg: db_config_free(db->config); log: eina_log_domain_unregister(zrpcdb_log_dom); zrpcdb_log_dom = -1; err: eina_shutdown(); return EINA_FALSE; }
char * esql_query_escape(Eina_Bool backslashes, size_t *len, const char *fmt, va_list args) { Eina_Strbuf *buf; const char *p, *pp; char *ret = NULL; size_t fmtlen; buf = eina_strbuf_new(); *len = 0; fmtlen = strlen(fmt); pp = strchr(fmt, '%'); if (!pp) pp = fmt + fmtlen; for (p = fmt; p && *p; pp = strchr(p, '%')) { Eina_Bool l = EINA_FALSE; Eina_Bool ll = EINA_FALSE; long long int i; double d; char *s; if (!pp) pp = fmt + fmtlen; EINA_SAFETY_ON_FALSE_GOTO(eina_strbuf_append_length(buf, p, ((pp - p > 1) ? pp - p : 1)), err); if (*pp != '%') break; /* no more fmt strings */ top: switch (pp[1]) { case 0: ERR("Invalid format string!"); goto err; case 'l': if (!l) l = EINA_TRUE; else if (!ll) ll = EINA_TRUE; else { ERR("Invalid format string!"); goto err; } pp++; goto top; case 'f': if (l && ll) { ERR("Invalid format string!"); goto err; } d = va_arg(args, double); EINA_SAFETY_ON_FALSE_GOTO(eina_strbuf_append_printf(buf, "%lf", d), err); break; case 'i': case 'd': if (l && ll) i = va_arg(args, long long int); else if (l) i = va_arg(args, long int); else i = va_arg(args, int); EINA_SAFETY_ON_FALSE_GOTO(eina_strbuf_append_printf(buf, "%lli", i), err); break; case 's': if (l) { ERR("Invalid format string!"); goto err; } s = va_arg(args, char *); if (!s) break; s = esql_string_escape(backslashes, s); EINA_SAFETY_ON_NULL_GOTO(s, err); EINA_SAFETY_ON_FALSE_GOTO(eina_strbuf_append(buf, s), err); free(s); break; case 'c': if (l) { ERR("Invalid format string!"); goto err; } { char c[3]; c[0] = va_arg(args, int); c[1] = c[2] = 0; s = esql_string_escape(backslashes, c); EINA_SAFETY_ON_NULL_GOTO(s, err); EINA_SAFETY_ON_FALSE_GOTO(eina_strbuf_append(buf, s), err); free(s); } break; case '%': EINA_SAFETY_ON_FALSE_GOTO(eina_strbuf_append_char(buf, '%'), err); break; default: ERR("Unsupported format string: '%s'!", pp); goto err; }