/* ** Data sent from erlang to port. */ static void trace_file_output(ErlDrvData handle, char *buf, ErlDrvSizeT len) { int index = 1; ei_print_term(stdout, buf, &index); erts_printf("\n"); /* erts_printf("output: %d: %u\n", rc, (unsigned char)buff[0]); */ int arity; char atom[MAXATOMLEN]; char type[MAXATOMLEN]; char pidstr[100]; index = 1; erlang_pid pid; if(!ei_decode_tuple_header(buf, &index, &arity)) { if(!ei_decode_atom(buf, &index, atom)) { if(strcmp("trace", atom) == 0) { if(!ei_decode_pid(buf, &index, &pid)) { if(!ei_decode_atom(buf, &index, type)) { snprintf(pidstr, 100, "<0.%d.%d>", pid.num, pid.serial); erts_printf("%s: %s\n", pidstr, type); dispatch(pidstr, type, index, buf); } } } } } }
static switch_status_t handle_msg_sendevent(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char ename[MAXATOMLEN + 1]; char esname[MAXATOMLEN + 1]; int headerlength; memset(esname, 0, MAXATOMLEN); if (ei_decode_atom(buf->buff, &buf->index, ename) || (!strncasecmp(ename, "CUSTOM", MAXATOMLEN) && ei_decode_atom(buf->buff, &buf->index, esname)) || ei_decode_list_header(buf->buff, &buf->index, &headerlength)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { switch_event_types_t etype; if (switch_name_event(ename, &etype) == SWITCH_STATUS_SUCCESS) { switch_event_t *event; if ((strlen(esname) && switch_event_create_subclass(&event, etype, esname) == SWITCH_STATUS_SUCCESS) || switch_event_create(&event, etype) == SWITCH_STATUS_SUCCESS) { char key[1024]; char value[1024]; int i = 0; switch_bool_t fail = SWITCH_FALSE; while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) { i++; if (ei_decode_string(buf->buff, &buf->index, key) || ei_decode_string(buf->buff, &buf->index, value)) { fail = SWITCH_TRUE; break; } switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value); } if (headerlength != i || fail) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { switch_event_fire(&event); ei_x_encode_atom(rbuf, "ok"); } } } } return SWITCH_STATUS_SUCCESS; }
static void handle_flush(const char *req, int *req_index) { char dirstr[MAXATOMLEN]; if (ei_decode_atom(req, req_index, dirstr) < 0) { send_error_response("einval"); return; } enum uart_direction direction; if (strcmp(dirstr, "receive") == 0) direction = UART_DIRECTION_RECEIVE; else if (strcmp(dirstr, "transmit") == 0) direction = UART_DIRECTION_TRANSMIT; else if (strcmp(dirstr, "both") == 0) direction = UART_DIRECTION_BOTH; else { send_error_response("einval"); return; } if (!uart_is_open(uart)) { send_error_response("ebadf"); return; } if (uart_flush(uart, direction) >= 0) send_ok_response(); else send_error_response(uart_last_error()); }
static int update_list(struct exmpp_hashtable *kl, const char *buf, int *index) { int nb_items, i, type, item_len; char item[MAXATOMLEN]; /* We check that we have a real list. */ if (ei_decode_list_header(buf, index, &nb_items) != 0) return (-1); if (nb_items < 0) return (0); for (i = 0; i < nb_items; ++i) { /* Decode the item. */ if (ei_get_type(buf, index, &type, &item_len) != 0) return (-1); if (ei_decode_atom(buf, index, item) != 0) return (-1); /* Add it to the list. */ if (!exmpp_ht_exists(kl, item, item_len)) exmpp_ht_store(kl, item, item_len, &DUMMY); } return (0); }
/* * A true RPC. It return a NULL pointer * in case of failure, otherwise a valid * (ETERM *) pointer containing the reply */ int ei_rpc(ei_cnode* ec, int fd, char *mod, char *fun, const char* inbuf, int inbuflen, ei_x_buff* x) { int i, index; ei_term t; erlang_msg msg; char rex[MAXATOMLEN]; if (ei_rpc_to(ec, fd, mod, fun, inbuf, inbuflen) < 0) { return -1; } /* FIXME are we not to reply to the tick? */ while ((i = ei_rpc_from(ec, fd, ERL_NO_TIMEOUT, &msg, x)) == ERL_TICK) ; if (i == ERL_ERROR) return -1; /*ep = 'erl'_element(2,emsg.msg);*/ /* {RPC_Tag, RPC_Reply} */ index = 0; if (ei_decode_version(x->buff, &index, &i) < 0 || ei_decode_ei_term(x->buff, &index, &t) < 0) return -1; /* FIXME ei_decode_version don't set erl_errno as before */ /* FIXME this is strange, we don't check correct "rex" atom and we let it pass if not ERL_SMALL_TUPLE_EXT and arity == 2 */ if (t.ei_type == ERL_SMALL_TUPLE_EXT && t.arity == 2) if (ei_decode_atom(x->buff, &index, rex) < 0) return -1; /* remove header */ x->index -= index; memmove(x->buff, &x->buff[index], x->index); return 0; }
/** * @brief Decode and forward requests from Elixir to the appropriate handlers * @param req the undecoded request * @param cookie */ static void handle_elixir_request(const char *req, void *cookie) { (void) cookie; // Commands are of the form {Command, Arguments}: // { atom(), term() } int req_index = sizeof(uint16_t); if (ei_decode_version(req, &req_index, NULL) < 0) errx(EXIT_FAILURE, "Message version issue?"); int arity; if (ei_decode_tuple_header(req, &req_index, &arity) < 0 || arity != 2) errx(EXIT_FAILURE, "expecting {cmd, args} tuple"); char cmd[MAXATOMLEN]; if (ei_decode_atom(req, &req_index, cmd) < 0) errx(EXIT_FAILURE, "expecting command atom"); for (struct request_handler *rh = request_handlers; rh->name != NULL; rh++) { if (strcmp(cmd, rh->name) == 0) { rh->handler(req, &req_index); return; } } errx(EXIT_FAILURE, "unknown command: %s", cmd); }
int next_pointer(GEOSCommand *command, int argc, char *name, void** data) { int arity; char atom[MAXATOMLEN]; unsigned long pointer; //decode tuple if(ei_decode_tuple_header(command->param_bytes, &command->index, &arity)) { return -1; } //verify if it's the right label if(arity!=argc) { return -1; } //decode pointer label if(ei_decode_atom(command->param_bytes,&command->index, atom)) { return -1; } if(strcmp(atom,name)) { return -1; } //decode the pointer if(ei_decode_ulong(command->param_bytes, &command->index, &pointer)) { return -1; } *data = (void *) pointer; return 0; }
static int select_known_elems(struct exmpp_xml_ctx *ctx, const char *buf, int index) { int type, list_name_len; char list_name[MAXATOMLEN]; struct exmpp_hashtable *kl; if (ei_get_type(buf, &index, &type, &list_name_len) != 0) return (-1); if (ei_decode_atom(buf, &index, list_name) != 0) return (-1); if (strcmp(list_name, "false") == 0) { ctx->check_elems = 0; return (0); } if (strcmp(list_name, "true") == 0) { if (ctx->known_elems == NULL) return (-1); ctx->check_elems = 1; return (0); } kl = exmpp_ht_fetch(known_elems_index, list_name, list_name_len); if (kl == NULL) return (-1); ctx->known_elems = kl; ctx->check_elems = 1; return (0); }
ETERM *erl_global_whereis(int fd, const char *name, char *node) { char buf[EISMALLBUF]; char *bufp=buf; char tmpbuf[64]; int index = 0; erlang_pid *self = erl_self(); erlang_pid epid; ETERM *opid; erlang_msg msg; int i; int version,arity,msglen; self->num = fd; /* FIXME looks strange to change something?! */ ei_encode_version(buf,&index); ei_encode_tuple_header(buf,&index,2); ei_encode_pid(buf,&index,self); /* PidFrom */ ei_encode_tuple_header(buf,&index,5); ei_encode_atom(buf,&index,"call"); /* call */ ei_encode_atom(buf,&index,"global"); /* Mod */ ei_encode_atom(buf,&index,"whereis_name"); /* Fun */ ei_encode_list_header(buf,&index,1); /* Args: [ name ] */ ei_encode_atom(buf,&index,name); ei_encode_empty_list(buf,&index); ei_encode_atom(buf,&index,"user"); /* user */ /* make the rpc call */ if (ei_send_reg_encoded(fd,self,"rex",buf,index)) return NULL; while (1) { index = EISMALLBUF; if (!(i = ei_recv_internal(fd,&bufp,&index,&msg,&msglen,1,0))) continue; else break; } if (i != ERL_SEND) return NULL; /* expecting { rex, pid } */ index = 0; if (ei_decode_version(buf,&index,&version) || ei_decode_tuple_header(buf,&index,&arity) || (arity != 2) || ei_decode_atom(buf,&index,tmpbuf) || strcmp(tmpbuf,"rex") || ei_decode_pid(buf,&index,&epid)) return NULL; /* bad response from other side */ /* put the pid into a format for the caller */ index = 0; ei_encode_pid(buf,&index,&epid); opid = erl_decode((unsigned char*)buf); /* extract the nodename for the caller */ if (node) strcpy(node,epid.node); return opid; }
/*----------------------------------------------------------------- * MAIN *----------------------------------------------------------------*/ int main(int argc, char *argv[]) { byte* buf; int size = BUF_SIZE; if (argc > 1) { test(argc, argv); return 0; } fprintf(stderr, "gssapi started\r\n"); if ((buf = malloc(size)) == NULL) return -1; while ( (buf = read_cmd(buf, &size)) ) { int res = 0; int index = 0; int version, arity; char command[MAXATOMLEN]; ei_x_buff result; port_func func; /* Ensure that we are receiving the binary term by reading and * stripping the version byte */ EI(ei_decode_version(buf, &index, &version)); /* Our marshalling spec is that we are expecting a tuple {Command, Arg1} */ EI(ei_decode_tuple_header(buf, &index, &arity)); EI(arity != 2); EI(ei_decode_atom(buf, &index, command)); /* Prepare the output buffer that will hold {ok, Result} or {error, Reason} */ EI(ei_x_new_with_version(&result) || ei_x_encode_tuple_header(&result, 2)); /* fprintf(stderr, "command: %s\r\n", command); */ func = lookup_func(command); if (func) { res = func(buf, index, &result); } else { EI(ei_x_encode_atom(&result, "error") || ei_x_encode_atom(&result, "unsupported_command")); } write_cmd(&result); ei_x_free(&result); } /* error: */ fprintf(stderr, "No more command, exiting\r\n"); return 0; }
QByteArray toArray() const { int idx = _index; QByteArray a(_size, 0); if (isAtom()) ei_decode_atom(_buf, &idx, a.data()); else ei_decode_string(_buf, &idx, a.data()); return a; }
static switch_status_t handle_msg_session_event(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; if (arity == 1) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { session_elem_t *session; if ((session = find_session_elem_by_pid(listener, &msg->from))) { int custom = 0; switch_event_types_t type; int i = 0; switch_thread_rwlock_wrlock(session->event_rwlock); for (i = 1; i < arity; i++) { if (!ei_decode_atom(buf->buff, &buf->index, atom)) { if (custom) { switch_core_hash_insert(session->event_hash, atom, MARKER); } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) { if (type == SWITCH_EVENT_ALL) { uint32_t x = 0; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ALL events enabled for %s\n", session->uuid_str); for (x = 0; x < SWITCH_EVENT_ALL; x++) { session->event_list[x] = 1; } } if (type <= SWITCH_EVENT_ALL) { session->event_list[type] = 1; } if (type == SWITCH_EVENT_CUSTOM) { custom++; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s for session %s\n", atom, session->uuid_str); } } switch_thread_rwlock_unlock(session->event_rwlock); ei_x_encode_atom(rbuf, "ok"); } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } return SWITCH_STATUS_SUCCESS; }
static switch_status_t handle_msg_session_nixevent(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; if (arity == 1) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { session_elem_t *session; if ((session = find_session_elem_by_pid(listener, &msg->from))) { int custom = 0; int i = 0; switch_event_types_t type; switch_thread_rwlock_wrlock(session->event_rwlock); for (i = 1; i < arity; i++) { if (!ei_decode_atom(buf->buff, &buf->index, atom)) { if (custom) { switch_core_hash_delete(session->event_hash, atom); } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) { uint32_t x = 0; if (type == SWITCH_EVENT_CUSTOM) { custom++; } else if (type == SWITCH_EVENT_ALL) { for (x = 0; x <= SWITCH_EVENT_ALL; x++) { session->event_list[x] = 0; } } else { if (session->event_list[SWITCH_EVENT_ALL]) { session->event_list[SWITCH_EVENT_ALL] = 0; for (x = 0; x < SWITCH_EVENT_ALL; x++) { session->event_list[x] = 1; } } session->event_list[type] = 0; } } } } switch_thread_rwlock_unlock(session->event_rwlock); ei_x_encode_atom(rbuf, "ok"); } else { /* no session for this pid */ ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } return SWITCH_STATUS_SUCCESS; }
/** * @brief Helper for decoding atoms that checks the length of the atom * @param buf the request * @param index the index into the request * @param dest where to store the response * @param maxlength the length of the destination * @return -1 on error; 0 on success */ int erlcmd_decode_atom(const char *buf, int *index, char *dest, int maxlength) { int type; int size; if (ei_get_type(buf, index, &type, &size) < 0 || type != ERL_ATOM_EXT || size + 1 > maxlength) return -1; return ei_decode_atom(buf, index, dest); }
void do_call(char *pid, int index, char *buf) { char m[MAXATOMLEN]; char f[MAXATOMLEN]; long a; int arity; if(ei_decode_tuple_header(buf, &index, &arity) || (arity != 3)) return; if(ei_decode_atom(buf, &index, m)) return; if(ei_decode_atom(buf, &index, f)) return; if(ei_decode_long(buf, &index, &a)) { if(ei_decode_list_header(buf, &index, &arity)) return; a = arity; } erts_printf("%s call %s/%s/%d\n", pid, m, f, a); }
static void cmd_ei_rpc(char* buf, int len) { int index = 0, n; long fd; erlang_pid pid; ei_x_buff x, rpc_x; int r; char mod[MAXATOMLEN], func[MAXATOMLEN]; #if 0 && defined(__WIN32__) DebugBreak(); #endif if (ei_decode_long(buf, &index, &fd) < 0) fail("expected long"); if (ei_decode_pid(buf, &index, &pid) < 0) fail("expected pid (node)"); if (ei_decode_tuple_header(buf, &index, &n) < 0 && n < 2) fail("expected tuple {module, function}"); if (ei_decode_atom(buf, &index, mod) < 0) fail("expected atom (module)"); if (ei_decode_atom(buf, &index, func) < 0) fail("expected atom (function)"); message("pid %s %d %d %d\n", pid.node, pid.num, pid.serial, pid.creation); message("{%s, %s}\n", mod, func); if (ei_x_new(&rpc_x) < 0) fail("ei_x_new"); if (ei_rpc(&ec, fd, mod, func, &buf[index], len - index, &rpc_x) < 0) fail("ei_rpc"); if (ei_x_new_with_version(&x) < 0) fail("ei_x_new_with_version"); if (ei_x_append(&x, &rpc_x) < 0) fail("append"); send_bin_term(&x); /*send_errno_result(ei_send(&ec, fd, &pid, x.buff, x.index));*/ ei_x_free(&x); ei_x_free(&rpc_x); }
static switch_status_t handle_msg_event(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; if (arity == 1) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { int custom = 0; switch_event_types_t type; int i = 0; if (!switch_test_flag(listener, LFLAG_EVENTS)) { switch_set_flag_locked(listener, LFLAG_EVENTS); } switch_thread_rwlock_wrlock(listener->event_rwlock); for (i = 1; i < arity; i++) { if (!ei_decode_atom(buf->buff, &buf->index, atom)) { if (custom) { switch_core_hash_insert(listener->event_hash, atom, MARKER); } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) { if (type == SWITCH_EVENT_ALL) { uint32_t x = 0; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ALL events enabled\n"); for (x = 0; x < SWITCH_EVENT_ALL; x++) { listener->event_list[x] = 1; } } if (type <= SWITCH_EVENT_ALL) { listener->event_list[type] = 1; } if (type == SWITCH_EVENT_CUSTOM) { custom++; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s\n", atom); } } switch_thread_rwlock_unlock(listener->event_rwlock); ei_x_encode_atom(rbuf, "ok"); } return SWITCH_STATUS_SUCCESS; }
static switch_status_t handle_msg_tuple(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf) { char tupletag[MAXATOMLEN]; int arity; switch_status_t ret = SWITCH_STATUS_SUCCESS; ei_decode_tuple_header(buf->buff, &buf->index, &arity); if (ei_decode_atom(buf->buff, &buf->index, tupletag)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { if (!strncmp(tupletag, "fetch_reply", MAXATOMLEN)) { ret = handle_msg_fetch_reply(listener, buf, rbuf); } else if (!strncmp(tupletag, "set_log_level", MAXATOMLEN)) { ret = handle_msg_set_log_level(listener, arity, buf, rbuf); } else if (!strncmp(tupletag, "event", MAXATOMLEN)) { ret = handle_msg_event(listener, arity, buf, rbuf); } else if (!strncmp(tupletag, "session_event", MAXATOMLEN)) { ret = handle_msg_session_event(listener, msg, arity, buf, rbuf); } else if (!strncmp(tupletag, "nixevent", MAXATOMLEN)) { ret = handle_msg_nixevent(listener, arity, buf, rbuf); } else if (!strncmp(tupletag, "session_nixevent", MAXATOMLEN)) { ret = handle_msg_session_nixevent(listener, msg, arity, buf, rbuf); } else if (!strncmp(tupletag, "api", MAXATOMLEN)) { ret = handle_msg_api(listener, msg, arity, buf, rbuf); } else if (!strncmp(tupletag, "bgapi", MAXATOMLEN)) { ret = handle_msg_bgapi(listener, msg, arity, buf, rbuf); } else if (!strncmp(tupletag, "sendevent", MAXATOMLEN)) { ret = handle_msg_sendevent(listener, arity, buf, rbuf); } else if (!strncmp(tupletag, "sendmsg", MAXATOMLEN)) { ret = handle_msg_sendmsg(listener, arity, buf, rbuf); } else if (!strncmp(tupletag, "bind", MAXATOMLEN)) { ret = handle_msg_bind(listener, msg, buf, rbuf); } else if (!strncmp(tupletag, "handlecall", MAXATOMLEN)) { ret = handle_msg_handlecall(listener, msg, arity, buf, rbuf); } else if (!strncmp(tupletag, "rex", MAXATOMLEN)) { ret = handle_msg_rpcresponse(listener, msg, arity, buf, rbuf); } else if (!strncmp(tupletag, "setevent", MAXATOMLEN)) { ret = handle_msg_setevent(listener, msg, arity, buf, rbuf); } else if (!strncmp(tupletag, "session_setevent", MAXATOMLEN)) { ret = handle_msg_session_setevent(listener, msg, arity, buf, rbuf); } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "undef"); } } return ret; }
static void cmd_ei_connect(char* buf, int len) { int index = 0; char node[256]; int i; if (ei_decode_atom(buf, &index, node) < 0) fail("expected atom"); i=ei_connect(&ec, node); #ifdef VXWORKS if(i >= 0) { save_fd(i); } #endif send_errno_result(i); }
int ei_decode_atom_safe(char *buf, int *index, char *dst) { int type, size; ei_get_type(buf, index, &type, &size); if (type != ERL_ATOM_EXT) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed atom\n", type, size); return -1; } else if (size > MAXATOMLEN) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of atom with size %d into a buffer of size %d\n", size, MAXATOMLEN); return -1; } else { return ei_decode_atom(buf, index, dst); } }
/* * Find member in tuple (aka RPC struct) */ static int find_member(erl_rpc_ctx_t *ctx, int arity, const char* member_name) { int index,i=0; int type,size; char key_name[MAXATOMLEN]; /* save position */ index = ctx->request_index; /* { name, Value, name, Value...} */ while (i < arity) { if (ei_get_type(ctx->request->buff,&ctx->request_index,&type,&size)) { erl_rpc_fault(ctx,400,"Bad struct member type"); goto error; } if(ei_decode_atom(ctx->request->buff,&ctx->request_index, key_name)) { erl_rpc_fault(ctx,400,"Bad member name"); goto error; } if (strcasecmp(member_name,key_name)) { if(ei_skip_term(ctx->request->buff,&ctx->request_index)) { erl_rpc_fault(ctx,400,"Unexpected end of struct tuple"); goto error; } continue; } else { /* return at current position */ return 0; } i++; } erl_rpc_fault(ctx,400, "Member %s not found",member_name); error: ctx->request_index = index; return -1; }
static switch_status_t handle_msg_api(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char api_cmd[MAXATOMLEN]; int type; int size; char *arg; switch_bool_t fail = SWITCH_FALSE; if (arity < 3) { fail = SWITCH_TRUE; } ei_get_type(buf->buff, &buf->index, &type, &size); if ((size > (sizeof(api_cmd) - 1)) || ei_decode_atom(buf->buff, &buf->index, api_cmd)) { fail = SWITCH_TRUE; } ei_get_type(buf->buff, &buf->index, &type, &size); arg = malloc(size + 1); if (ei_decode_string_or_binary(buf->buff, &buf->index, size, arg)) { fail = SWITCH_TRUE; } if (!fail) { struct api_command_struct acs = { 0 }; acs.listener = listener; acs.api_cmd = api_cmd; acs.arg = arg; acs.bg = 0; acs.pid = msg->from; api_exec(NULL, (void *) &acs); switch_safe_free(arg); /* don't reply */ return SWITCH_STATUS_FALSE; } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); return SWITCH_STATUS_SUCCESS; } }
/* tests de tipos simples */ int test_performance_atom(char *atom, int times) { ei_x_buff output; ei_x_buff input; erlang_msg msg; int version; int ei_res; int index; char decoded_atom[MAXATOMLEN]; // Inicializa buffers ei_x_new_with_version(&output); ei_x_new(&input); // Codifica ei_x_encode_tuple_header(&output, 2); ei_x_encode_pid(&output, &local_pid); ei_x_encode_atom(&output, atom); for (int i = 0; i<times; i++) { if (ei_reg_send(&ec, connection_fd, REMOTE_SERVER_NAME, output.buff, output.index) < 0) { return 1; } do { ei_res = ei_xreceive_msg(connection_fd, &msg, &input); } while(ei_res == ERL_TICK); if (ei_res == ERL_ERROR) { return -1; } index = 0; if (ei_decode_version(input.buff, &index, &version) < 0) { std::cout << "failed decoding version \n"; return 1; } if (ei_decode_atom(input.buff, &index, decoded_atom) < 0) { std::cout << "failed decoding atom \n"; return 1; } } return 0; }
static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf) { /* format is (result|config|directory|dialplan|phrases) */ char sectionstr[MAXATOMLEN]; switch_xml_section_t section; if (ei_decode_atom(buf->buff, &buf->index, sectionstr) || !(section = switch_xml_parse_section_string(sectionstr))) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { struct erlang_binding *binding, *ptr; if (!(binding = switch_core_alloc(listener->pool, sizeof(*binding)))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n"); ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badmem"); } else { binding->section = section; binding->process.type = ERLANG_PID; binding->process.pid = msg->from; binding->listener = listener; switch_thread_rwlock_wrlock(globals.listener_rwlock); for (ptr = bindings.head; ptr && ptr->next; ptr = ptr->next); if (ptr) { ptr->next = binding; } else { bindings.head = binding; } switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | section); switch_thread_rwlock_unlock(globals.listener_rwlock); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sections %d\n", switch_xml_get_binding_sections(bindings.search_binding)); ei_link(listener, ei_self(listener->ec), &msg->from); ei_x_encode_atom(rbuf, "ok"); } } return SWITCH_STATUS_SUCCESS; }
static switch_status_t handle_msg_nixevent(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; if (arity == 1) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { int custom = 0; int i = 0; switch_event_types_t type; for (i = 1; i < arity; i++) { if (!ei_decode_atom(buf->buff, &buf->index, atom)) { if (custom) { switch_core_hash_delete(listener->event_hash, atom); } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) { uint32_t x = 0; if (type == SWITCH_EVENT_CUSTOM) { custom++; } else if (type == SWITCH_EVENT_ALL) { for (x = 0; x <= SWITCH_EVENT_ALL; x++) { listener->event_list[x] = 0; } } else { if (listener->event_list[SWITCH_EVENT_ALL]) { listener->event_list[SWITCH_EVENT_ALL] = 0; for (x = 0; x < SWITCH_EVENT_ALL; x++) { listener->event_list[x] = 1; } } listener->event_list[type] = 0; } } } } ei_x_encode_atom(rbuf, "ok"); } return SWITCH_STATUS_SUCCESS; }
static int get_known_list_name(const char *buf, int *index, char *list_name, int *list_name_len) { int arity, type; /* The term has the form {List_Name, List}. */ if (ei_decode_tuple_header(buf, index, &arity) != 0) return (-1); if (arity != 2) return (-1); /* Decode the list name. */ if (ei_get_type(buf, index, &type, list_name_len) != 0) return (-1); if (ei_decode_atom(buf, index, list_name) != 0) return (-1); return (0); }
static void cmd_ei_reg_send(char* buf, int len) { int index = 0; long fd; char reg_name[MAXATOMLEN]; erlang_pid pid; ei_x_buff x; if (ei_decode_long(buf, &index, &fd) < 0) fail("expected long (fd)"); if (ei_decode_atom(buf, &index, reg_name) < 0) fail("expected atom (reg name)"); if (ei_x_new_with_version(&x) < 0) fail("ei_x_new_with_version"); if (ei_x_append_buf(&x, &buf[index], len - index) < 0) fail("append"); send_errno_result(ei_reg_send(&ec, fd, reg_name, x.buff, x.index)); ei_x_free(&x); }
static switch_status_t handle_msg_api(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char api_cmd[MAXATOMLEN]; char arg[1024]; if (arity < 3 || ei_decode_atom(buf->buff, &buf->index, api_cmd) || ei_decode_string(buf->buff, &buf->index, arg)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); return SWITCH_STATUS_SUCCESS; } else { struct api_command_struct acs = { 0 }; acs.listener = listener; acs.api_cmd = api_cmd; acs.arg = arg; acs.bg = 0; acs.pid = msg->from; api_exec(NULL, (void *) &acs); /* don't reply */ return SWITCH_STATUS_FALSE; } }
static int mn_send_commit(int fd, erlang_pid *mnesia, erlang_pid *self) { char buf[EISMALLBUF]; char *bufp=buf; char string[256]; int index = 0; int version,arity; int msglen; erlang_msg msg; int i; /* set up commit message { commit, self() } */ ei_encode_version(buf,&index); ei_encode_tuple_header(buf,&index,2); ei_encode_atom(buf,&index,EI_MNESIA_COMMIT); ei_encode_pid(buf,&index,self); /* send it */ if (ei_send_encoded(fd,mnesia,buf,index)) return -1; /* get reply */ while (1) { index = EISMALLBUF; if (!(i=ei_recv_internal(fd,&bufp,&index,&msg,&msglen,1,0))) continue; else if (i < 0) return -1; else break; } if (i == ERL_SEND) { index = 0; if (ei_decode_version(buf,&index,&version) || ei_decode_tuple_header(buf,&index,&arity) || ei_decode_atom(buf,&index,string)) return -1; if (!strcmp(string,"ok")) return 0; } /* wrong message type */ return -1; }
static switch_status_t handle_msg_bgapi(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char api_cmd[MAXATOMLEN]; char arg[ARGLEN]; if (arity < 3 || ei_decode_atom(buf->buff, &buf->index, api_cmd) || ei_decode_string_or_binary(buf->buff, &buf->index, ARGLEN - 1, arg)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { struct api_command_struct *acs = NULL; switch_memory_pool_t *pool; switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; switch_uuid_t uuid; switch_core_new_memory_pool(&pool); acs = switch_core_alloc(pool, sizeof(*acs)); switch_assert(acs); acs->pool = pool; acs->listener = listener; acs->api_cmd = switch_core_strdup(acs->pool, api_cmd); acs->arg = switch_core_strdup(acs->pool, arg); acs->bg = 1; acs->pid = msg->from; switch_threadattr_create(&thd_attr, acs->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_uuid_get(&uuid); switch_uuid_format(acs->uuid_str, &uuid); switch_thread_create(&thread, thd_attr, api_exec, acs, acs->pool); ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "ok"); _ei_x_encode_string(rbuf, acs->uuid_str); } return SWITCH_STATUS_SUCCESS; }