int pty_forward_set_ignore_vhangup(PTYForward *f, bool b) { int r; assert(f); if (!!(f->flags & PTY_FORWARD_IGNORE_VHANGUP) == b) return 0; if (b) f->flags |= PTY_FORWARD_IGNORE_VHANGUP; else f->flags &= ~PTY_FORWARD_IGNORE_VHANGUP; if (!ignore_vhangup(f)) { /* We shall now react to vhangup()s? Let's check * immediately if we might be in one */ f->master_readable = true; r = shovel(f); if (r < 0) return r; } return 0; }
/* Child process that finds out what to connect to and proxies */ void start_shoveler(int in_socket) { fd_set fds; struct timeval tv; int res = PROBE_AGAIN; int out_socket; struct connection cnx; init_cnx(&cnx); cnx.q[0].fd = in_socket; FD_ZERO(&fds); FD_SET(in_socket, &fds); memset(&tv, 0, sizeof(tv)); tv.tv_sec = probing_timeout; while (res == PROBE_AGAIN) { /* POSIX does not guarantee that tv will be updated, but the client can * only postpone the inevitable for so long */ res = select(in_socket + 1, &fds, NULL, NULL, &tv); if (res == -1) perror("select"); if (FD_ISSET(in_socket, &fds)) { /* Received data: figure out what protocol it is */ res = probe_client_protocol(&cnx); } else { /* Timed out: it's necessarily SSH */ cnx.proto = timeout_protocol(); break; } } if (cnx.proto->service && check_access_rights(in_socket, cnx.proto->service)) { exit(0); } /* Connect the target socket */ out_socket = connect_addr(&cnx, in_socket); CHECK_RES_DIE(out_socket, "connect"); cnx.q[1].fd = out_socket; log_connection(&cnx); flush_deferred(&cnx.q[1]); shovel(&cnx); close(in_socket); close(out_socket); if (verbose) fprintf(stderr, "connection closed down\n"); exit(0); }
static int on_stdout_event(sd_event_source *e, int fd, uint32_t revents, void *userdata) { PTYForward *f = userdata; assert(f); assert(e); assert(e == f->stdout_event_source); assert(fd >= 0); assert(fd == STDOUT_FILENO); if (revents & (EPOLLOUT|EPOLLHUP)) f->stdout_writable = true; return shovel(f); }
static int on_master_event(sd_event_source *e, int fd, uint32_t revents, void *userdata) { PTYForward *f = userdata; assert(f); assert(e); assert(e == f->master_event_source); assert(fd >= 0); assert(fd == f->master); if (revents & (EPOLLIN|EPOLLHUP)) f->master_readable = true; if (revents & (EPOLLOUT|EPOLLHUP)) f->master_writable = true; return shovel(f); }
int pty_forward_set_ignore_vhangup(PTYForward *f, bool ignore_vhangup) { int r; assert(f); if (f->ignore_vhangup == ignore_vhangup) return 0; f->ignore_vhangup = ignore_vhangup; if (!f->ignore_vhangup) { /* We shall now react to vhangup()s? Let's check * immediately if we might be in one */ f->master_readable = true; r = shovel(f); if (r < 0) return r; } return 0; }