void *erlXML_StartNamespaceDeclHandler(expat_data *d, const XML_Char *prefix, const XML_Char *uri) { int prefix_len; char *buf; /* From the expat documentation: "For a default namespace declaration (xmlns='...'), the prefix will be null ... ... The URI will be null for the case where the default namespace is being unset." FIXME: I'm not quite sure what all that means */ if (uri == NULL) return NULL; ei_x_encode_list_header(&xmlns_buf, 1); ei_x_encode_tuple_header(&xmlns_buf, 2); if (prefix) { prefix_len = strlen(prefix); buf = driver_alloc(7 + prefix_len); strcpy(buf, "xmlns:"); strcpy(buf+6, prefix); ei_x_encode_binary(&xmlns_buf, buf, strlen(buf)); driver_free(buf); } else { ei_x_encode_binary(&xmlns_buf, "xmlns", strlen("xmlns")); }; ei_x_encode_binary(&xmlns_buf, uri, strlen(uri)); return NULL; }
void encode_name(const XML_Char *name) { char *name_start; char *prefix_start; char *buf; int name_len, prefix_len, buf_len; if ((name_start = strchr(name, '\n'))) { if ((prefix_start = strchr(name_start+1, '\n'))) { name_len = prefix_start - name_start; prefix_len = strlen(prefix_start+1); buf_len = prefix_len + name_len; buf = driver_alloc(buf_len); memcpy(buf, prefix_start+1, prefix_len); memcpy(buf+prefix_len, name_start, name_len); buf[prefix_len] = ':'; ei_x_encode_binary(&event_buf, buf, buf_len); driver_free(buf); } else { ei_x_encode_binary(&event_buf, name_start+1, strlen(name_start+1)); }; } else { ei_x_encode_binary(&event_buf, name, strlen(name)); } }
int make_attribute(struct exmpp_xml_ctx *ctx, const char *ns, int ns_len, const char *attr, int attr_len, const char *value, int value_len) { ei_x_buff *tree; tree = ctx->current_tree; /* Start #xmlattr record. */ ei_x_encode_list_header(tree, 1); ei_x_encode_tuple_header(tree, 4); ei_x_encode_atom(tree, "xmlattr"); /* Check if the namespace is known and encode it. */ encode_ns(ctx, tree, ns, ns_len); /* Check if the attribute is known and encode it. */ encode_attr(ctx, tree, attr, attr_len); /* Encode the value. */ if (value_len == -1) ei_x_encode_binary(tree, value, strlen(value)); else ei_x_encode_binary(tree, value, value_len); return (0); }
static int encode_attr(struct exmpp_xml_ctx *ctx, ei_x_buff *tree, const char *attr, int attr_len) { int ret; if (attr_len == -1) ret = ei_x_encode_binary(tree, attr, strlen(attr)); else ret = ei_x_encode_binary(tree, attr, attr_len); return (ret); }
void *erlXML_StartElementHandler(expat_data *d, const XML_Char *name, const XML_Char **atts) { int i; ei_x_encode_list_header(&event_buf, 1); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, XML_START); ei_x_encode_tuple_header(&event_buf, 2); encode_name(name); ei_x_append(&event_buf, &xmlns_buf); ei_x_free(&xmlns_buf); ei_x_new(&xmlns_buf); for (i = 0; atts[i]; i += 2) {} if (i > 0) { ei_x_encode_list_header(&event_buf, i/2); for (i = 0; atts[i]; i += 2) { ei_x_encode_tuple_header(&event_buf, 2); encode_name(atts[i]); ei_x_encode_binary(&event_buf, atts[i+1], strlen(atts[i+1])); } } ei_x_encode_empty_list(&event_buf); return NULL; }
int add_character_data(struct exmpp_xml_ctx *ctx, const char *text, int text_len) { ei_x_buff *tree; tree = ctx->current_tree; if (tree == NULL) return (-1); if (ctx->root_depth == -1 || ctx->depth <= ctx->root_depth) { /* We're above root depth (or the feature is disabled), * so we start a new Erlang term each time. */ /* The current_tree buffer was reset by * current_tree_finished(). */ } else { /* We continue the children list. */ ei_x_encode_list_header(tree, 1); } /* Start an #xmlcdata record. */ ei_x_encode_tuple_header(tree, 2); ei_x_encode_atom(tree, "xmlcdata"); /* Encode the data. */ ei_x_encode_binary(tree, text, text_len); if (ctx->root_depth == -1 || ctx->depth <= ctx->root_depth) current_tree_finished(ctx); return (0); }
void epcap_response(u_char *user, const struct pcap_pkthdr *hdr, const u_char *pkt) { EPCAP_STATE *ep = (EPCAP_STATE *)user; ei_x_buff msg = {0}; IS_FALSE(ei_x_new_with_version(&msg)); /* {packet, DatalinkType, Time, ActualLength, Packet} */ IS_FALSE(ei_x_encode_tuple_header(&msg, 5)); IS_FALSE(ei_x_encode_atom(&msg, "packet")); /* DataLinkType */ IS_FALSE(ei_x_encode_long(&msg, ep->datalink)); /* {MegaSec, Sec, MicroSec} */ IS_FALSE(ei_x_encode_tuple_header(&msg, 3)); IS_FALSE(ei_x_encode_long(&msg, abs(hdr->ts.tv_sec / 1000000))); IS_FALSE(ei_x_encode_long(&msg, hdr->ts.tv_sec % 1000000)); IS_FALSE(ei_x_encode_long(&msg, hdr->ts.tv_usec)); /* ActualLength} */ IS_FALSE(ei_x_encode_long(&msg, hdr->len)); /* Packet */ IS_FALSE(ei_x_encode_binary(&msg, pkt, hdr->caplen)); /* } */ epcap_send_free(&msg); }
static int erl_json_ei_string(void* ctx, const unsigned char* val, unsigned int len) { State* pState = (State*) ctx; flog(stderr, "string", 0, (const char*)val, len); list_header_for_value(pState); ei_x_encode_binary(&pState->ei_buf, val, len); return 1; }
static int unwrap(char *buf, int index, ei_x_buff *presult) { ei_x_buff result = *presult; /* {unwrap, {Idx, Input}} -> {ok, {conf_state, Output}} */ int arity; gss_buffer_desc in; gss_buffer_desc out; long idx; int conf_state; OM_uint32 maj_stat, min_stat; gss_qop_t qop; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); EI(ei_decode_tuple_header(buf, &index, &arity)); EI(arity != 2); EI(ei_decode_long(buf, &index, &idx)); EI(decode_gssapi_binary(buf, &index, &in)); if (idx < 0 || idx >= MAX_SESSIONS || !g_sessions[idx]) ENCODE_ERROR("bad_instance"); maj_stat = gss_unwrap(&min_stat, g_sessions[idx], &in, &out, &conf_state, &qop); if (!GSS_ERROR(maj_stat)) { const char *conf_str = conf_state ? "true":"false"; EI(ei_x_encode_atom(&result, "ok") || ei_x_encode_tuple_header(&result, 2) || ei_x_encode_atom(&result, conf_str) || ei_x_encode_binary(&result, out.value, out.length) ); } else { EI(ei_x_encode_atom(&result, "error") || ei_x_encode_long(&result, maj_stat)); } error: if (in.value) gss_release_buffer(&min_stat, &in); if (out.value) gss_release_buffer(&min_stat, &out); *presult = result; return 0; }
void *erlXML_CharacterDataHandler(expat_data *d, const XML_Char *s, int len) { ei_x_encode_list_header(&event_buf, 1); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, XML_CDATA); ei_x_encode_binary(&event_buf, s, len); return NULL; }
static ErlDrvSSizeT expat_erl_control(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { expat_data* d = (expat_data*)drv_data; int res, errcode; char *errstring; ErlDrvBinary *b; size_t size; switch (command) { case PARSE_COMMAND: case PARSE_FINAL_COMMAND: ei_x_new_with_version(&event_buf); ei_x_new(&xmlns_buf); res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND); if(!res) { errcode = XML_GetErrorCode(d->parser); errstring = (char *)XML_ErrorString(errcode); ei_x_encode_list_header(&event_buf, 1); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, XML_ERROR); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, errcode); ei_x_encode_binary(&event_buf, errstring, strlen(errstring)); } ei_x_encode_empty_list(&event_buf); size = event_buf.index; b = driver_alloc_binary(size); memcpy(b->orig_bytes, event_buf.buff, size); ei_x_free(&event_buf); ei_x_free(&xmlns_buf); *rbuf = (char *)b; return size; default: return 0; } }
static int erl_json_ei_map_key(void* ctx, const unsigned char* buf, unsigned int len) { State* pState = (State*) ctx; flog(stderr, "map key", 0, buf, len); list_header_for_value(pState); ei_x_encode_tuple_header(&pState->ei_buf, 2); switch(keys_as(pState)) { case EEP0018_PARSE_KEYS_AS_ATOM: ei_x_encode_atom_len(&pState->ei_buf, buf, len); break; case EEP0018_PARSE_KEYS_AS_BINARY: ei_x_encode_binary(&pState->ei_buf, buf, len); break; } pState->skip_list_header_for_value = -1; return 1; }
void encode_result(ei_x_buff* x, PGresult* res, PGconn* conn) { int row, n_rows, col, n_cols, fsize; switch (PQresultStatus(res)) { case PGRES_TUPLES_OK: n_rows = PQntuples(res); n_cols = PQnfields(res); ei_x_encode_tuple_header(x, 2); encode_ok(x); ei_x_encode_list_header(x, 1); for (col = 0; col < n_cols; ++col) { ei_x_encode_list_header(x, 1); ei_x_encode_string(x, PQfname(res, col)); } ei_x_encode_empty_list(x); for (row = 0; row < n_rows; ++row) { ei_x_encode_list_header(x, 1); for (col = 0; col < n_cols; ++col) { ei_x_encode_list_header(x, 1); fsize = PQgetlength(res, row, col); ei_x_encode_binary(x, PQgetvalue(res, row, col), fsize); } ei_x_encode_empty_list(x); } ei_x_encode_empty_list(x); break; case PGRES_COMMAND_OK: ei_x_encode_tuple_header(x, 2); encode_ok(x); ei_x_encode_string(x, PQcmdTuples(res)); break; default: encode_error(x, conn); break; } }
ETERM * write_to_png_stream(ETERM* arg, int c_node) { cairo_context * const ctx = get_cairo_context(arg); if(!ctx) return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); struct png_data out = {}; const int status = cairo_surface_write_to_png_stream(ctx->sf, write_cb, &out); ETERM *term = NULL; ei_x_buff req; ei_x_new_with_version(&req); ei_x_encode_tuple_header(&req, 3); ei_x_encode_atom(&req, "c_node"); ei_x_encode_long(&req, c_node); ei_x_encode_tuple_header(&req, 2); ei_x_encode_atom(&req, "ok"); ei_x_encode_binary(&req, out.buf, out.written); int index = 0; ei_decode_term(req.buff, &index, &term); ei_x_free(&req); free(out.buf); return term; }
int srdb1_encode_kv(int tupsize,const db_key_t* _k, const db_op_t* _op, const db_val_t* _v, const int _n, ei_x_buff *argbuf) { int i; struct tm* tt; time_t t_t; if(_k) { ei_x_encode_list_header(argbuf, _n); for(i = 0; i < _n; i++) { db_val_t *vv; ei_x_encode_tuple_header(argbuf, tupsize); ei_x_encode_atom_len(argbuf,_k[i]->s,_k[i]->len); if(tupsize == 3 ) { if (_op) { ei_x_encode_atom(argbuf,_op[i]); } else { ei_x_encode_atom(argbuf,"="); } } vv=&(_v[i]); if (VAL_NULL(vv)) { ei_x_encode_atom(argbuf,"undefined"); } else { switch(VAL_TYPE(vv)) { case DB1_INT: ei_x_encode_ulong(argbuf, VAL_INT(vv)); break; case DB1_BIGINT: ei_x_encode_longlong(argbuf, VAL_BIGINT(vv)); break; case DB1_DOUBLE: ei_x_encode_double(argbuf, VAL_DOUBLE(vv)); break; case DB1_STRING: ei_x_encode_string(argbuf,VAL_STRING(vv)); break; case DB1_STR: ei_x_encode_string_len(argbuf,VAL_STR(vv).s,VAL_STR(vv).len); break; case DB1_DATETIME: t_t=VAL_TIME(vv); tt= localtime(&t_t); ei_x_encode_tuple_header(argbuf, 2); ei_x_encode_tuple_header(argbuf, 3); ei_x_encode_long(argbuf, tt->tm_year + 1900); ei_x_encode_long(argbuf, tt->tm_mon +1); ei_x_encode_long(argbuf, tt->tm_mday); ei_x_encode_tuple_header(argbuf, 3); ei_x_encode_long(argbuf, tt->tm_hour); ei_x_encode_long(argbuf, tt->tm_min); ei_x_encode_long(argbuf, tt->tm_sec); break; case DB1_BLOB: ei_x_encode_binary(argbuf,VAL_BLOB(vv).s,VAL_BLOB(vv).len); break; case DB1_BITMAP: ei_x_encode_ulong(argbuf,VAL_BITMAP(vv)); break; } } } ei_x_encode_empty_list(argbuf); } else { ei_x_encode_list_header(argbuf, 0); } return 0; }
static int wrap(char *buf, int index, ei_x_buff *presult) { ei_x_buff result = *presult; /* {wrap, {Idx, Conf_req_flag, Input}} -> {ok, {Conf_state, Output}} */ int arity; gss_buffer_desc in; gss_buffer_desc out; long idx; char conf_str[MAXATOMLEN]; int conf_req; int conf_state; OM_uint32 maj_stat, min_stat; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); EI(ei_decode_tuple_header(buf, &index, &arity)); EI(arity != 3); EI(ei_decode_long(buf, &index, &idx)); EI(ei_decode_atom(buf, &index, conf_str)); EI(decode_gssapi_binary(buf, &index, &in)); if (idx < 0 || idx >= MAX_SESSIONS || !g_sessions[idx]) ENCODE_ERROR("bad_instance"); if (!strcmp(conf_str, "false")) { conf_req = 0; } else if (!strcmp(conf_str, "true")) { conf_req = 1; } else { ENCODE_ERROR("bad_parameter"); } maj_stat = gss_wrap(&min_stat, g_sessions[idx], conf_req, GSS_C_QOP_DEFAULT, &in, &conf_state, &out); if (!GSS_ERROR(maj_stat)) { const char *conf_str = conf_state ? "true":"false"; EI(ei_x_encode_atom(&result, "ok") || ei_x_encode_tuple_header(&result, 2) || ei_x_encode_atom(&result, conf_str) || ei_x_encode_binary(&result, out.value, out.length) ); } else { EI(ei_x_encode_atom(&result, "error") || ei_x_encode_long(&result, maj_stat)); } error: if (in.value) gss_release_buffer(&min_stat, &in); if (out.value) gss_release_buffer(&min_stat, &out); *presult = result; return 0; }
static int init_sec_context(char *buf, int index, ei_x_buff *presult) { ei_x_buff result = *presult; /* {init_sec_context, {Idx, Service, Host, Input}} -> {ok, {Idx, Data}} | {error, Error} */ int arity; gss_buffer_desc in; gss_buffer_desc out; int res; char *service = NULL; char *hostname = NULL; long idx; OM_uint32 min_stat; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); EI(ei_decode_tuple_header(buf, &index, &arity)); EI(arity != 4); EI(ei_decode_long(buf, &index, &idx)); DECODE_STRING(&service); DECODE_STRING(&hostname); EI(decode_gssapi_binary(buf, &index, &in)); if (idx < 0) { idx = session_find_free(); if (idx < 0) ENCODE_ERROR("no_mem"); g_sessions[idx] = GSS_C_NO_CONTEXT; } else { if (idx < 0 || idx >= MAX_SESSIONS || !g_sessions[idx]) ENCODE_ERROR("bad_instance"); } res = init_user(&g_sessions[idx], service, hostname, &in, &out); if (!GSS_ERROR(res)) { const char *status = (res & GSS_S_CONTINUE_NEEDED)?"needsmore":"ok"; EI(ei_x_encode_atom(&result, status) || ei_x_encode_tuple_header(&result, 2) || ei_x_encode_long(&result, idx) || ei_x_encode_binary(&result, out.value, out.length) ); } else { EI(ei_x_encode_atom(&result, "error") || ei_x_encode_long(&result, res)); } error: if (service) free(service); if (hostname) free(hostname); if (in.value) gss_release_buffer(&min_stat, &in); if (out.value) gss_release_buffer(&min_stat, &out); *presult = result; return 0; }
static int accept_sec_context(char *buf, int index, ei_x_buff *presult) { ei_x_buff result = *presult; /* {accept_sec_context, {Idx, In}} -> {ok, {Idx, Name, CCName, Out}} | {needsmore, {Idx, Out}} */ int arity; gss_buffer_desc in; gss_buffer_desc out; gss_buffer_desc name; int res; char *ccname = NULL; long idx; OM_uint32 min_stat; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); memset(&name, 0, sizeof(name)); EI(ei_decode_tuple_header(buf, &index, &arity)); EI(arity != 2); EI(ei_decode_long(buf, &index, &idx)); EI(decode_gssapi_binary(buf, &index, &in)); if (idx < 0) { idx = session_find_free(); if (idx < 0) ENCODE_ERROR("no_mem"); g_sessions[idx] = GSS_C_NO_CONTEXT; } else { if (idx < 0 || idx >= MAX_SESSIONS || !g_sessions[idx]) ENCODE_ERROR("bad_instance"); } res = accept_user(&g_sessions[idx], &in, &out, &name, &ccname); if (!GSS_ERROR(res)) { if (res & GSS_S_CONTINUE_NEEDED) { EI(ei_x_encode_atom(&result, "needsmore") || ei_x_encode_tuple_header(&result, 2) || ei_x_encode_long(&result, idx) || ei_x_encode_binary(&result, out.value, out.length) ); } else { const char *ret_ccname = ccname; if (!ret_ccname) ret_ccname = ""; EI(ei_x_encode_atom(&result, "ok") || ei_x_encode_tuple_header(&result, 4) || ei_x_encode_long(&result, idx) || ei_x_encode_string_len(&result, name.value, name.length) || ei_x_encode_string(&result, ret_ccname) || ei_x_encode_binary(&result, out.value, out.length) ); } } else { EI(ei_x_encode_atom(&result, "error") || ei_x_encode_atom(&result, "unauthorized")); } error: if (ccname) free(ccname); if (in.value) gss_release_buffer(&min_stat, &in); if (out.value) gss_release_buffer(&min_stat, &out); if (name.value) gss_release_buffer(&min_stat, &name); *presult = result; return 0; }
int main(void) #endif { ErlConnect conp; Erl_IpAddr thisipaddr = (Erl_IpAddr)0; FILE *fp = (FILE *)0; char* charp = "foo"; double *doublep = NULL; double doublex = 0.0; ei_cnode xec; ei_reg *ei_regp = NULL; ei_term eterm; ei_x_buff eix; erlang_big *bigp = NULL; erlang_fun efun; erlang_msg *msgp = NULL; erlang_msg emsg; erlang_pid *pidp = NULL; erlang_pid epid; erlang_port eport; erlang_ref eref; erlang_trace etrace; int *intp = NULL; int intx = 0; long *longp = NULL; long longx = 0; short creation = 0; struct ei_reg_stat *ei_reg_statp = NULL; struct ei_reg_tabstat *ei_reg_tabstatp = NULL; struct hostent *hostp = NULL; unsigned char * ucharp = (unsigned char *)"foo"; unsigned long *ulongp = NULL; unsigned long ulongx = 0; void *voidp = NULL; #ifndef VXWORKS EI_LONGLONG *longlongp = (EI_LONGLONG*)NULL; EI_LONGLONG longlongx = 0; EI_ULONGLONG *ulonglongp = (EI_ULONGLONG*)NULL; EI_ULONGLONG ulonglongx = 0; #endif enum erlang_char_encoding enc; intx = erl_errno; ei_connect_init(&xec, charp, charp, creation); ei_connect_xinit (&xec, charp, charp, charp, thisipaddr, charp, creation); ei_connect(&xec, charp); ei_xconnect (&xec, thisipaddr, charp); ei_receive(intx, ucharp, intx); ei_receive_msg(intx, &emsg, &eix); ei_xreceive_msg(intx, &emsg, &eix); ei_send(intx, &epid, charp, intx); ei_reg_send(&xec, intx, charp, charp, intx); ei_rpc(&xec, intx, charp, charp, charp, intx, &eix); ei_rpc_to(&xec, intx, charp, charp, charp, intx); ei_rpc_from(&xec, intx, intx, &emsg, &eix); ei_publish(&xec, intx); ei_accept(&xec, intx, &conp); ei_unpublish(&xec); ei_thisnodename(&xec); ei_thishostname(&xec); ei_thisalivename(&xec); ei_self(&xec); ei_gethostbyname(charp); ei_gethostbyaddr(charp, intx, intx); ei_gethostbyname_r(charp, hostp, charp, intx, intp); ei_gethostbyaddr_r(charp, intx, intx, hostp, charp, intx, intp); ei_encode_version(charp, intp); ei_x_encode_version(&eix); ei_encode_long(charp, intp, longx); ei_x_encode_long(&eix, longx); ei_encode_ulong(charp, intp, ulongx); ei_x_encode_ulong(&eix, ulongx); ei_encode_double(charp, intp, doublex); ei_x_encode_double(&eix, doublex); ei_encode_boolean(charp, intp, intx); ei_x_encode_boolean(&eix, intx); ei_encode_char(charp, intp, 'a'); ei_x_encode_char(&eix, 'a'); ei_encode_string(charp, intp, charp); ei_encode_string_len(charp, intp, charp, intx); ei_x_encode_string(&eix, charp); ei_x_encode_string_len(&eix, charp, intx); ei_encode_atom(charp, intp, charp); ei_encode_atom_as(charp, intp, charp, ERLANG_LATIN1, ERLANG_UTF8); ei_encode_atom_len(charp, intp, charp, intx); ei_encode_atom_len_as(charp, intp, charp, intx, ERLANG_ASCII, ERLANG_LATIN1); ei_x_encode_atom(&eix, charp); ei_x_encode_atom_as(&eix, charp, ERLANG_LATIN1, ERLANG_UTF8); ei_x_encode_atom_len(&eix, charp, intx); ei_x_encode_atom_len_as(&eix, charp, intx, ERLANG_LATIN1, ERLANG_UTF8); ei_encode_binary(charp, intp, (void *)0, longx); ei_x_encode_binary(&eix, (void*)0, intx); ei_encode_pid(charp, intp, &epid); ei_x_encode_pid(&eix, &epid); ei_encode_fun(charp, intp, &efun); ei_x_encode_fun(&eix, &efun); ei_encode_port(charp, intp, &eport); ei_x_encode_port(&eix, &eport); ei_encode_ref(charp, intp, &eref); ei_x_encode_ref(&eix, &eref); ei_encode_trace(charp, intp, &etrace); ei_x_encode_trace(&eix, &etrace); ei_encode_tuple_header(charp, intp, intx); ei_x_encode_tuple_header(&eix, longx); ei_encode_list_header(charp, intp, intx); ei_x_encode_list_header(&eix, longx); /* #define ei_encode_empty_list(buf,i) ei_encode_list_header(buf,i,0) */ ei_x_encode_empty_list(&eix); ei_get_type(charp, intp, intp, intp); ei_get_type_internal(charp, intp, intp, intp); ei_decode_version(charp, intp, intp); ei_decode_long(charp, intp, longp); ei_decode_ulong(charp, intp, ulongp); ei_decode_double(charp, intp, doublep); ei_decode_boolean(charp, intp, intp); ei_decode_char(charp, intp, charp); ei_decode_string(charp, intp, charp); ei_decode_atom(charp, intp, charp); ei_decode_atom_as(charp, intp, charp, MAXATOMLEN_UTF8, ERLANG_WHATEVER, &enc, &enc); ei_decode_binary(charp, intp, (void *)0, longp); ei_decode_fun(charp, intp, &efun); free_fun(&efun); ei_decode_pid(charp, intp, &epid); ei_decode_port(charp, intp, &eport); ei_decode_ref(charp, intp, &eref); ei_decode_trace(charp, intp, &etrace); ei_decode_tuple_header(charp, intp, intp); ei_decode_list_header(charp, intp, intp); ei_decode_ei_term(charp, intp, &eterm); ei_print_term(fp, charp, intp); ei_s_print_term(&charp, charp, intp); ei_x_format(&eix, charp); ei_x_format_wo_ver(&eix, charp); ei_x_new(&eix); ei_x_new_with_version(&eix); ei_x_free(&eix); ei_x_append(&eix, &eix); ei_x_append_buf(&eix, charp, intx); ei_skip_term(charp, intp); ei_reg_open(intx); ei_reg_resize(ei_regp, intx); ei_reg_close(ei_regp); ei_reg_setival(ei_regp, charp, longx); ei_reg_setfval(ei_regp, charp, doublex); ei_reg_setsval(ei_regp, charp, charp); ei_reg_setpval(ei_regp, charp, voidp, intx); ei_reg_setval(ei_regp, charp, intx); ei_reg_getival(ei_regp, charp); ei_reg_getfval(ei_regp, charp); ei_reg_getsval(ei_regp, charp); ei_reg_getpval(ei_regp, charp, intp); ei_reg_getval(ei_regp, charp, intx); ei_reg_markdirty(ei_regp, charp); ei_reg_delete(ei_regp, charp); ei_reg_stat(ei_regp, charp, ei_reg_statp); ei_reg_tabstat(ei_regp, ei_reg_tabstatp); ei_reg_dump(intx, ei_regp, charp, intx); ei_reg_restore(intx, ei_regp, charp); ei_reg_purge(ei_regp); #if defined(HAVE_GMP_H) && defined(HAVE_LIBGMP) { mpz_t obj; ei_decode_bignum(charp, intp, obj); ei_encode_bignum(charp, intp, obj); ei_x_encode_bignum(&eix, obj); } #endif /* HAVE_GMP_H && HAVE_LIBGMP */ #ifndef VXWORKS ei_decode_longlong(charp, intp, longlongp); ei_decode_ulonglong(charp, intp, ulonglongp); ei_encode_longlong(charp, intp, longlongx); ei_encode_ulonglong(charp, intp, ulonglongx); ei_x_encode_longlong(&eix, longlongx); ei_x_encode_ulonglong(&eix, ulonglongx); #endif #ifdef USE_EI_UNDOCUMENTED ei_decode_intlist(charp, intp, longp, intp); ei_receive_encoded(intx, &charp, intp, msgp, intp); ei_send_encoded(intx, pidp, charp, intx); ei_send_reg_encoded(intx, pidp, charp, charp, intx); ei_decode_big(charp, intp, bigp); ei_big_comp(bigp, bigp); ei_big_to_double(bigp, doublep); ei_small_to_big(intx, bigp); ei_alloc_big(intx); ei_free_big(bigp); #endif /* USE_EI_UNDOCUMENTED */ return BUFSIZ + EAGAIN + EHOSTUNREACH + EIO + EI_BIN + EI_DELET + EI_DIRTY + EI_FLT + EI_FORCE + EI_INT + EI_NOPURGE + EI_STR + EMSGSIZE + ENOMEM + ERL_ERROR + ERL_EXIT + ERL_LINK + ERL_MSG + ERL_NO_TIMEOUT + ERL_REG_SEND + ERL_SEND + ERL_TICK + ERL_TIMEOUT + ERL_UNLINK + ETIMEDOUT + MAXATOMLEN; }
/* * Function returns always success - we uses EPMD for transport */ int erl_rpc_send(erl_rpc_ctx_t *ctx, int depth) { if (ctx->response_sent) return 0; ctx->response_sent = 1; erl_rpc_ctx_t *handler; erl_rpc_param_t *fault = *(ctx->fault_p); if (fault) { LM_ERR("fault: %d %.*s\n",fault->type, STR_FMT(&fault->value.S)); /* restore clear point */ ctx->response->index = ctx->response_index; /* {error,{struct,[ {"code", 400}, {"error","Error message"}]}}*/ if (ei_x_encode_tuple_header(ctx->response,1)) goto error; /* {error,{_,_}} */ if (rpc_reply_with_struct && ei_x_encode_atom(ctx->response,"struct")) goto error; /* {error,{struct,_}} */ if (ei_x_encode_list_header(ctx->response,2)) goto error; /* {error,{struct,[_,_]}} */ if (ei_x_encode_tuple_header(ctx->response,2)) goto error; /* {error,{struct,[{_,_},_]}} */ if (ei_x_encode_atom(ctx->response,"code")) goto error; /* {error,{struct,[{code,_},_]}} */ if (ei_x_encode_long(ctx->response,fault->type)) goto error;/* {error,{struct,[{code,400},_]}} */ if (ei_x_encode_tuple_header(ctx->response,2)) goto error; /* {error,{struct,[{code,400},{_,_}]}} */ if (ei_x_encode_binary(ctx->response,"error",sizeof("error")-1)) goto error; /* {error,{struct,[{code,400},{<<"error">>,_}]}} */ if (ei_x_encode_binary(ctx->response,(void*)fault->value.S.s,fault->value.S.len)) /* {error,{struct,[{code,400},{<<"error">>,<<Msg>>}]}} */ goto error; if (ei_x_encode_empty_list(ctx->response)) goto error; } else if (ctx->reply_params) { while(ctx->reply_params) { if (ctx->reply_params->member_name) { /* {"member_name", _} */ if (ei_x_encode_tuple_header(ctx->response,2)) goto error; if (ei_x_encode_binary(ctx->response,ctx->reply_params->member_name, strlen(ctx->reply_params->member_name))) goto error; } /* {"member_name", MemberValue} */ switch (ctx->reply_params->type) { case ERL_INTEGER_EXT: if(ei_x_encode_long(ctx->response,ctx->reply_params->value.n)) goto error; break; case ERL_FLOAT_EXT: if(ei_x_encode_double(ctx->response,ctx->reply_params->value.d)) goto error; break; case ERL_STRING_EXT: if(ei_x_encode_binary(ctx->response,ctx->reply_params->value.S.s,ctx->reply_params->value.S.len)) goto error; break; case ERL_SMALL_TUPLE_EXT: /* add as {struct,list(no_params)} */ handler = (erl_rpc_ctx_t*)ctx->reply_params->value.handler; if (ei_x_encode_tuple_header(ctx->response,1)) goto error; if (rpc_reply_with_struct && ei_x_encode_atom(ctx->response,"struct")) goto error; if (ei_x_encode_list_header(ctx->response,handler->no_params)) goto error; if (erl_rpc_send(handler, depth++)) goto error; if (ei_x_encode_empty_list(ctx->response)) goto error; break; case ERL_LIST_EXT: /* add as [list(no_params)] */ handler = (erl_rpc_ctx_t*)ctx->reply_params->value.handler; if (ei_x_encode_list_header(ctx->response,handler->no_params)) goto error; if (erl_rpc_send(handler, depth++)) goto error; if (handler->no_params) if (ei_x_encode_empty_list(ctx->response)) goto error; break; default: LM_ERR("Unknown type '%c' for encoding RPC reply\n",ctx->reply_params->type); break; } ctx->reply_params=ctx->reply_params->next; } } else if (!depth) { /* restore start point */ LM_WARN("encode empty response -> ok"); ctx->response->index = ctx->response_index; if (ei_x_encode_atom(ctx->response,"ok")) goto error; } return 0; error: LM_ERR("error while encoding response\n"); return -1; }
int add_event_data(ei_x_buff* sendbuf, int topic, const void* data) { switch (topic) { case EVENT_COMMAND_FINISHED: { ei_x_encode_atom(sendbuf, "event_command_finished"); struct SCommandFinishedEvent* event_data = (struct SCommandFinishedEvent*)data; ei_x_encode_tuple_header(sendbuf, 6); { if (ei_x_encode_atom(sendbuf, "unitid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unitid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unitId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unitId); return -1; } } { if (ei_x_encode_atom(sendbuf, "commandid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "commandid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->commandId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->commandId); return -1; } } { if (ei_x_encode_atom(sendbuf, "commandtopicid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "commandtopicid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->commandTopicId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->commandTopicId); return -1; } } break; } case EVENT_ENEMY_CREATED: { ei_x_encode_atom(sendbuf, "event_enemy_created"); struct SEnemyCreatedEvent* event_data = (struct SEnemyCreatedEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "enemy") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "enemy"); return -1; } if (ei_x_encode_long(sendbuf, event_data->enemy) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->enemy); return -1; } } break; } case EVENT_ENEMY_DAMAGED: { ei_x_encode_atom(sendbuf, "event_enemy_damaged"); struct SEnemyDamagedEvent* event_data = (struct SEnemyDamagedEvent*)data; ei_x_encode_tuple_header(sendbuf, 12); { if (ei_x_encode_atom(sendbuf, "enemy") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "enemy"); return -1; } if (ei_x_encode_long(sendbuf, event_data->enemy) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->enemy); return -1; } } { if (ei_x_encode_atom(sendbuf, "attacker") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "attacker"); return -1; } if (ei_x_encode_long(sendbuf, event_data->attacker) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->attacker); return -1; } } { if (ei_x_encode_atom(sendbuf, "damage") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "damage"); return -1; } if (ei_x_encode_double(sendbuf, event_data->damage) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->damage); return -1; } } { if (ei_x_encode_atom(sendbuf, "dir_posf3") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "dir_posf3"); return -1; } if (ei_x_encode_tuple_header(sendbuf, 3) < 0) { fprintf(stderr, "cannot encode '%i' as 'tuple_header'\n", 3); return -1; } if (ei_x_encode_double(sendbuf, event_data->dir_posF3[0]) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->dir_posF3[0]); return -1; } if (ei_x_encode_double(sendbuf, event_data->dir_posF3[1]) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->dir_posF3[1]); return -1; } if (ei_x_encode_double(sendbuf, event_data->dir_posF3[2]) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->dir_posF3[2]); return -1; } } { if (ei_x_encode_atom(sendbuf, "weapondefid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "weapondefid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->weaponDefId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->weaponDefId); return -1; } } { if (ei_x_encode_atom(sendbuf, "paralyzer") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "paralyzer"); return -1; } if (ei_x_encode_atom(sendbuf, event_data->paralyzer ? "true" : "false") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", event_data->paralyzer ? "true" : "false"); return -1; } } break; } case EVENT_ENEMY_DESTROYED: { ei_x_encode_atom(sendbuf, "event_enemy_destroyed"); struct SEnemyDestroyedEvent* event_data = (struct SEnemyDestroyedEvent*)data; ei_x_encode_tuple_header(sendbuf, 4); { if (ei_x_encode_atom(sendbuf, "enemy") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "enemy"); return -1; } if (ei_x_encode_long(sendbuf, event_data->enemy) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->enemy); return -1; } } { if (ei_x_encode_atom(sendbuf, "attacker") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "attacker"); return -1; } if (ei_x_encode_long(sendbuf, event_data->attacker) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->attacker); return -1; } } break; } case EVENT_ENEMY_ENTER_LOS: { ei_x_encode_atom(sendbuf, "event_enemy_enter_los"); struct SEnemyEnterLOSEvent* event_data = (struct SEnemyEnterLOSEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "enemy") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "enemy"); return -1; } if (ei_x_encode_long(sendbuf, event_data->enemy) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->enemy); return -1; } } break; } case EVENT_ENEMY_ENTER_RADAR: { ei_x_encode_atom(sendbuf, "event_enemy_enter_radar"); struct SEnemyEnterRadarEvent* event_data = (struct SEnemyEnterRadarEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "enemy") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "enemy"); return -1; } if (ei_x_encode_long(sendbuf, event_data->enemy) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->enemy); return -1; } } break; } case EVENT_ENEMY_FINISHED: { ei_x_encode_atom(sendbuf, "event_enemy_finished"); struct SEnemyFinishedEvent* event_data = (struct SEnemyFinishedEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "enemy") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "enemy"); return -1; } if (ei_x_encode_long(sendbuf, event_data->enemy) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->enemy); return -1; } } break; } case EVENT_ENEMY_LEAVE_LOS: { ei_x_encode_atom(sendbuf, "event_enemy_leave_los"); struct SEnemyLeaveLOSEvent* event_data = (struct SEnemyLeaveLOSEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "enemy") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "enemy"); return -1; } if (ei_x_encode_long(sendbuf, event_data->enemy) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->enemy); return -1; } } break; } case EVENT_ENEMY_LEAVE_RADAR: { ei_x_encode_atom(sendbuf, "event_enemy_leave_radar"); struct SEnemyLeaveRadarEvent* event_data = (struct SEnemyLeaveRadarEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "enemy") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "enemy"); return -1; } if (ei_x_encode_long(sendbuf, event_data->enemy) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->enemy); return -1; } } break; } case EVENT_LOAD: { ei_x_encode_atom(sendbuf, "event_load"); struct SLoadEvent* event_data = (struct SLoadEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "file") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "file"); return -1; } if (ei_x_encode_string(sendbuf, event_data->file) < 0) { fprintf(stderr, "cannot encode '%s' as 'string'\n", event_data->file); return -1; } } break; } case EVENT_LUA_MESSAGE: { ei_x_encode_atom(sendbuf, "event_lua_message"); struct SLuaMessageEvent* event_data = (struct SLuaMessageEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "indata") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "indata"); return -1; } if (ei_x_encode_string(sendbuf, event_data->inData) < 0) { fprintf(stderr, "cannot encode '%s' as 'string'\n", event_data->inData); return -1; } } break; } case EVENT_MESSAGE: { ei_x_encode_atom(sendbuf, "event_message"); struct SMessageEvent* event_data = (struct SMessageEvent*)data; ei_x_encode_tuple_header(sendbuf, 4); { if (ei_x_encode_atom(sendbuf, "player") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "player"); return -1; } if (ei_x_encode_long(sendbuf, event_data->player) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->player); return -1; } } { if (ei_x_encode_atom(sendbuf, "message") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "message"); return -1; } if (ei_x_encode_string(sendbuf, event_data->message) < 0) { fprintf(stderr, "cannot encode '%s' as 'string'\n", event_data->message); return -1; } } break; } case EVENT_RELEASE: { ei_x_encode_atom(sendbuf, "event_release"); struct SReleaseEvent* event_data = (struct SReleaseEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "reason") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "reason"); return -1; } if (ei_x_encode_long(sendbuf, event_data->reason) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->reason); return -1; } } break; } case EVENT_SAVE: { ei_x_encode_atom(sendbuf, "event_save"); struct SSaveEvent* event_data = (struct SSaveEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "file") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "file"); return -1; } if (ei_x_encode_string(sendbuf, event_data->file) < 0) { fprintf(stderr, "cannot encode '%s' as 'string'\n", event_data->file); return -1; } } break; } case EVENT_SEISMIC_PING: { ei_x_encode_atom(sendbuf, "event_seismic_ping"); struct SSeismicPingEvent* event_data = (struct SSeismicPingEvent*)data; ei_x_encode_tuple_header(sendbuf, 4); { if (ei_x_encode_atom(sendbuf, "pos_posf3") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "pos_posf3"); return -1; } if (ei_x_encode_tuple_header(sendbuf, 3) < 0) { fprintf(stderr, "cannot encode '%i' as 'tuple_header'\n", 3); return -1; } if (ei_x_encode_double(sendbuf, event_data->pos_posF3[0]) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->pos_posF3[0]); return -1; } if (ei_x_encode_double(sendbuf, event_data->pos_posF3[1]) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->pos_posF3[1]); return -1; } if (ei_x_encode_double(sendbuf, event_data->pos_posF3[2]) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->pos_posF3[2]); return -1; } } { if (ei_x_encode_atom(sendbuf, "strength") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "strength"); return -1; } if (ei_x_encode_double(sendbuf, event_data->strength) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->strength); return -1; } } break; } case EVENT_UNIT_CAPTURED: { ei_x_encode_atom(sendbuf, "event_unit_captured"); struct SUnitCapturedEvent* event_data = (struct SUnitCapturedEvent*)data; ei_x_encode_tuple_header(sendbuf, 6); { if (ei_x_encode_atom(sendbuf, "unitid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unitid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unitId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unitId); return -1; } } { if (ei_x_encode_atom(sendbuf, "oldteamid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "oldteamid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->oldTeamId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->oldTeamId); return -1; } } { if (ei_x_encode_atom(sendbuf, "newteamid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "newteamid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->newTeamId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->newTeamId); return -1; } } break; } case EVENT_UNIT_CREATED: { ei_x_encode_atom(sendbuf, "event_unit_created"); struct SUnitCreatedEvent* event_data = (struct SUnitCreatedEvent*)data; ei_x_encode_tuple_header(sendbuf, 4); { if (ei_x_encode_atom(sendbuf, "unit") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unit"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unit) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unit); return -1; } } { if (ei_x_encode_atom(sendbuf, "builder") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "builder"); return -1; } if (ei_x_encode_long(sendbuf, event_data->builder) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->builder); return -1; } } break; } case EVENT_UNIT_DAMAGED: { ei_x_encode_atom(sendbuf, "event_unit_damaged"); struct SUnitDamagedEvent* event_data = (struct SUnitDamagedEvent*)data; ei_x_encode_tuple_header(sendbuf, 12); { if (ei_x_encode_atom(sendbuf, "unit") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unit"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unit) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unit); return -1; } } { if (ei_x_encode_atom(sendbuf, "attacker") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "attacker"); return -1; } if (ei_x_encode_long(sendbuf, event_data->attacker) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->attacker); return -1; } } { if (ei_x_encode_atom(sendbuf, "damage") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "damage"); return -1; } if (ei_x_encode_double(sendbuf, event_data->damage) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->damage); return -1; } } { if (ei_x_encode_atom(sendbuf, "dir_posf3") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "dir_posf3"); return -1; } if (ei_x_encode_tuple_header(sendbuf, 3) < 0) { fprintf(stderr, "cannot encode '%i' as 'tuple_header'\n", 3); return -1; } if (ei_x_encode_double(sendbuf, event_data->dir_posF3[0]) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->dir_posF3[0]); return -1; } if (ei_x_encode_double(sendbuf, event_data->dir_posF3[1]) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->dir_posF3[1]); return -1; } if (ei_x_encode_double(sendbuf, event_data->dir_posF3[2]) < 0) { fprintf(stderr, "cannot encode '%f' as 'double'\n", event_data->dir_posF3[2]); return -1; } } { if (ei_x_encode_atom(sendbuf, "weapondefid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "weapondefid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->weaponDefId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->weaponDefId); return -1; } } { if (ei_x_encode_atom(sendbuf, "paralyzer") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "paralyzer"); return -1; } if (ei_x_encode_atom(sendbuf, event_data->paralyzer ? "true" : "false") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", event_data->paralyzer ? "true" : "false"); return -1; } } break; } case EVENT_UNIT_DESTROYED: { ei_x_encode_atom(sendbuf, "event_unit_destroyed"); struct SUnitDestroyedEvent* event_data = (struct SUnitDestroyedEvent*)data; ei_x_encode_tuple_header(sendbuf, 4); { if (ei_x_encode_atom(sendbuf, "unit") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unit"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unit) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unit); return -1; } } { if (ei_x_encode_atom(sendbuf, "attacker") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "attacker"); return -1; } if (ei_x_encode_long(sendbuf, event_data->attacker) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->attacker); return -1; } } break; } case EVENT_UNIT_FINISHED: { ei_x_encode_atom(sendbuf, "event_unit_finished"); struct SUnitFinishedEvent* event_data = (struct SUnitFinishedEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "unit") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unit"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unit) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unit); return -1; } } break; } case EVENT_UNIT_GIVEN: { ei_x_encode_atom(sendbuf, "event_unit_given"); struct SUnitGivenEvent* event_data = (struct SUnitGivenEvent*)data; ei_x_encode_tuple_header(sendbuf, 6); { if (ei_x_encode_atom(sendbuf, "unitid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unitid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unitId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unitId); return -1; } } { if (ei_x_encode_atom(sendbuf, "oldteamid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "oldteamid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->oldTeamId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->oldTeamId); return -1; } } { if (ei_x_encode_atom(sendbuf, "newteamid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "newteamid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->newTeamId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->newTeamId); return -1; } } break; } case EVENT_UNIT_IDLE: { ei_x_encode_atom(sendbuf, "event_unit_idle"); struct SUnitIdleEvent* event_data = (struct SUnitIdleEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "unit") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unit"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unit) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unit); return -1; } } break; } case EVENT_UNIT_MOVE_FAILED: { ei_x_encode_atom(sendbuf, "event_unit_move_failed"); struct SUnitMoveFailedEvent* event_data = (struct SUnitMoveFailedEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "unit") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unit"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unit) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unit); return -1; } } break; } case EVENT_UPDATE: { ei_x_encode_atom(sendbuf, "event_update"); struct SUpdateEvent* event_data = (struct SUpdateEvent*)data; ei_x_encode_tuple_header(sendbuf, 2); { if (ei_x_encode_atom(sendbuf, "frame") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "frame"); return -1; } if (ei_x_encode_long(sendbuf, event_data->frame) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->frame); return -1; } } break; } case EVENT_WEAPON_FIRED: { ei_x_encode_atom(sendbuf, "event_weapon_fired"); struct SWeaponFiredEvent* event_data = (struct SWeaponFiredEvent*)data; ei_x_encode_tuple_header(sendbuf, 4); { if (ei_x_encode_atom(sendbuf, "unitid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "unitid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->unitId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->unitId); return -1; } } { if (ei_x_encode_atom(sendbuf, "weapondefid") < 0) { fprintf(stderr, "cannot encode '%s' as 'atom'\n", "weapondefid"); return -1; } if (ei_x_encode_long(sendbuf, event_data->weaponDefId) < 0) { fprintf(stderr, "cannot encode '%i' as 'long'\n", event_data->weaponDefId); return -1; } } break; } default: { ei_x_encode_long(sendbuf, topic); ei_x_encode_binary(sendbuf, data, sizeof(data)); } } return 0; }
int joo_write (int fd, JooTerm *terms) { int ret = 0; ei_x_buff buf; if (joo_term_count_children (terms) < 0) return -1; if (ei_x_new_with_version (&buf)) { errno = ENOMEM; return -1; } for (JooTerm *term = terms; term->type != JOO_END; term++) { if (term->push) { errno = EINVAL; return -1; } switch (term->type) { case JOO_ATOM: if (ei_x_encode_atom (&buf, term->value.text)) { errno = ENOMEM; return -1; } break; case JOO_STRING: if (ei_x_encode_string (&buf, term->value.text)) { errno = ENOMEM; return -1; } break; case JOO_BINARY: if (ei_x_encode_binary (&buf, term->value.binary.data, term->value.binary.size)) { errno = ENOMEM; return -1; } break; case JOO_TUPLE_START: if (ei_x_encode_tuple_header (&buf, term->num_children)) { errno = ENOMEM; return -1; } break; case JOO_TUPLE_END: break; default: abort (); } } if (write_ei_x_buff (fd, &buf) < 0) { errno = EIO; ret = -1; } ei_x_free (&buf); return ret; }
static int control(ErlDrvData handle, unsigned int command, char* buf, int count, char** res, int res_size) { tcbdb_drv_t *driver = (tcbdb_drv_t*)handle; TCBDB *bdb = driver->bdb; int index = 1, tp, sz, version; char key[MAX_KEY_SIZE], value[MAX_VALUE_SIZE]; long key_size, value_size; long long long_tmp; bool rs; const char *value_tmp = NULL; ei_x_buff x; ei_x_new_with_version(&x); if (bdb == NULL && command != OPEN) return ei_error(&x, "database_not_opened", res, res_size); ei_decode_version(buf, &index, &version); switch (command) { case OPEN: // open(Filepath::string()) if (bdb == NULL) { ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_STRING_EXT) return ei_error(&x, "invalid_argument", res, res_size); TCBDB *bdb = tcbdbnew(); tcbdbsetmutex(bdb); tcbdbsetcache(bdb, 104800, 51200); tcbdbsetxmsiz(bdb, 1048576); tcbdbtune(bdb, 0, 0, 0, 7, -1, BDBTLARGE); char *file = driver_alloc(sz + 1); ei_decode_string(buf, &index, file); rs = tcbdbopen(bdb, file, BDBOWRITER | BDBOCREAT); driver_free(file); if (!rs) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); driver->bdb = bdb; ei_x_encode_atom(&x, "ok"); } else return ei_error(&x, "database already opened", res, res_size); break; case CLOSE: tcbdbclose(bdb); tcbdbdel(bdb); driver->bdb = NULL; ei_x_encode_atom(&x, "ok"); break; case PUT: case PUTDUP: case PUTCAT: case PUTKEEP: // put({Key::binary(), Value::binary()}) ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_SMALL_TUPLE_EXT || sz != 2) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_tuple_header(buf, &index, &sz); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT) return ei_error(&x, "invalid_argument", res, res_size); if (sz <= MAX_VALUE_SIZE) { ei_decode_binary(buf, &index, &value[0], &value_size); switch (command) { case PUT: rs = tcbdbput(bdb, &key[0], key_size, &value[0], value_size); break; case PUTDUP: rs = tcbdbputdup(bdb, &key[0], key_size, &value[0], value_size); break; case PUTCAT: rs = tcbdbputcat(bdb, &key[0], key_size, &value[0], value_size); break; default: rs = tcbdbputkeep(bdb, &key[0], key_size, &value[0], value_size); } } else { void *p = driver_alloc(sz); if (p) { ei_decode_binary(buf, &index, p, &value_size); switch (command) { case PUT: rs = tcbdbput(bdb, &key[0], key_size, p, value_size); break; case PUTDUP: rs = tcbdbputdup(bdb, &key[0], key_size, p, value_size); break; case PUTCAT: rs = tcbdbputcat(bdb, &key[0], key_size, p, value_size); break; default: rs = tcbdbputkeep(bdb, &key[0], key_size, p, value_size); } driver_free(p); } else return ei_error(&x, "too long value", res, res_size); }; if (!rs) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); ei_x_encode_atom(&x, "ok"); break; case GET: // get(Key::binary()) -> {ok, Value} | {error, not_found} ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); value_tmp = tcbdbget3(bdb, &key[0], key_size, &sz); ei_x_encode_tuple_header(&x, 2); if (value_tmp != NULL) { ei_x_encode_atom(&x, "ok"); ei_x_encode_binary(&x, value_tmp, sz); } else { ei_x_encode_atom(&x, "error"); ei_x_encode_atom(&x, "not_found"); } break; case GETDUP: // get(Key::binary()) -> {ok, Values} ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); TCLIST *vals = tcbdbget4(bdb, key, key_size); if (vals) { ei_x_encode_tuple_header(&x, 2); ei_x_encode_atom(&x, "ok"); int j; for (j=0; j<tclistnum(vals); j++) { value_tmp = tclistval(vals, j, &sz); ei_x_encode_list_header(&x, 1); ei_x_encode_binary(&x, value_tmp, sz); } tclistdel(vals); ei_x_encode_empty_list(&x); } else { ei_x_encode_tuple_header(&x, 2); ei_x_encode_atom(&x, "ok"); ei_x_encode_empty_list(&x); } break; case REMOVE: // remove(Keys::list()) // remove(Key::binary()) // remove({Key::binary(), Value::binary()}) ei_get_type(buf, &index, &tp, &sz); if (tp == ERL_LIST_EXT) { int count, j; ei_decode_list_header(buf, &index, &count); for (j=0; j<count; j++) { ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); if (!tcbdbout3(bdb, &key[0], key_size)) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); } ei_x_encode_atom(&x, "ok"); } else if (tp == ERL_BINARY_EXT && sz <= MAX_KEY_SIZE) { ei_decode_binary(buf, &index, &key[0], &key_size); tcbdbout3(bdb, &key[0], key_size); ei_x_encode_atom(&x, "ok"); } else if (tp == ERL_SMALL_TUPLE_EXT && sz == 2) { ei_decode_tuple_header(buf, &index, &sz); // get key ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); // get value ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_VALUE_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &value[0], &value_size); // remove by key&value BDBCUR *cur = tcbdbcurnew(bdb); if (!tcbdbcurjump(cur, &key[0], key_size)) return ei_error(&x, "record_not_found", res, res_size); bool removed = false, not_found = false; while (!removed && !not_found) { int cur_key_size, cur_val_size; const void *curkey = tcbdbcurkey3(cur, &cur_key_size); if (cur_key_size == key_size && memcmp(curkey, key, key_size) == 0) { const void *curval = tcbdbcurval3(cur, &cur_val_size); if (cur_val_size == value_size && memcmp(curval, value, value_size) == 0) { tcbdbcurout(cur); removed = true; } else if (!tcbdbcurnext(cur)) not_found = true; } else not_found = true; } if (not_found) ei_x_encode_atom(&x, "not_found"); else ei_x_encode_atom(&x, "ok"); } else return ei_error(&x, "invalid_argument", res, res_size); break; case RANGE: /* * range({Prefix::binary(), limit:integer()}) * range({StartKey::binary(), BeginInclusion::boolean(), EndKey::binary(), EndInclusion::binary(), limit:integer()}) */ ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_SMALL_TUPLE_EXT || sz < 2) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_tuple_header(buf, &index, &sz); ei_get_type(buf, &index, &tp, &sz); if (tp == ERL_BINARY_EXT && sz <= MAX_KEY_SIZE) { char keys[MAX_KEY_SIZE], keyf[MAX_KEY_SIZE]; long keys_size, keyf_size; int keys_inc, keyf_inc; long max = -1; TCLIST *range; ei_decode_binary(buf, &index, &keys[0], &keys_size); ei_get_type(buf, &index, &tp, &sz); if (tp == ERL_ATOM_EXT) { // range ei_decode_boolean(buf, &index, &keys_inc); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &keyf[0], &keyf_size); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_ATOM_EXT) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_boolean(buf, &index, &keyf_inc); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_INTEGER_EXT) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_long(buf, &index, &max); range = tcbdbrange(bdb, &keys[0], keys_size, keys_inc == 1, &keyf[0], keyf_size, keyf_inc == 1, max); } else if (tp == ERL_INTEGER_EXT) { // prefix ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_INTEGER_EXT) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_long(buf, &index, &max); range = tcbdbfwmkeys(bdb, &keys[0], keys_size, max); } else return ei_error(&x, "invalid_argument", res, res_size); const char *key; int key_size, value_size; int idx, cnt = 0, rcount = tclistnum(range); ei_x_encode_tuple_header(&x, 2); ei_x_encode_atom(&x, "ok"); BDBCUR *cur = tcbdbcurnew(bdb); for (idx=0; idx<rcount; idx++) { key = tclistval(range, idx, &key_size); TCLIST *vals = tcbdbget4(bdb, key, key_size); if (vals) { int j; for (j=0; j<tclistnum(vals); j++) { ei_x_encode_list_header(&x, 1); value_tmp = tclistval(vals, j, &value_size); ei_x_encode_binary(&x, value_tmp, value_size); if (max >= 0 && ++cnt >= max) break; } tclistdel(vals); } idx++; } tcbdbcurdel(cur); tclistdel(range); ei_x_encode_empty_list(&x); } else return ei_error(&x, "invalid_argument", res, res_size); break; case SYNC: // sync() if (!tcbdbsync(bdb)) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); ei_x_encode_atom(&x, "ok"); break; case INFO: // info() ei_x_encode_tuple_header(&x, 3); ei_x_encode_atom(&x, "ok"); long_tmp = tcbdbrnum(bdb); ei_x_encode_longlong(&x, long_tmp); long_tmp = tcbdbfsiz(bdb); ei_x_encode_longlong(&x, long_tmp); break; case ITERATE: // Read(none) -> {ok, Key} | {error, not_found} // Read(Key::binary()) -> {ok, Key} | {error, not_found} ei_get_type(buf, &index, &tp, &sz); BDBCUR *cur = tcbdbcurnew(bdb); if (tp == ERL_BINARY_EXT && sz <= MAX_KEY_SIZE) { ei_decode_binary(buf, &index, &key[0], &key_size); rs = tcbdbcurjump(cur, &key[0], key_size) && tcbdbcurnext(cur); } else rs = tcbdbcurfirst(cur); if (rs) { int key_size; const char *key = tcbdbcurkey3(cur, &key_size); ei_x_encode_tuple_header(&x, 2); ei_x_encode_atom(&x, "ok"); ei_x_encode_binary(&x, key, key_size); tcbdbcurdel(cur); } else { tcbdbcurdel(cur); return ei_error(&x, "not_found", res, res_size); } break; case VANISH: // vanish() -> ok if (!tcbdbvanish(bdb)) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); ei_x_encode_atom(&x, "ok"); break; case BACKUP: // backup(path::string()) -> ok | {error, Reason} ei_get_type(buf, &index, &tp, &sz); if (tp == ERL_STRING_EXT) { char *file = driver_alloc(sz + 1); ei_decode_string(buf, &index, file); if (tcbdbcopy(driver->bdb, file)) ei_x_encode_atom(&x, "ok"); else return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); } else return ei_error(&x, "invalid_argument", res, res_size); break; default: return ei_error(&x, "invalid_command", res, res_size); } if (res_size < x.index) (*res) = (char *)driver_alloc(x.index); int n = x.index; memcpy(*res, x.buff, x.index); ei_x_free(&x); return n; };
static int erlang_query(DICT_ERLANG *dict_erlang, const char *key, ARGV *nodes, char *cookie, char *mod, char *fun, char **res) { int cur_node; int err, index, retries; int res_version, res_type, res_size; int fd; ei_cnode ec; ei_x_buff args; ei_x_buff resp; VSTRING *node_name; node_name = vstring_alloc(15); /* Get an "unique" name for the node */ vstring_sprintf(node_name, "dict_erlang%u", getpid() % 999); err = ei_connect_init(&ec, vstring_str(node_name), cookie, 0); if (err != 0) { msg_warn_erl("ei_connect_init"); return -1; } retries = 3; retry: cur_node = dict_erlang->active_node; do { fd = ei_connect(&ec, nodes->argv[cur_node]); if (fd >= 0) { dict_erlang->active_node = cur_node; if (msg_verbose) msg_info("connected to node %s", nodes->argv[cur_node]); break; } cur_node = (cur_node + 1) % nodes->argc; } while (cur_node != dict_erlang->active_node); if (fd < 0) { if (retries > 0 && erl_errno == EIO) { msg_warn_erl("no suitable nodes found, retrying"); retries--; goto retry; } msg_warn_erl("no suitable nodes found, failing"); return -1; } ei_x_new(&args); ei_x_new(&resp); ei_x_encode_list_header(&args, 1); ei_x_encode_binary(&args, key, strlen(key)); ei_x_encode_empty_list(&args); err = ei_rpc(&ec, fd, mod, fun, args.buff, args.index, &resp); if (err == -1) { msg_warn_erl("ei_rpc"); goto cleanup; } err = handle_response(dict_erlang, key, &resp, res); cleanup: close(fd); ei_x_free(&args); ei_x_free(&resp); return err; }
static inline void write_binary(State *p, const char* s, unsigned len) { ei_x_encode_binary(&p->ei_buf, s, len); }