static void channel_np_connect_done(void * args) { ChannelConnectInfo * info = (ChannelConnectInfo *)((AsyncReqInfo *)args)->client_data; if (info->req.error) { if (info->req.error == EPERM) { info->req.error = set_fmt_errno(ERR_OTHER, "Failed to handshake the connection h:%s p:%s", info->host, info->port); } else if (info->req.error == ECONNREFUSED) { info->req.error = set_fmt_errno(ERR_OTHER, "Failed to establish connection h:%s p:%s", info->host, info->port); } if (info->np_sock) nopoll_conn_close(info->np_sock); info->callback(info->callback_args, info->req.error, NULL); } else { ChannelNP * c = create_channel(info->np_sock, info->is_ssl, 0); if (c == NULL) { if (info->np_sock) nopoll_conn_close(info->np_sock); info->callback(info->callback_args, errno, NULL); } else { set_peer_addr(c, info->addr_buf, info->addr_len); info->callback(info->callback_args, 0, &c->chan); } } nopoll_ctx_unref(info->np_ctx); loc_free(info->host); loc_free(info->port); loc_free(info->addr_buf); loc_free(info); }
static StreamClient * find_client(char * s, Channel * c) { unsigned id = 0; if (str2id(s, &id)) { unsigned h = get_client_hash(id, c); LINK * l = handle_hash[h].next; while (l != &handle_hash[h]) { StreamClient * client = hash2client(l); if (client->stream->id == id && client->channel == c) return client; l = l->next; } } errno = set_fmt_errno(ERR_OTHER, "No such stream: %s", s); return NULL; }
static void command_launch(char * token, Channel * c) { int err = 0; char encoding[TERM_PROP_DEF_SIZE]; char pty_type[TERM_PROP_DEF_SIZE]; const char * args[] = TERM_LAUNCH_ARGS; const char * exec = TERM_LAUNCH_EXEC; int selfattach = 0; ProcessStartParams prms; Terminal * term = (Terminal *)loc_alloc_zero(sizeof(Terminal)); memset(&prms, 0, sizeof(prms)); json_read_string(&c->inp, pty_type, sizeof(pty_type)); json_test_char(&c->inp, MARKER_EOA); json_read_string(&c->inp, encoding, sizeof(encoding)); json_test_char(&c->inp, MARKER_EOA); prms.envp = read_env(&c->inp); json_test_char(&c->inp, MARKER_EOM); #if !defined(_WIN32) && !defined(__CYGWIN__) { struct stat st; if (err == 0 && stat(exec, &st) != 0) { err = errno; if (err == ENOENT) { static char fnm[FILE_PATH_SIZE]; /* On some systems (e.g. Free DSB) bash is installed under /usr/local */ assert(exec[0] == '/'); snprintf(fnm, sizeof(fnm), "/usr/local%s", exec); if (stat(fnm, &st) == 0) { args[0] = exec = fnm; err = 0; } } if (err == ENOENT && strcmp(exec, "/bin/bash") == 0) { /* "bash" not found, try "sh" */ const char * fnm = "/bin/sh"; if (stat(fnm, &st) == 0) { args[0] = exec = fnm; err = 0; } } if (err) err = set_fmt_errno(err, "Cannot start %s", exec); } } set_terminal_env(&prms.envp, pty_type, encoding, exec); prms.dir = getenv("HOME"); if (prms.dir) prms.dir = tmp_strdup(prms.dir); #else { const char * home_drv = getenv("HOMEDRIVE"); const char * home_dir = getenv("HOMEPATH"); if (home_drv && home_dir) { prms.dir = tmp_strdup2(home_drv, home_dir); } } #endif prms.exe = exec; prms.args = (char **)args; prms.service = TERMINALS; prms.use_terminal = 1; prms.exit_cb = terminal_exited; prms.exit_args = term; if (err == 0 && start_process(c, &prms, &selfattach, &term->prs) < 0) err = errno; if (!err) { term->bcg = c->bcg; channel_lock_with_msg(term->channel = c, TERMINALS); strlcpy(term->pty_type, pty_type, sizeof(term->pty_type)); strlcpy(term->encoding, encoding, sizeof(term->encoding)); list_add_first(&term->link, &terms_list); assert(find_terminal(get_process_pid(term->prs)) == term); } else { assert(term->prs == NULL); loc_free(term); } /* write result back */ write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err) { write_stringz(&c->out, "null"); } else { write_context(&c->out, get_process_pid(term->prs)); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }