static void read_getcapabilities_struct(InputStream * inp, const char * name, void * x) { PortConnection * conn = (PortConnection *) x; if (strcmp(name, "AutoConnect") == 0) conn->auto_connect_stream = json_read_boolean(inp); else json_skip_object(inp); }
static void read_disassembly_params(InputStream * inp, const char * name, void * x) { DisassembleCmdArgs * args = (DisassembleCmdArgs *) x; if (strcmp(name, "ISA") == 0) { args->isa = json_read_alloc_string(inp); } else if (strcmp(name, "Simplified") == 0) { args->simplified = json_read_boolean(inp); } else if (strcmp(name, "Pseudo") == 0) { args->pseudo_instr = json_read_boolean(inp); } else if (strcmp(name, "OpcodeValue") == 0) { args->opcode_value =json_read_boolean(inp); } else { json_skip_object(inp); } }
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 read_reset_params(InputStream * inp, const char * name, void * x) { ResetParams * params = (ResetParams *)x; if (strcmp(name, "Suspend") == 0) { params->suspend = json_read_boolean(inp); } else { ResetParameter * param = (ResetParameter *)loc_alloc_zero(sizeof(ResetParameter)); param->name = loc_strdup(name); param->value = json_read_object(inp); param->next = params->list; params->list = param; } }
static void command_copy(char * token, Channel * c) { char src[FILE_PATH_SIZE]; char dst[FILE_PATH_SIZE]; int copy_uidgid; int copy_perms; struct stat st; int fi = -1; int fo = -1; int err = 0; int64_t pos = 0; read_path(&c->inp, src, sizeof(src)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); read_path(&c->inp, dst, sizeof(dst)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); copy_uidgid = json_read_boolean(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); copy_perms = json_read_boolean(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (stat(src, &st) < 0) err = errno; if (err == 0 && (fi = open(src, O_RDONLY | O_BINARY, 0)) < 0) err = errno; if (err == 0 && (fo = open(dst, O_WRONLY | O_BINARY | O_CREAT, 0775)) < 0) err = errno; while (err == 0 && pos < st.st_size) { char buf[BUF_SIZE]; int wr = 0; int rd = read(fi, buf, sizeof(buf)); if (rd == 0) break; if (rd < 0) { err = errno; break; } wr = write(fo, buf, rd); if (wr < 0) { err = errno; break; } if (wr < rd) { err = ENOSPC; break; } pos += rd; } if (fo >= 0 && close(fo) < 0 && err == 0) err = errno; if (fi >= 0 && close(fi) < 0 && err == 0) err = errno; if (err == 0) { struct utimbuf buf; buf.actime = st.st_atime; buf.modtime = st.st_mtime; if (utime(dst, &buf) < 0) err = errno; } if (err == 0 && copy_perms && chmod(dst, st.st_mode) < 0) err = errno; #if !defined(WIN32) && !defined(_WRS_KERNEL) if (err == 0 && copy_uidgid && chown(dst, st.st_uid, st.st_gid) < 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); }
static PortServer * create_server(Channel * c, PortAttribute * attrs) { int sock = -1; struct sockaddr_in addr; PortAttribute * attr = attrs; #if defined(_WRS_KERNEL) int addrlen; #else socklen_t addrlen; #endif u_short port_number; PortServer * server = NULL; int is_udp = 0; /* do we use a server UDP -or TCP- port? */ char * port_config = NULL; int error = 0; int auto_connect = 0; uint64_t auto_connect_period = 0; unsigned int local_port = 0; while (attr != NULL) { if (strcmp(attr->name, "Port") == 0) { ByteArrayInputStream buf; InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value)); port_config = json_read_alloc_string(inp); if (strncasecmp(port_config, "udp:", strlen("udp:")) == 0) { is_udp = 1; } } else if (strcmp(attr->name, "AutoConnect") == 0) { ByteArrayInputStream buf; InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value)); auto_connect = json_read_boolean(inp); } else if (strcmp(attr->name, "AutoConnectPeriod") == 0) { ByteArrayInputStream buf; InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value)); auto_connect_period = json_read_ulong(inp); } else if (strcmp(attr->name, "LocalPort") == 0) { ByteArrayInputStream buf; InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value)); local_port = (unsigned int) json_read_uint64(inp); } attr = attr->next; } if (port_config == NULL) { error = set_errno(ERR_OTHER, "No port configuration is specified"); } if (error == 0) { loc_free(port_config); memset((void *) &addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = (u_short) htons(local_port); if (is_udp) sock = socket(AF_INET, SOCK_DGRAM, 0); else if ((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0) set_socket_options(sock); /* set socket options */ if (sock == -1) error = errno; } if (error == 0) { if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { error = errno; } } if (error == 0 && !is_udp) { if (listen(sock, 16) != 0) error = errno; } if (error == 0) { /* Get port property in case the default port could not be used or * the client specified a port that the system converts to a * dynamic port number. */ addrlen = sizeof addr; if (getsockname(sock, (struct sockaddr *) &addr, &addrlen) < 0) error = errno; } if (error == 0) { port_number = (u_short) ntohs(addr.sin_port); server = (PortServer *)loc_alloc_zero(sizeof(PortServer)); server->sock = sock; server->is_udp = is_udp; #if defined(SOCK_MAXADDRLEN) server->addr_len = SOCK_MAXADDRLEN; #else server->addr_len = 0x1000; #endif server->addr_buf = (struct sockaddr *)loc_alloc(server->addr_len); server->local_port = port_number; if (!server->is_udp) { server->accept_in_progress = 1; server->auto_connect = auto_connect; server->accreq.done = port_server_accept_done; server->accreq.client_data = server; server->accreq.type = AsyncReqAccept; server->accreq.u.acc.sock = sock; server->accreq.u.acc.addr = server->addr_buf; server->accreq.u.acc.addrlen = server->addr_len; async_req_post(&server->accreq); } else { /* For UDP, automatically connect to the port since there is no * connection request we can detect. */ server->auto_connect = 1; } server->auto_connect_period = auto_connect_period; list_add_last(&server->link, &server_list); channel_lock_with_msg(server->channel = c, channel_lock_svr_msg); snprintf (server->id, sizeof(server->id), "PS%" PRIu64, port_server_id++); server->attrs = attrs; } if (error == 0) return server; else { if (sock != -1) closesocket(sock); loc_free(server); return NULL ; } }
static void command_get_children(char * token, Channel * c) { char id[256]; int attached_only; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); attached_only = json_read_boolean(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); write_stringz(&c->out, "R"); write_stringz(&c->out, token); if (id[0] != 0) { write_errno(&c->out, 0); write_stringz(&c->out, "null"); } else { #if defined(WIN32) DWORD err = 0; HANDLE snapshot; PROCESSENTRY32 pe32; snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) err = set_win32_errno(GetLastError()); memset(&pe32, 0, sizeof(pe32)); pe32.dwSize = sizeof(PROCESSENTRY32); if (!err && !Process32First(snapshot, &pe32)) { err = set_win32_errno(GetLastError()); CloseHandle(snapshot); } write_errno(&c->out, err); if (err) { write_stringz(&c->out, "null"); } else { int cnt = 0; write_stream(&c->out, '['); do { if (!attached_only || context_find_from_pid(pe32.th32ProcessID) != NULL) { if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, pid2id(pe32.th32ProcessID, 0)); cnt++; } } while (Process32Next(snapshot, &pe32)); write_stream(&c->out, ']'); write_stream(&c->out, 0); } if (snapshot != INVALID_HANDLE_VALUE) CloseHandle(snapshot); #elif defined(_WRS_KERNEL) int i = 0; int cnt = 0; int ids_cnt = 0; int ids_max = 500; int * ids = (int *)loc_alloc(ids_max * sizeof(int)); for (;;) { ids_cnt = taskIdListGet(ids, ids_max); if (ids_cnt < ids_max) break; loc_free(ids); ids_max *= 2; ids = (int *)loc_alloc(ids_max * sizeof(int)); } write_errno(&c->out, 0); write_stream(&c->out, '['); for (i = 0; i < ids_cnt; i++) { if (!attached_only || context_find_from_pid(ids[i]) != NULL) { if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, pid2id(ids[i], 0)); cnt++; } } write_stream(&c->out, ']'); write_stream(&c->out, 0); #elif defined(__APPLE__) #else DIR * proc = opendir("/proc"); if (proc == NULL) { write_errno(&c->out, errno); write_stringz(&c->out, "null"); } else { int cnt = 0; write_errno(&c->out, 0); write_stream(&c->out, '['); for (;;) { struct dirent * ent = readdir(proc); if (ent == NULL) break; if (ent->d_name[0] >= '1' && ent->d_name[0] <= '9') { pid_t pid = atol(ent->d_name); if (!attached_only || context_find_from_pid(pid) != NULL) { if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, pid2id(pid, 0)); cnt++; } } } write_stream(&c->out, ']'); write_stream(&c->out, 0); closedir(proc); } #endif } write_stream(&c->out, MARKER_EOM); }
static void command_start(char * token, Channel * c) { int pid = 0; int err = 0; char dir[FILE_PATH_SIZE]; char exe[FILE_PATH_SIZE]; char ** args = NULL; char ** envp = NULL; int args_len = 0; int envp_len = 0; int attach = 0; int selfattach = 0; int pending = 0; ChildProcess * prs = NULL; Trap trap; if (set_trap(&trap)) { json_read_string(&c->inp, dir, sizeof(dir)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); json_read_string(&c->inp, exe, sizeof(exe)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); args = json_read_alloc_string_array(&c->inp, &args_len); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); envp = json_read_alloc_string_array(&c->inp, &envp_len); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); attach = json_read_boolean(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (dir[0] != 0 && chdir(dir) < 0) err = errno; if (err == 0 && start_process(c, envp, dir, exe, args, attach, &pid, &selfattach, &prs) < 0) err = errno; if (prs != NULL) { write_process_input(prs); prs->out_struct = read_process_output(prs, prs->out, prs->out_id, sizeof(prs->out_id)); if (prs->out != prs->err) prs->err_struct = read_process_output(prs, prs->err, prs->err_id, sizeof(prs->err_id)); strncpy(prs->name, exe, sizeof(prs->name) - 1); } if (!err) { if (attach) { AttachDoneArgs * data = loc_alloc_zero(sizeof *data); data->c = c; strcpy(data->token, token); pending = context_attach(pid, start_done, data, selfattach) == 0; if (pending) { stream_lock(c); } else { err = errno; loc_free(data); } } else { add_waitpid_process(pid); } } if (!pending) { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err || pid == 0) { write_stringz(&c->out, "null"); } else { write_context(&c->out, pid); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); } clear_trap(&trap); } loc_free(args); loc_free(envp); if (trap.error) exception(trap.error); }