/* Write data to the channel. Throw `guile-ssh-error' on a libssh error, or signal a system error if amount of data written is smaller than size SZ. */ static void ptob_write (SCM channel, const void *data, size_t sz) #define FUNC_NAME "ptob_write" { struct channel_data *channel_data = _scm_to_channel_data (channel); int res = ssh_channel_write (channel_data->ssh_channel, data, sz); if (res == SSH_ERROR) { ssh_session session = ssh_channel_get_session (channel_data->ssh_channel); guile_ssh_session_error1 (FUNC_NAME, session, channel); } if (res < sz) scm_syserror (FUNC_NAME); }
static int main_loop(ssh_channel chan) { ssh_session session = ssh_channel_get_session(chan); socket_t fd; struct termios *term = NULL; struct winsize *win = NULL; pid_t childpid; ssh_event event; short events; childpid = forkpty(&fd, NULL, term, win); if(childpid == 0) { execl("/bin/bash", "/bin/bash", (char *)NULL); abort(); } cb.userdata = &fd; ssh_callbacks_init(&cb); ssh_set_channel_callbacks(chan, &cb); events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; event = ssh_event_new(); if(event == NULL) { printf("Couldn't get a event\n"); return -1; } if(ssh_event_add_fd(event, fd, events, copy_fd_to_chan, chan) != SSH_OK) { printf("Couldn't add an fd to the event\n"); return -1; } if(ssh_event_add_session(event, session) != SSH_OK) { printf("Couldn't add the session to the event\n"); return -1; } do { ssh_event_dopoll(event, 1000); } while(!ssh_channel_is_closed(chan)); ssh_event_remove_fd(event, fd); ssh_event_remove_session(event, session); ssh_event_free(event); return 0; }
static size_t write_to_channel_port (SCM channel, SCM src, size_t start, size_t count) #define FUNC_NAME "write_to_channel_port" { char *data = (char *) SCM_BYTEVECTOR_CONTENTS (src) + start; struct channel_data *channel_data = _scm_to_channel_data (channel); int res = ssh_channel_write (channel_data->ssh_channel, data, count); if (res == SSH_ERROR) { ssh_session session = ssh_channel_get_session (channel_data->ssh_channel); guile_ssh_session_error1 (FUNC_NAME, session, channel); } assert (res >= 0); return res; }
/* Complete the processing of buffered output data. Currently this callback makes no effect because the channel CHANNEL uses unbuffered output. */ static void ptob_flush (SCM channel) #define FUNC_NAME "ptob_flush" { scm_port *pt = SCM_PTAB_ENTRY (channel); struct channel_data *cd = _scm_to_channel_data (channel); size_t wrsize = pt->write_pos - pt->write_buf; if (wrsize) { int res = ssh_channel_write (cd->ssh_channel, pt->write_buf, wrsize); if (res == SSH_ERROR) { ssh_session session = ssh_channel_get_session (cd->ssh_channel); guile_ssh_session_error1 (FUNC_NAME, session, channel); } } pt->write_pos = pt->write_buf; }
static int my_fd_data_function(UNUSED_PARAM(socket_t fd), int revents, void *userdata) { struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata; ssh_channel channel = event_fd_data->channel; ssh_session session; int len, i, wr; char buf[16384]; int blocking; if (channel == NULL) { _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel == NULL!"); return 0; } session = ssh_channel_get_session(channel); if (ssh_channel_is_closed(channel)) { _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel is closed!"); stack_socket_close(session, event_fd_data); return 0; } if (!(revents & POLLIN)) { if (revents & POLLPRI) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLPRI"); } if (revents & POLLOUT) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLOUT"); } if (revents & POLLHUP) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLHUP"); } if (revents & POLLNVAL) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLNVAL"); } if (revents & POLLERR) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLERR"); } return 0; } blocking = ssh_is_blocking(session); ssh_set_blocking(session, 0); _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "Trying to read from tcp socket fd = %d... (Channel %d:%d state=%d)", *event_fd_data->p_fd, channel->local_channel, channel->remote_channel, channel->state); #ifdef _WIN32 struct sockaddr from; int fromlen = sizeof(from); len = recvfrom(*event_fd_data->p_fd, buf, sizeof(buf), 0, &from, &fromlen); #else len = recv(*event_fd_data->p_fd, buf, sizeof(buf), 0); #endif // _WIN32 if (len < 0) { _ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Reading from tcp socket: %s", strerror(errno)); ssh_channel_send_eof(channel); } else if (len > 0) { if (ssh_channel_is_open(channel)) { wr = 0; do { i = ssh_channel_write(channel, buf, len); if (i < 0) { _ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Error writing on the direct-tcpip channel: %d", i); len = wr; break; } wr += i; _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel_write (%d from %d)", wr, len); } while (i > 0 && wr < len); } else { _ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Can't write on closed channel!"); } } else { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "The destination host has disconnected!"); ssh_channel_close(channel); #ifdef _WIN32 shutdown(*event_fd_data->p_fd, SD_RECEIVE); #else shutdown(*event_fd_data->p_fd, SHUT_RD); #endif // _WIN32 } ssh_set_blocking(session, blocking); return len; }
ssh_session channel_get_session(ssh_channel channel){ return ssh_channel_get_session(channel); }