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_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_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 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 getcapabilities_cb(Channel * c, void * x, int error) { Trap trap; PortConnection * conn = (PortConnection *)x; PortAttribute * attr = conn->server->redir_info->attrs; OutputStream * out = &conn->server->channel->out; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_read_struct(&c->inp, read_getcapabilities_struct, (void *)conn); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } if (error) { connect_port_callback(conn, error); } else { if (conn->auto_connect_stream) { conn->pending = protocol_send_command(conn->server->channel, "PortForward", "create", portcreate_cb, conn); write_stream(out, '{'); json_write_string(out, "ID"); write_stream(out, ':'); json_write_string(out, conn->id); while (attr != NULL) { write_stream(out, ','); if (strcmp(attr->name, "RemotePort") == 0) { json_write_string(out, "Port"); } else { json_write_string(out, attr->name); } write_stream(out, ':'); write_string(out, attr->value); attr = attr->next; } if (conn->auto_connect_stream) { write_stream(out, ','); json_write_string(out, "AutoConnect"); write_stream(out, ':'); json_write_boolean(out, 1); } write_stream(out, '}'); write_stream(out, MARKER_EOA); write_stream(out, MARKER_EOM); } else { conn->pending = protocol_send_command(conn->server->channel, "Streams", "subscribe", subscribe_cb, conn); json_write_string(out, "PortForward"); write_stream(out, MARKER_EOA); write_stream(out, MARKER_EOM); } } }
static void command_getm(char * token, Channel * c) { GetmArgs args; args.locs = read_location_list(&c->inp, &args.locs_cnt); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_getm_cache_client, c, &args, sizeof(args)); }
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 read_stream_done(Channel *c, void *client_data, int error) { PortConnection * conn = ((PortReadInfo *) client_data)->conn; int idx = ((PortReadInfo *) client_data)->idx; size_t read_size = 0; conn->pending_read_request &= ~(1 << idx); if (error) { trace(LOG_ALWAYS, "Reply error %d: %s\n", error, errno_to_str(error)); read_packet_callback(conn, error, idx, 0); } else { int end; InputStream *inp = &conn->server->channel->inp; int ch = peek_stream(inp); if (ch == 'n') { (void) read_stream(inp); if (read_stream(inp) != 'u') goto err_json_syntax; if (read_stream(inp) != 'l') goto err_json_syntax; if (read_stream(inp) != 'l') goto err_json_syntax; } else { JsonReadBinaryState state; json_read_binary_start(&state, inp); for (;;) { size_t rd = json_read_binary_data(&state, conn->read_buffer[idx] + read_size, sizeof conn->read_buffer[idx]); if (rd == 0) break; read_size += rd; } assert(state.size_start <= 0 || read_size == state.size_start); json_read_binary_end(&state); } json_test_char(&c->inp, MARKER_EOA); error = read_errno(inp); (void)json_read_long(inp); if (read_stream(inp) != 0) goto err_json_syntax; end = json_read_boolean(inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); #if 0 if (read_stream(inp) != 0 || read_stream(inp) != MARKER_EOM) goto err_json_syntax; #endif if (end) read_packet_callback(conn, 0, idx, 0); else read_packet_callback(conn, 0, idx, read_size); } return; err_json_syntax: return; }
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)); }
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 void command_set(char * token, Channel * c) { SetArgs args; json_read_string(&c->inp, args.id, sizeof(args.id)); json_test_char(&c->inp, MARKER_EOA); args.data = (uint8_t *)json_read_alloc_binary(&c->inp, &args.data_len); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_set_cache_client, c, &args, sizeof(args)); }
static void command_setm(char * token, Channel * c) { SetmArgs args; args.locs = read_location_list(&c->inp, &args.locs_cnt); json_test_char(&c->inp, MARKER_EOA); args.data = (uint8_t *)json_read_alloc_binary(&c->inp, &args.data_len); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args.token, token, sizeof(args.token)); cache_enter(command_setm_cache_client, c, &args, sizeof(args)); }
static void command_find_by_name_args(char * token, Channel * c, CommandFindByNameArgs * args) { args->ip = 0; json_read_string(&c->inp, args->id, sizeof(args->id)); json_test_char(&c->inp, MARKER_EOA); if (json_peek(&c->inp) != '"' && json_peek(&c->inp) != 'n') { args->ip = (ContextAddress)json_read_uint64(&c->inp); 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_by_name_cache_client, c, args, sizeof(CommandFindByNameArgs)); }
static void command_unsubscribe(char * token, Channel * c) { char type[256]; int err = 0; json_read_string(&c->inp, type, sizeof(type)); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); if (virtual_stream_unsubscribe(c, type) < 0) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_search(char * token, Channel * c) { char id[256]; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); json_read_struct(&c->inp, read_filter_attrs, NULL); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, ERR_UNSUPPORTED); write_stringz(&c->out, "null"); write_stream(&c->out, MARKER_EOM); }
static void command_disconnect(char * token, Channel * c) { char id[256]; int err = 0; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); if (virtual_stream_disconnect(c, token, id) < 0) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
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 delete_config_done(Channel *c, void *client_data, int error) { PortConnection * conn = (PortConnection *) client_data; Trap trap; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } if (!conn->auto_connect_stream) { protocol_send_command(conn->server->channel, "Streams", "disconnect", disconnect_stream_done, conn); json_write_string(&conn->server->channel->out, conn->out_stream_id); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); } else { loc_free(conn->out_stream_id); conn->out_stream_id = NULL; loc_free(conn->in_stream_id); conn->in_stream_id = NULL; port_unlock(conn); port_connection_close(conn); } }
static void subscribe_cb(Channel * c, void * x, int error) { Trap trap; PortConnection * conn = (PortConnection *)x; PortAttribute * attr = conn->server->redir_info->attrs; OutputStream * out = &conn->server->channel->out; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } /* Ignore error for subscribe since we may already have subscribed for this channel */ conn->pending = protocol_send_command(conn->server->channel, "PortForward", "create", portcreate_cb, conn); write_stream(out, '{'); json_write_string(out, "ID"); write_stream(out, ':'); json_write_string(out, conn->id); write_stream(out, ','); while (attr != NULL) { json_write_string(out, attr->name); write_stream(out, ':'); write_string(out, attr->value); attr = attr->next; } write_stream(out, '}'); write_stream(out, MARKER_EOA); write_stream(out, MARKER_EOM); }
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_get_children(char * token, Channel * c) { char id[256]; json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, 0); write_stream(&c->out, '['); if (id[0] == 0) { LINK * qp; int cnt = 0; for (qp = context_root.next; qp != &context_root; qp = qp->next) { Context * ctx = ctxl2ctxp(qp); if (ctx->parent != NULL) continue; if (ctx->exited) continue; if (ctx->mem_access == 0 && list_is_empty(&ctx->children)) continue; if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, ctx->id); cnt++; } } else { Context * parent = id2ctx(id); if (parent != NULL) { LINK * l; int cnt = 0; for (l = parent->children.next; l != &parent->children; l = l->next) { Context * ctx = cldl2ctxp(l); assert(ctx->parent == parent); if (ctx->exited) continue; if (ctx->mem_access == 0 && list_is_empty(&ctx->children)) continue; if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, ctx->id); cnt++; } } } write_stream(&c->out, ']'); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
static void getconfig_cb(Channel * c, void * x, int error) { Trap trap; PortConnection * conn = (PortConnection *)x; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_read_struct(&c->inp, read_getconfig_struct, (void *)conn); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } connect_port_callback(conn, error); }
static void command_get_capabilities(char * token, Channel * c) { char id[256]; Context * ctx; OutputStream * out = &c->out; int err = 0; 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) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; write_stringz(out, "R"); write_stringz(out, token); write_errno(out, err); write_stream(out, '['); if (!err) { unsigned i; ContextExtensionRS * ext = EXT(get_reset_context(ctx)); for (i = 0; i < ext->resets_cnt; i++) { ResetInfo * ri = ext->resets + i; if (i > 0) write_stream(&c->out, ','); write_stream(out, '{'); json_write_string(out, "Type"); write_stream(out, ':'); json_write_string(out, ri->type); write_stream(out, ','); json_write_string(out, "Description"); write_stream(out, ':'); json_write_string(out, ri->desc); write_stream(out, '}'); } } write_stream(out, ']'); write_stream(out, 0); write_stream(out, MARKER_EOM); }
static void port_server_cmd_get_capabilities(char * token, Channel * c) { OutputStream * out = &c->out; int err = 0; char * id; id = json_read_alloc_string(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); loc_free(id); write_stringz(out, "R"); write_stringz(out, token); write_errno(out, err); if (err) { write_stringz(&c->out, "null"); } else { write_stream(out, '{'); write_stream(out, '}'); write_stream(out, 0); } write_stream(out, MARKER_EOM); }
static void write_stream_done(Channel *c, void *client_data, int error) { Trap trap; PortConnection * conn = (PortConnection *) client_data;; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } assert (conn->pending_write_request <= MAX_STREAM_WRITE && conn->pending_write_request > 0); if (conn->pending_write_request == MAX_STREAM_WRITE) { send_packet_callback(conn, error); } conn->pending_write_request--; }
static MemoryCommandArgs * read_command_args(char * token, Channel * c, int cmd) { int err = 0; char id[256]; MemoryCommandArgs buf; memset(&buf, 0, sizeof(buf)); json_read_string(&c->inp, id, sizeof(id)); json_test_char(&c->inp, MARKER_EOA); buf.addr = (ContextAddress)json_read_uint64(&c->inp); json_test_char(&c->inp, MARKER_EOA); buf.word_size = (int)json_read_long(&c->inp); json_test_char(&c->inp, MARKER_EOA); buf.size = (int)json_read_long(&c->inp); json_test_char(&c->inp, MARKER_EOA); buf.mode = (int)json_read_long(&c->inp); json_test_char(&c->inp, MARKER_EOA); if (cmd == CMD_GET) json_test_char(&c->inp, MARKER_EOM); buf.ctx = id2ctx(id); if (buf.ctx == NULL) err = ERR_INV_CONTEXT; else if (buf.ctx->exited) err = ERR_ALREADY_EXITED; else if (buf.ctx->mem_access == 0) err = ERR_INV_CONTEXT; if (err != 0) { if (cmd != CMD_GET) { int ch; do ch = read_stream(&c->inp); while (ch != MARKER_EOM && ch != MARKER_EOS); } write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (cmd == CMD_GET) write_stringz(&c->out, "null"); write_errno(&c->out, err); write_stringz(&c->out, "null"); write_stream(&c->out, MARKER_EOM); return NULL; } else { MemoryCommandArgs * args = (MemoryCommandArgs *)loc_alloc(sizeof(MemoryCommandArgs)); *args = buf; args->c = c; strlcpy(args->token, token, sizeof(args->token)); channel_lock(c); context_lock(buf.ctx); return args; } }
static void delete_config_done(Channel *c, void *client_data, int error) { PortConnection * conn = (PortConnection *) client_data; Trap trap; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } loc_free(conn->out_stream_id); conn->out_stream_id = NULL; loc_free(conn->in_stream_id); conn->in_stream_id = NULL; port_unlock(conn); port_connection_close(conn); }
static void portcreate_cb(Channel * c, void * x, int error) { Trap trap; PortConnection * conn = (PortConnection *)x; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } if (error) { connect_port_callback(conn, error); } else { conn->pending = protocol_send_command(conn->server->channel, "PortForward", "getConfig", getconfig_cb, conn); json_write_string(&conn->server->channel->out, conn->id); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); } }