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 read_file_attrs(InputStream * inp, char * nm, void * arg) { FileAttrs * attrs = (FileAttrs *)arg; if (strcmp(nm, "Size") == 0) { attrs->size = json_read_int64(inp); attrs->flags |= ATTR_SIZE; } else if (strcmp(nm, "UID") == 0) { attrs->uid = (int)json_read_long(inp); attrs->flags |= ATTR_UIDGID; } else if (strcmp(nm, "GID") == 0) { attrs->gid = (int)json_read_long(inp); attrs->flags |= ATTR_UIDGID; } else if (strcmp(nm, "Permissions") == 0) { attrs->permissions = (int)json_read_long(inp); attrs->flags |= ATTR_PERMISSIONS; } else if (strcmp(nm, "ATime") == 0) { attrs->atime = json_read_int64(inp); attrs->flags |= ATTR_ACMODTIME; } else if (strcmp(nm, "MTime") == 0) { attrs->mtime = json_read_int64(inp); attrs->flags |= ATTR_ACMODTIME; } else { exception(ERR_JSON_SYNTAX); } }
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 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 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_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 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_write(char * token, Channel * c) { char id[256]; StreamClient * client = NULL; long size = 0; long offs = 0; char * data = NULL; int err = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); size = json_read_long(&c->inp); if (read_stream(&c->inp) != 0) 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; { JsonReadBinaryState state; unsigned data_pos = 0; if (!err && !list_is_empty(&client->write_requests)) data = loc_alloc(size); json_read_binary_start(&state, &c->inp); for (;;) { if (data != NULL) { size_t rd = json_read_binary_data(&state, data + data_pos, size - offs - data_pos); if (rd == 0) break; data_pos += rd; } else { char buf[256]; size_t rd = json_read_binary_data(&state, buf, sizeof(buf)); if (rd == 0) break; if (!err) { size_t done = 0; if (virtual_stream_add_data(client->stream, buf, rd, &done, 0) < 0) err = errno; assert(done <= rd); offs += done; if (!err && done < rd) { data = loc_alloc(size - offs); memcpy(data, buf + done, rd - done); data_pos = rd - done; } } } } json_read_binary_end(&state); } if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (data != NULL) { WriteRequest * r = loc_alloc_zero(sizeof(WriteRequest)); list_init(&r->link_client); r->client = client; r->data = data; r->size = size - offs; 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); } }