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);
    }
}
Beispiel #2
0
void send_event_register_changed(const char * id) {
    unsigned i;
    Context * ctx = NULL;
    int frame = STACK_NO_FRAME;
    RegisterDefinition * def = NULL;
    OutputStream * out = &broadcast_group->out;

    id2register(id, &ctx, &frame, &def);
    if (ctx == NULL) return;

    for (i = 0; i < listener_cnt; i++) {
        Listener * l = listeners + i;
        if (l->func->register_changed == NULL) continue;
        l->func->register_changed(ctx, frame, def, l->args);
    }

    if (frame >= 0 && frame == get_top_frame(ctx)) {
        id = register2id(ctx, STACK_TOP_FRAME, def);
    }

    write_stringz(out, "E");
    write_stringz(out, REGISTERS);
    write_stringz(out, "registerChanged");

    json_write_string(out, id);
    write_stream(out, 0);

    write_stream(out, MARKER_EOM);
}
static void event_get_context(void * arg) {
    GetContextArgs * s = (GetContextArgs *)arg;
    Channel * c = s->c;
    Context * ctx = s->ctx;

    if (!is_stream_closed(c)) {
        int err = 0;

        write_stringz(&c->out, "R");
        write_stringz(&c->out, s->token);

        if (ctx->exited) err = ERR_ALREADY_EXITED;
        write_errno(&c->out, err);

        if (err == 0) {
            write_context(&c->out, ctx, s->parent != 0);
            write_stream(&c->out, 0);
        }
        else {
            write_stringz(&c->out, "null");
        }

        write_stream(&c->out, MARKER_EOM);
        flush_stream(&c->out);
    }
    stream_unlock(c);
    context_unlock(ctx);
    loc_free(s);
}
Beispiel #4
0
static void port_server_cmd_create(char * token, Channel * c) {
    int err = 0;
    PortAttribute * attrs = NULL;
    PortServer * server;
    Channel * port_channel;
    json_read_struct(&c->inp, read_port_server_property, &attrs);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    /* In case the current channel is a proxy (value-add), use the
     * target channel. Otherwise, use the provided channel. */
    port_channel = proxy_get_target_channel(c);
    if (port_channel == NULL) port_channel = c;
    server = create_port_server(c, attrs, NULL, NULL, NULL, NULL);
    if (server == NULL) err = errno;
    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    if (err) write_stringz(&c->out, "null");
    else {
        write_port_server_info(&c->out, server);
        write_stream(&c->out, 0);
    }
    write_stream(&c->out, MARKER_EOM);
}
Beispiel #5
0
static void command_get_context_cache_client(void * x) {
    GetContextArgs * args = (GetContextArgs *)x;
    Channel * c  = cache_channel();
    Context * ctx = NULL;
    int frame = STACK_NO_FRAME;
    RegisterDefinition * reg_def = NULL;
    Trap trap;

    if (set_trap(&trap)) {
        if (id2register(args->id, &ctx, &frame, &reg_def) < 0) exception(errno);
        clear_trap(&trap);
    }

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, trap.error);
    if (reg_def != NULL) {
        write_context(&c->out, args->id, ctx, frame, reg_def);
    }
    else {
        write_stringz(&c->out, "null");
    }
    write_stream(&c->out, MARKER_EOM);
}
Beispiel #6
0
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);
    }
}
Beispiel #7
0
int virtual_stream_eos(Channel * c, char * token, char * id) {
    size_t done = 0;
    WriteRequest * r = NULL;
    int err = 0;
    StreamClient * 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 = (WriteRequest *)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;
        strlcpy(r->token, token, sizeof(r->token));
        list_add_last(&r->link_client, &client->write_requests);
    }
    else if (err == 0) {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }

    if (err != 0) errno = err;

    return err == 0 ? 0 : -1;
}
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_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_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);
}
Beispiel #13
0
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 port_server_cmd_create(char * token, Channel * c) {
    int err = 0;
    PortRedirectionInfo * port = loc_alloc_zero(sizeof(PortRedirectionInfo));
    PortServer * server;
    json_read_struct(&c->inp, read_port_server_property, port);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    /* In case the current channel is a proxy (value-add), use the
     * target channel.
     */
    port->c = proxy_get_target_channel(c);
    if (port->c == NULL) port->c = c;
    server = create_port_redirection(port);
    if (server == NULL) err = errno;
    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    if (err) write_stringz(&c->out, "null");
    else {
        write_port_server_info(&c->out, server);
        write_stream(&c->out, 0);
    }
    write_stream(&c->out, MARKER_EOM);
}
Beispiel #15
0
static void command_reset_cache_client(void * x) {
    CommandResetArgs * args = (CommandResetArgs *)x;
    Channel * c = cache_channel();
    Context * ctx = id2ctx(args->id);
    OutputStream * out = &c->out;
    int err = 0;

    if (ctx == NULL) err = ERR_INV_CONTEXT;
    else if (ctx->exited) err = ERR_ALREADY_EXITED;

    if (!err) {
        Context * grp = get_reset_context(ctx);
        ResetInfo * rst = find_reset(grp, args->type);
        if (rst == NULL) err = set_errno(ERR_OTHER, "Unsupported reset type");
        else if (rst->reset(ctx, &args->params) < 0) err = errno;
    }

    cache_exit();

    while (args->params.list != NULL) {
        ResetParameter * p = args->params.list;
        args->params.list = p->next;
        loc_free(p->name);
        loc_free(p->value);
        loc_free(p);
    }

    write_stringz(out, "R");
    write_stringz(out, args->token);
    write_errno(out, err);
    write_stream(out, MARKER_EOM);
}
static void command_open(char * token, Channel * c) {
    char path[FILE_PATH_SIZE];
    unsigned long flags = 0;
    FileAttrs attrs;
    int file = -1;
    int err = 0;
    OpenFileInfo * handle = NULL;

    read_path(&c->inp, path, sizeof(path));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    flags = json_read_ulong(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    memset(&attrs, 0, sizeof(FileAttrs));
    json_read_struct(&c->inp, read_file_attrs, &attrs);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    if ((attrs.flags & ATTR_PERMISSIONS) == 0) {
        attrs.permissions = 0775;
    }
    file = open(path, to_local_open_flags(flags), attrs.permissions);

    if (file < 0) {
        err = errno;
    }
    else {
        handle = create_open_file_info(c, path, file, NULL);
    }

    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_fs_errno(&c->out, err);
    write_file_handle(&c->out, handle);
    write_stream(&c->out, MARKER_EOM);
}
static void command_mkdir(char * token, Channel * c) {
    char path[FILE_PATH_SIZE];
    FileAttrs attrs;
    int err = 0;
    int mode = 0777;

    read_path(&c->inp, path, sizeof(path));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    memset(&attrs, 0, sizeof(FileAttrs));
    json_read_struct(&c->inp, read_file_attrs, &attrs);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    if (attrs.flags & ATTR_PERMISSIONS) {
        mode = attrs.permissions;
    }
#if defined(_WRS_KERNEL)
    if (mkdir(path) < 0) err = errno;
#else
    if (mkdir(path, mode) < 0) err = errno;
#endif

    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_fs_errno(&c->out, err);
    write_stream(&c->out, MARKER_EOM);
}
void send_event_memory_changed(Context * ctx, ContextAddress addr, unsigned long size) {
    OutputStream * out = &broadcast_group->out;

    if (!context_has_state(ctx) || is_intercepted(ctx)) {
        write_stringz(out, "E");
        write_stringz(out, MEMORY);
        write_stringz(out, "memoryChanged");

        json_write_string(out, ctx->id);
        write_stream(out, 0);

        /* <array of addres ranges> */
        write_stream(out, '[');
        write_stream(out, '{');

        json_write_string(out, "addr");
        write_stream(out, ':');
        json_write_uint64(out, addr);

        write_stream(out, ',');

        json_write_string(out, "size");
        write_stream(out, ':');
        json_write_ulong(out, size);

        write_stream(out, '}');
        write_stream(out, ']');
        write_stream(out, 0);

        write_stream(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);
}
Beispiel #20
0
static void command_get_array_type_cache_client(void * x) {
    CommandGetArrayTypeArgs * args = (CommandGetArrayTypeArgs *)x;
    Channel * c = cache_channel();
    Symbol * sym = NULL;
    Symbol * arr = NULL;
    int err = 0;

    if (id2symbol(args->id, &sym) < 0) err = errno;
    if (err == 0 && get_array_symbol(sym, (ContextAddress)args->length, &arr) < 0) err = errno;

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, err);

    if (err == 0) {
        json_write_string(&c->out, symbol2id(arr));
        write_stream(&c->out, 0);
    }
    else {
        write_stringz(&c->out, "null");
    }

    write_stream(&c->out, MARKER_EOM);
}
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);
}
Beispiel #22
0
static void command_find_by_addr_cache_client(void * x) {
    CommandFindByAddrArgs * args = (CommandFindByAddrArgs *)x;
    Channel * c = cache_channel();
    Context * ctx = NULL;
    int frame = STACK_NO_FRAME;
    Symbol * sym = NULL;
    int err = 0;

    if (id2frame(args->id, &ctx, &frame) < 0) ctx = id2ctx(args->id);
    if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->id);
    else if (ctx->exited) err = ERR_ALREADY_EXITED;

    if (err == 0 && find_symbol_by_addr(ctx, frame, args->addr, &sym) < 0) err = errno;

    list_cnt = 0;
    if (err == 0) {
        list_add(sym);
        while (find_next_symbol(&sym) == 0) list_add(sym);
        if (get_error_code(errno) != ERR_SYM_NOT_FOUND) err = errno;
    }

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, err);
    write_symbol_list(&c->out);
    write_stream(&c->out, MARKER_EOM);
}
Beispiel #23
0
static void command_find_in_scope_cache_client(void * x) {
    CommandFindInScopeArgs * args = (CommandFindInScopeArgs *)x;
    Channel * c = cache_channel();
    Context * ctx = NULL;
    int frame = STACK_NO_FRAME;
    Symbol * scope = NULL;
    Symbol * sym = NULL;
    int err = 0;

    if (id2frame(args->frame_id, &ctx, &frame) < 0) ctx = id2ctx(args->frame_id);
    if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->frame_id);
    else if (ctx->exited) err = ERR_ALREADY_EXITED;

    if (err == 0 && args->scope_id[0] && id2symbol(args->scope_id, &scope) < 0) err = errno;
    if (err == 0 && args->name == NULL) err = set_errno(EINVAL, "Symbol name must not be null");
    if (err == 0 && find_symbol_in_scope(ctx, frame, args->ip, scope, args->name, &sym) < 0) err = errno;

    list_cnt = 0;
    if (err == 0) {
        list_add(sym);
        while (find_next_symbol(&sym) == 0) list_add(sym);
        if (get_error_code(errno) != ERR_SYM_NOT_FOUND) err = errno;
    }

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, err);
    write_symbol_list(&c->out);
    write_stream(&c->out, MARKER_EOM);
    loc_free(args->name);
}
Beispiel #24
0
static void command_get_children_cache_client(void * x) {
    CommandGetChildrenArgs * args = (CommandGetChildrenArgs *)x;
    Channel * c = cache_channel();
    int err = 0;
    Symbol * sym = NULL;
    Symbol ** list = NULL;
    int cnt = 0;

    if (id2symbol(args->id, &sym) < 0) err = errno;
    if (err == 0 && get_symbol_children(sym, &list, &cnt) < 0) err = errno;

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->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);
}
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_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);
}
Beispiel #27
0
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_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);
}
Beispiel #29
0
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 send_read_reply(StreamClient * client, char * token, size_t size) {
    VirtualStream * stream = client->stream;
    Channel * c = client->channel;
    unsigned lost = 0;
    unsigned read1 = 0;
    unsigned read2 = 0;
    int eos = 0;
    char * data1 = NULL;
    char * data2 = NULL;
    unsigned pos = 0;
    unsigned len = (stream->buf_inp + stream->buf_len - stream->buf_out) % stream->buf_len;

    assert(len > 0 || stream->eos);
    assert(client->pos <= stream->pos);
    if ((uint64_t)len < stream->pos - client->pos) {
        lost = (long)(stream->pos - client->pos - len);
    }
    else {
        len = (unsigned)(stream->pos - client->pos);
    }
    pos = (stream->buf_inp + stream->buf_len - len) % stream->buf_len;
    if (len > size) len = size;
    data1 = stream->buf + pos;
    if (pos + len <= stream->buf_len) {
        read1 = len;
    }
    else {
        read1 = stream->buf_len - pos;
        data2 = stream->buf;
        read2 = len - read1;
    }
    assert(read1 + read2 == len);
    client->pos += lost + read1 + read2;
    assert(client->pos <= stream->pos);
    if (client->pos == stream->pos && stream->eos) eos = 1;
    assert(eos || lost + read1 + read2 > 0);

    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    if (read1 + read2 > 0) {
        JsonWriteBinaryState state;

        json_write_binary_start(&state, &c->out, read1 + read2);
        json_write_binary_data(&state, data1, read1);
        json_write_binary_data(&state, data2, read2);
        json_write_binary_end(&state);
        write_stream(&c->out, 0);
    }
    else {
        write_stringz(&c->out, "null");
    }
    write_errno(&c->out, 0);
    json_write_long(&c->out, lost);
    write_stream(&c->out, 0);
    json_write_boolean(&c->out, eos);
    write_stream(&c->out, 0);
    write_stream(&c->out, MARKER_EOM);
    flush_stream(&c->out);
}