static void command_reset(char * token, Channel * c) { CommandResetArgs args; memset(&args, 0, sizeof(args)); json_read_string(&c->inp, args.id, sizeof(args.id)); json_test_char(&c->inp, MARKER_EOA); json_read_string(&c->inp, args.type, sizeof(args.type)); json_test_char(&c->inp, MARKER_EOA); json_read_struct(&c->inp, read_reset_params, &args.params); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_reset_cache_client, c, &args, sizeof(args)); }
static void command_set_signal_mask(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid; Context * ctx = NULL; int dont_stop; int dont_pass; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); dont_stop = json_read_long(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); dont_pass = json_read_long(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); pid = id2pid(id, NULL); ctx = context_find_from_pid(pid); if (ctx == NULL) { err = ERR_INV_CONTEXT; } else { ctx->sig_dont_stop = dont_stop; ctx->sig_dont_pass = dont_pass; } write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_signal(char * token, Channel * c) { int err = 0; char id[256]; int signal = 0; pid_t pid, parent; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); signal = (int)json_read_long(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); pid = id2pid(id, &parent); write_stringz(&c->out, "R"); write_stringz(&c->out, token); #if defined(WIN32) err = ENOSYS; #elif defined(_WRS_KERNEL) if (kill(pid, signal) < 0) err = errno; #elif defined(__APPLE__) if (kill(pid, signal) < 0) err = errno; #else if (parent == 0) { if (kill(pid, signal) < 0) err = errno; } else { if (tkill(pid, signal) < 0) err = errno; } #endif write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_terminate(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid, parent; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); pid = id2pid(id, &parent); write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (parent != 0) { err = ERR_INV_CONTEXT; } else { #if defined(WIN32) HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid); if (h == NULL) { err = ERR_INV_CONTEXT; } else { TerminateProcess(h, 1); CloseHandle(h); } #else if (kill(pid, SIGTERM) < 0) err = errno; #endif } write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_write(char * token, Channel * c) { char id[256]; long size; int err = 0; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); size = json_read_long(&c->inp); json_test_char(&c->inp, MARKER_EOA); if (virtual_stream_write(c, token, id, size, &c->inp) < 0) err = errno; json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); if (err != 0) { /* * Handle reply with an error. If none error was detected, the reply * was sent back by virtual_stream_write() or delayed. */ write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); } }
static void command_unsubscribe(char * token, Channel * c) { char type[256]; int err = 0; Subscription * s = NULL; LINK * l; json_read_string(&c->inp, type, sizeof(type)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); for (l = subscriptions.next; l != &subscriptions;) { Subscription * h = all2subscription(l); l = l->next; if (h->channel == c && strcmp(type, h->type) == 0) { s = h; break; } } if (s == NULL) err = ERR_INV_CONTEXT; if (err == 0) delete_subscription(s); write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_set_win_size(char * token, Channel * c) { int err = 0; char id[256]; unsigned tid; Terminal * term = NULL; unsigned ws_col; unsigned ws_row; int changed = 0; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); ws_col = json_read_ulong(&c->inp); json_test_char(&c->inp, MARKER_EOA); ws_row = json_read_ulong(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); tid = id2tid(id); if (tid == 0 || (term = find_terminal(tid)) == NULL) { err = ERR_INV_CONTEXT; } else if (set_process_tty_win_size(term->prs, ws_col, ws_row, &changed) < 0) { err = errno; } if (changed) send_event_terminal_win_size_changed(&term->bcg->out, term); write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_get_state(char * token, Channel * c) { char id[256]; Context * ctx; int err = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); ctx = id2ctx(id); write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (ctx == NULL) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; write_errno(&c->out, err); json_write_boolean(&c->out, ctx != NULL && ctx->intercepted); write_stream(&c->out, 0); if (err) { write_stringz(&c->out, "0"); write_stringz(&c->out, "null"); write_stringz(&c->out, "null"); } else { write_context_state(&c->out, ctx); } write_stream(&c->out, MARKER_EOM); }
static void command_eos(char * token, Channel * c) { char id[256]; StreamClient * client = NULL; size_t done = 0; WriteRequest * r = NULL; int err = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); client = find_client(id, c); if (client == NULL) err = errno; if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED; if (!err && !list_is_empty(&client->write_requests)) r = loc_alloc_zero(sizeof(WriteRequest)); if (!err && r == NULL && virtual_stream_add_data(client->stream, NULL, 0, &done, 1) < 0) err = errno; if (r != NULL) { list_init(&r->link_client); r->client = client; r->eos = 1; strncpy(r->token, token, sizeof(r->token) - 1); list_add_last(&r->link_client, &client->write_requests); } else { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); } }
static void command_get_children(char * token, Channel * c) { int err = 0; char id[256]; Symbol sym; Symbol * list = NULL; int cnt = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (id2symbol(id, &sym) < 0) err = errno; if (err == 0 && get_symbol_children(&sym, &list, &cnt) < 0) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err == 0) { int i; write_stream(&c->out, '['); for (i = 0; i < cnt; i++) { if (i > 0) write_stream(&c->out, ','); json_write_string(&c->out, symbol2id(list + i)); } write_stream(&c->out, ']'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); loc_free(list); }
static void command_get_context(char * token, Channel * c) { int err = 0; char id[256]; Context * ctx = NULL; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); ctx = id2ctx(id); if (ctx == NULL || ctx->mem_access == 0) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err == 0) { write_context(&c->out, ctx); } else { write_string(&c->out, "null"); } write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
static void command_disassemble(char * token, Channel * c) { int error = 0; Context * ctx = NULL; DisassembleCmdArgs * args = (DisassembleCmdArgs *)loc_alloc_zero(sizeof(DisassembleCmdArgs)); json_read_string(&c->inp, args->id, sizeof(args->id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); args->addr = (ContextAddress)json_read_uint64(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); args->size = (ContextAddress)json_read_uint64(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); json_read_struct(&c->inp, read_disassembly_params, args); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); ctx = id2ctx(args->id); if (ctx == NULL) error = ERR_INV_CONTEXT; else if (ctx->exited) error = ERR_ALREADY_EXITED; else if (context_get_group(ctx, CONTEXT_GROUP_PROCESS)->mem_access == 0) error = ERR_INV_CONTEXT; if (error != 0) { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, error); write_stringz(&c->out, "null"); write_stream(&c->out, MARKER_EOM); loc_free(args); } else { channel_lock(args->c = c); strlcpy(args->token, token, sizeof(args->token)); post_safe_event(ctx, safe_event_disassemble, args); } }
static void command_read(char * token, Channel * c) { char id[256]; OpenFileInfo * h = NULL; int64_t offset; unsigned long len; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); offset = json_read_int64(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); len = json_read_ulong(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); h = find_open_file_info(id); if (h == NULL) { reply_read(token, &c->out, EBADF, NULL, 0, 0); } else { IORequest * req = create_io_request(token, h, REQ_READ); if (offset < 0) { req->info.type = AsyncReqRead; } else { req->info.type = AsyncReqSeekRead; req->info.u.fio.offset = (off_t)offset; } req->info.u.fio.fd = h->file; req->info.u.fio.bufp = loc_alloc(len); req->info.u.fio.bufsz = len; post_io_requst(h); } }
static void command_find_in_scope(char * token, Channel * c) { CommandFindInScopeArgs args; json_read_string(&c->inp, args.frame_id, sizeof(args.frame_id)); json_test_char(&c->inp, MARKER_EOA); args.ip = (ContextAddress)json_read_uint64(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_read_string(&c->inp, args.scope_id, sizeof(args.scope_id)); json_test_char(&c->inp, MARKER_EOA); args.name = json_read_alloc_string(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_find_in_scope_cache_client, c, &args, sizeof(args)); }
static void command_attach(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid, parent; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); pid = id2pid(id, &parent); if (parent != 0) { err = ERR_INV_CONTEXT; } else if (context_find_from_pid(pid) != NULL) { err = ERR_ALREADY_ATTACHED; } else { AttachDoneArgs * data = loc_alloc_zero(sizeof *data); data->c = c; strcpy(data->token, token); if (context_attach(pid, attach_done, data, 0) == 0) { stream_lock(c); return; } err = errno; loc_free(data); } write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_get_context(char * token, Channel * c) { int err = 0; char id[256]; Context * ctx = NULL; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); ctx = id2ctx(id); if (ctx == NULL) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err) { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stringz(&c->out, "null"); write_stream(&c->out, MARKER_EOM); } else { /* Need to stop everything to access context properties. * In particular, proc FS access can fail when process is running. */ GetContextArgs * s = loc_alloc_zero(sizeof(GetContextArgs)); s->c = c; stream_lock(c); strcpy(s->token, token); s->ctx = ctx; context_lock(ctx); id2pid(id, &s->parent); post_safe_event(ctx->mem, event_get_context, s); } }
static void command_close(char * token, Channel * c) { char id[256]; OpenFileInfo * h = NULL; int err = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); h = find_open_file_info(id); if (h == NULL) { err = EBADF; } else if (h->dir != NULL) { if (closedir(h->dir) < 0) { err = errno; } else { delete_open_file_info(h); } } else { IORequest * req = create_io_request(token, h, REQ_CLOSE); req->info.type = AsyncReqClose; req->info.u.fio.fd = h->file; post_io_requst(h); return; } reply_close(token, &c->out, err); }
static void command_subscribe(char * token, Channel * c) { char type[256]; int err = 0; LINK * l; json_read_string(&c->inp, type, sizeof(type)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); for (l = subscriptions.next; l != &subscriptions;) { Subscription * h = all2subscription(l); l = l->next; if (h->channel == c && strcmp(type, h->type) == 0) { err = ERR_OTHER; break; } } if (err == 0) { Subscription * s = loc_alloc_zero(sizeof(Subscription)); list_init(&s->link_all); list_add_first(&s->link_all, &subscriptions); strncpy(s->type, type, sizeof(s->type) - 1); s->channel = c; } write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_get_context(char * token, Channel * c) { int err = 0; char id[256]; int tid; Terminal * term = NULL; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); tid = id2tid(id); write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (tid == 0 || (term = find_terminal(tid)) == NULL) { err = ERR_INV_CONTEXT; } write_errno(&c->out, err); if (term != NULL) { write_context(&c->out, tid); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static muse_cell json_read( muse_port_t p ) { json_skip_whitespace(p); if ( !port_eof(p) ) { muse_char c = port_getchar(p); port_ungetchar(c,p); switch ( c ) { case '"': return json_read_string(p); case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return json_read_number(p); case '[': return json_read_array(p); case '{': return json_read_object(p); default: if ( c >= 'a' && c <= 'z' ) return json_read_keyword(p); else { return muse_raise_error( p->env, muse_csymbol( p->env, L"json:syntax-error" ), MUSE_NIL ); } } } else { return muse_raise_error( p->env, muse_csymbol( p->env, L"json:unexpected-end-of-stream" ), MUSE_NIL ); } }
static void command_suspend(char * token, Channel * c) { char id[256]; Context * ctx; int err = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); ctx = id2ctx(id); if (ctx == NULL) { err = ERR_INV_CONTEXT; } else if (ctx->exited) { err = ERR_ALREADY_EXITED; } else if (ctx->intercepted) { err = ERR_ALREADY_STOPPED; } else if (ctx->stopped) { send_event_context_suspended(&c->bcg->out, ctx); } else { ctx->pending_intercept = 1; if (context_stop(ctx) < 0) err = errno; } send_simple_result(c, token, err); }
static void command_get_signal_list(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); pid = id2pid(id, NULL); write_stringz(&c->out, "R"); write_stringz(&c->out, token); /* pid is ignored, same signal list for all */ write_errno(&c->out, err); if (err) { write_stringz(&c->out, "null"); } else { int i = 0; int n = 0; write_stream(&c->out, '['); for (i = 0; i < 32; i++) { char * name = signal_name(i); char * desc = signal_description(i); if (name != NULL || desc != NULL) { if (n > 0) write_stream(&c->out, ','); write_stream(&c->out, '{'); json_write_string(&c->out, "Index"); write_stream(&c->out, ':'); json_write_long(&c->out, i); if (name != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "Name"); write_stream(&c->out, ':'); json_write_string(&c->out, name); } if (desc != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "Description"); write_stream(&c->out, ':'); json_write_string(&c->out, desc); } write_stream(&c->out, ','); json_write_string(&c->out, "Code"); write_stream(&c->out, ':'); json_write_ulong(&c->out, signal_code(i)); write_stream(&c->out, '}'); n++; } } write_stream(&c->out, ']'); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void command_resume(char * token, Channel * c) { char id[256]; long mode; long count; Context * ctx; int err = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); mode = json_read_long(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); count = json_read_long(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (peek_stream(&c->inp) != MARKER_EOM) { json_read_struct(&c->inp, resume_params_callback, &err); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); } if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (err == 0) { ctx = id2ctx(id); assert(safe_event_list == NULL); if (ctx == NULL) { err = ERR_INV_CONTEXT; } else if (ctx->exited) { err = ERR_ALREADY_EXITED; } else if (!ctx->intercepted) { err = ERR_ALREADY_RUNNING; } else if (ctx->regs_error) { err = ctx->regs_error; } else if (count != 1) { err = EINVAL; } else if (mode == RM_RESUME || mode == RM_STEP_INTO) { send_event_context_resumed(&c->bcg->out, ctx); if (mode == RM_STEP_INTO) { if (context_single_step(ctx) < 0) { err = errno; } else { ctx->pending_intercept = 1; } } else if (context_continue(ctx) < 0) { err = errno; } } else { err = EINVAL; } } send_simple_result(c, token, err); }
static void command_get_location_info(char * token, Channel * c) { CommandGetLocationInfo args; json_read_string(&c->inp, args.id, sizeof(args.id)); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_get_location_info_cache_client, c, &args, sizeof(args)); }
static void command_list(char * token, Channel * c) { CommandListArgs args; json_read_string(&c->inp, args.id, sizeof(args.id)); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_list_cache_client, c, &args, sizeof(args)); }
static void command_get_capabilities(char * token, Channel * c) { GetCapabilitiesCmdArgs args; json_read_string(&c->inp, args.id, sizeof(args.id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_get_capabilities_cache_client, c, &args, sizeof(args)); }
static void command_find_by_addr(char * token, Channel * c) { CommandFindByAddrArgs args; json_read_string(&c->inp, args.id, sizeof(args.id)); json_test_char(&c->inp, MARKER_EOA); args.addr = (ContextAddress)json_read_uint64(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_find_by_addr_cache_client, c, &args, sizeof(args)); }
static void command_get_sym_file_info(char * token, Channel * c) { CommandSymFileInfo args; json_read_string(&c->inp, args.id, sizeof(args.id)); json_test_char(&c->inp, MARKER_EOA); args.addr = (ContextAddress)json_read_uint64(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_get_sym_file_info_cache_client, c, &args, sizeof(args)); }
static muse_cell json_read_key( muse_port_t p ) { muse_env *env = p->env; int sp = _spos(); muse_cell str = json_read_string(p); int len = 0; const muse_char *strptr = muse_text_contents( env, str, &len ); str = muse_symbol( env, strptr, strptr + len ); _unwind(sp); return str; }
static void command_get_array_type(char * token, Channel * c) { CommandGetArrayTypeArgs args; json_read_string(&c->inp, args.id, sizeof(args.id)); json_test_char(&c->inp, MARKER_EOA); args.length = json_read_uint64(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_get_array_type_cache_client, c, &args, sizeof(args)); }