static int ei_error(ei_x_buff *x, const char *error, char** res, int res_size) { if (x) ei_x_free(x); ei_x_new_with_version(x); ei_x_encode_tuple_header(x, 2); ei_x_encode_atom(x, "error"); ei_x_encode_atom(x, error); 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 switch_status_t handle_msg_set_log_level(listener_t *listener, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { switch_log_level_t ltype = SWITCH_LOG_DEBUG; char loglevelstr[MAXATOMLEN]; if (arity != 2 || ei_decode_atom(buf->buff, &buf->index, loglevelstr)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { ltype = switch_log_str2level(loglevelstr); if (ltype && ltype != SWITCH_LOG_INVALID) { listener->level = ltype; 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, "badarg"); } } return SWITCH_STATUS_SUCCESS; }
int ei_x_encode_k(ei_x_buff* x, K r, QOpts* opts) { EI(ei_x_encode_tuple_header(x, 2)); ei_x_buff* types = x; ei_x_buff values; EI(ei_x_new(&values)); EIC(ei_x_encode_k_tv(types, &values, r, opts), ei_x_free(&values)); // cleanup expression // TODO - JMS - is there a way to do this without deep copying data? EIC(ei_x_append(types, &values), ei_x_free(&values)); // cleanup expression EI(ei_x_free(&values)); return 0; }
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[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"); } 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; }
/* {handlecall,<uuid>,<handler process registered name>} or {handlecall,<uuid>} to send messages back to the sender */ static switch_status_t handle_msg_handlecall(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char reg_name[MAXATOMLEN]; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; if (arity < 2 || arity > 3 || (arity == 3 && ei_decode_atom(buf->buff, &buf->index, reg_name)) || ei_decode_string_or_binary(buf->buff, &buf->index, SWITCH_UUID_FORMATTED_LENGTH, uuid_str)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { switch_core_session_t *session; if (!zstr_buf(uuid_str)) { if ((session = switch_core_session_locate(uuid_str))) { /* create a new session list element and attach it to this listener */ if ((arity == 2 && attach_call_to_pid(listener, &msg->from, session)) || (arity == 3 && attach_call_to_registered_process(listener, reg_name, session))) { 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, "session_attach_failed"); } /* release the lock returned by session locate */ switch_core_session_rwunlock(session); } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badsession"); } } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "baduuid"); } } return SWITCH_STATUS_SUCCESS; }
static int erl_json_ei_end_map(void* ctx) { State* pState = (State*) ctx; flog(stderr, "end map", 0, 0, 0); if(pState->skip_list_header_for_value) { ei_x_encode_tuple_header(&pState->ei_buf, 0); pState->skip_list_header_for_value = 0; } ei_x_encode_empty_list(&pState->ei_buf); return 1; }
/* function to spawn a process on a remote node */ int ei_spawn(struct ei_cnode_s *ec, int sockfd, erlang_ref * ref, char *module, char *function, int argc, char **argv) { int i; ei_x_buff buf; ei_x_new_with_version(&buf); ei_x_encode_tuple_header(&buf, 3); ei_x_encode_atom(&buf, "$gen_call"); ei_x_encode_tuple_header(&buf, 2); ei_x_encode_pid(&buf, ei_self(ec)); ei_init_ref(ec, ref); ei_x_encode_ref(&buf, ref); ei_x_encode_tuple_header(&buf, 5); ei_x_encode_atom(&buf, "spawn"); ei_x_encode_atom(&buf, module); ei_x_encode_atom(&buf, function); /* argument list */ if (argc < 0) { ei_x_encode_list_header(&buf, argc); for (i = 0; i < argc && argv[i]; i++) { ei_x_encode_atom(&buf, argv[i]); } } ei_x_encode_empty_list(&buf); /*if (i != argc - 1) { */ /* horked argument list */ /*} */ ei_x_encode_pid(&buf, ei_self(ec)); /* should really be a valid group leader */ #ifdef EI_DEBUG ei_x_print_reg_msg(&buf, "net_kernel", 1); #endif return ei_reg_send(ec, sockfd, "net_kernel", buf.buff, buf.index); }
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; }
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; }
bool CCESUT::TradeUpdate(PTradeUpdateTxnInput pTxnInput) { ei_x_buff x; ei_x_new_with_version(&x); ei_x_encode_tuple_header(&x, 2); { ei_x_encode_atom(&x, "ok"); ei_x_encode_tuple_header(&x, 2); { ei_x_encode_atom(&x, APP ".BH.TU"); m_Encoder.encode(&x, *pTxnInput); } } int result = driver_output(m_ErlDrvPort, x.buff, x.index); #ifdef _TRACE cout << "[TU] ! " << *pTxnInput << ", result=" << result << '\r' << endl; #endif ei_x_free(&x); return result; }
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; 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_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; } } } } switch_thread_rwlock_unlock(listener->event_rwlock); ei_x_encode_atom(rbuf, "ok"); } 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 ei_x_buff pack_parse_data(parse_result parse_result_){ ei_x_buff x; ei_x_new_with_version(&x); ei_x_encode_tuple_header(&x,2); //{caly_tekst,[link]} kodujemy caly tekst ei_x_encode_string(&x, parse_result_.second.c_str()); int link_list_length = parse_result_.first.size(); ei_x_encode_list_header(&x,link_list_length); vector<std::string>& links = parse_result_.first; for (vector<std::string>::iterator it = links.begin(); it != links.end(); it++){ ei_x_encode_string_len(&x,(*it).c_str(),(*it).size()); } ei_x_encode_empty_list(&x); return 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]; 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; } }
static void error() { ei_x_buff result; D("%s", "Error !"); check(ei_x_new_with_version(&result)); check(ei_x_encode_tuple_header(&result, 2)); check(ei_x_encode_atom(&result, "error")); // if (recording) assert(recording); check(ei_x_encode_atom(&result, "already_started")); //else //check(ei_x_encode_atom(&result, "not_started")); write_cmd(&result); ei_x_free(&result); }
int ei_x_encode_same_list_datetime(ei_x_buff* types, ei_x_buff* values, K r, QOpts* opts) { if(opts->unix_timestamp_is_q_datetime) { EI(ei_x_encode_tuple_header(types, 2)); EI(ei_x_encode_atom(types, "list")); EI(ei_x_encode_atom(types, "datetime")); if(r->n > 0) { EI(ei_x_encode_list_header(values, r->n)); int i; for(i=0; i<r->n; ++i) { EI(ei_x_encode_longlong(values, datetime_to_unix_timestamp(kF(r)[i]))); } } EI(ei_x_encode_empty_list(values)); } else { EI(ei_x_encode_same_list_float(types, values, "datetime", r, opts)); } return 0; }
int ei_x_encode_same_list_time(ei_x_buff* types, ei_x_buff* values, K r, QOpts* opts) { if(opts->day_seconds_is_q_time) { EI(ei_x_encode_tuple_header(types, 2)); EI(ei_x_encode_atom(types, "list")); EI(ei_x_encode_atom(types, "time")); if(r->n > 0) { EI(ei_x_encode_list_header(values, r->n)); int i; for(i=0; i<r->n; ++i) { EI(ei_x_encode_ki_val(values, msec_to_sec(kI(r)[i]))); } } EI(ei_x_encode_empty_list(values)); } else { EI(ei_x_encode_same_list_integer(types, values, "time", r, opts)); } return 0; }
int exit_element(struct exmpp_xml_ctx *ctx, const char *ns, int ns_len, const char *elem, int elem_len) { ei_x_buff *tree; /* Update depth. */ if (ctx->depth > 0) ctx->depth--; tree = ctx->current_tree; if (ctx->emit_endtag && (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(). */ /* Start an #xmlendtag record. */ ei_x_encode_tuple_header(tree, 3); ei_x_encode_atom(tree, "xmlendtag"); /* Check if the namespace is known and encode it. */ encode_ns(ctx, tree, ns, ns_len); /* Check if the element is known and encode it. */ encode_elem(ctx, tree, elem, elem_len); current_tree_finished(ctx); } else if (ctx->root_depth != -1 && ctx->depth >= ctx->root_depth) { /* Terminate the children list. */ ei_x_encode_empty_list(tree); if (ctx->depth == ctx->root_depth) current_tree_finished(ctx); } return (0); }
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 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; }
int ei_x_encode_general_list(ei_x_buff* types, ei_x_buff* values, K r, QOpts* opts) { LOG("ei_x_encode_general_list length "FMT_KN"\n", r->n); EI(ei_x_encode_tuple_header(types, 2)); EI(ei_x_encode_atom(types, "list")); if(r->n > 0) { int all_strings = 1; EI(ei_x_encode_list_header(values, r->n)); int i; for(i=0; i<r->n; ++i) { K elem = kK(r)[i]; if(elem->t != KC) { all_strings = 0; break; } EI(ei_x_encode_string_len(values, (const char*)kC(elem), elem->n)); } if(all_strings) { EI(ei_x_encode_atom(types, "string")); } else { EI(ei_x_encode_list_header(types, r->n)); int j; for(j=0; j<i; ++j) { EI(ei_x_encode_atom(types, "string")); } for(; i<r->n; ++i) { EI(ei_x_encode_k_tv(types, values, kK(r)[i], opts)); } EI(ei_x_encode_empty_list(types)); } } else { EI(ei_x_encode_empty_list(types)); } EI(ei_x_encode_empty_list(values)); return 0; }
static void cmd_ei_set_get_tracelevel(char* buf, int len) { int index = 0; long level = 0; long ret = 0; ei_x_buff x; if (ei_decode_long(buf, &index, &level) < 0) { fail("expected long"); } ei_set_tracelevel((int)level); ret = (long) ei_get_tracelevel(); ei_x_new_with_version(&x); ei_x_encode_tuple_header(&x, 2); ei_x_encode_atom(&x, "tracelevel"); ei_x_encode_long(&x, ret); send_bin_term(&x); ei_x_free(&x); }
static ErlDrvSSizeT do_call(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen, unsigned *ret_flags) { int nlen; ei_x_buff x; switch (command) { case 0: *rbuf = buf; *ret_flags |= DRIVER_CALL_KEEP_BUFFER; return len; case 1: ei_x_new(&x); ei_x_format(&x, "{[], a, [], b, c}"); nlen = x.index; if (nlen > rlen) { *rbuf =driver_alloc(nlen); } memcpy(*rbuf,x.buff,nlen); ei_x_free(&x); return nlen; case 2: ei_x_new(&x); ei_x_encode_version(&x); ei_x_encode_tuple_header(&x,2); ei_x_encode_atom(&x,"return"); ei_x_append_buf(&x,buf+1,len-1); nlen = x.index; if (nlen > rlen) { *rbuf =driver_alloc(nlen); } memcpy(*rbuf,x.buff,nlen); ei_x_free(&x); return nlen; default: return -1; } }
static void get_size(Cmd *cmd) { char *buff = cmd->data; int len = cmd->size; Gd *gd = cmd->gd; unsigned int x; unsigned int y; ei_x_buff b; if (gd->image == NULL) { driver_failure_atom(gd->port, "null_image"); return; } x = gdImageSX(gd->image); y = gdImageSY(gd->image); ei_x_new_with_version(&b); ei_x_encode_tuple_header(&b, 2); ei_x_encode_long(&b, x); ei_x_encode_long(&b, y); driver_output(gd->port, b.buff, b.index); ei_x_free(&b); }
int make_attribute_legacy(struct exmpp_xml_ctx *ctx, const char *attr, int attr_len, const char *value, int value_len) { ei_x_buff *tree; tree = ctx->current_tree; /* Start a simple tuple. */ ei_x_encode_list_header(tree, 1); ei_x_encode_tuple_header(tree, 2); /* 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_string(tree, value); else ei_x_encode_string_len(tree, value, value_len); return (0); }
int make_declared_ns_in_buf(struct exmpp_xml_ctx *ctx, ei_x_buff *buf, const char *ns, int ns_len, const char *prefix, int prefix_len) { /* Start declared namespace entry. */ ei_x_encode_list_header(buf, 1); ei_x_encode_tuple_header(buf, 2); /* Check if the namespace is known and encode it. */ encode_ns(ctx, buf, ns, ns_len); /* Encode prefix. */ if (prefix != NULL) if (prefix_len == -1) ei_x_encode_string(buf, prefix); else ei_x_encode_string_len(buf, prefix, prefix_len); else ei_x_encode_atom(buf, "none"); 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 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 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; }