/* Handle --exec if appropriate, otherwise start the initial read events and set the idle timeout. */ static void post_connect(nsock_pool nsp, nsock_iod iod) { /* Command to execute. */ if (o.cmdexec) { struct fdinfo info; info.fd = nsi_getsd(iod); #ifdef HAVE_OPENSSL info.ssl = (SSL *) nsi_getssl(iod); #endif /* Convert Nsock's non-blocking socket to an ordinary blocking one. It's possible for a program to write fast enough that it will get an EAGAIN on write on a non-blocking socket. */ block_socket(info.fd); netexec(&info, o.cmdexec); } /* Start the initial reads. */ if (!o.sendonly) nsock_read(nsp, cs.sock_nsi, read_socket_handler, -1, NULL); if (!o.recvonly) nsock_readbytes(nsp, cs.stdin_nsi, read_stdin_handler, -1, NULL, 0); /* The --idle-timeout option says to exit after a certain period of inactivity. We start a timer here and reset it on every read event; see refresh_idle_timer. */ if (o.idletimeout > 0) { cs.idle_timer_event_id = nsock_timer_create(nsp, idle_timer_handler, o.idletimeout, NULL); } }
static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data) { enum nse_status status = nse_status(evt); enum nse_type type = nse_type(evt); char *buf; int nbytes; ncat_assert(type == NSE_TYPE_READ); if (status == NSE_STATUS_EOF) { Close(STDOUT_FILENO); /* In --recv-only mode or non-TCP mode, exit after EOF on the socket. */ if (o.proto != IPPROTO_TCP || (o.proto == IPPROTO_TCP && o.recvonly)) nsock_loop_quit(nsp); return; } else if (status == NSE_STATUS_ERROR) { loguser("%s.\n", socket_strerror(nse_errorcode(evt))); exit(1); } else if (status == NSE_STATUS_TIMEOUT) { loguser("%s.\n", socket_strerror(ETIMEDOUT)); exit(1); } else if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL) { return; } else { ncat_assert(status == NSE_STATUS_SUCCESS); } buf = nse_readbuf(evt, &nbytes); if (o.linedelay) ncat_delay_timer(o.linedelay); if (o.telnet) dotelnet(nsi_getsd(nse_iod(evt)), (unsigned char *) buf, nbytes); /* Write socket data to stdout */ Write(STDOUT_FILENO, buf, nbytes); ncat_log_recv(buf, nbytes); nsock_readbytes(nsp, cs.sock_nsi, read_socket_handler, -1, NULL, 0); refresh_idle_timer(nsp); }
static void write_socket_handler(nsock_pool nsp, nsock_event evt, void *data) { enum nse_status status = nse_status(evt); enum nse_type type = nse_type(evt); assert(type == NSE_TYPE_WRITE); if (status == NSE_STATUS_ERROR) { loguser("%s.\n", socket_strerror(nse_errorcode(evt))); exit(1); } else if (status == NSE_STATUS_TIMEOUT) { loguser("%s.\n", socket_strerror(ETIMEDOUT)); exit(1); } else if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL) { return; } else { assert(status == NSE_STATUS_SUCCESS); } /* The write to the socket was successful. Allow reading more from stdin now. */ nsock_readbytes(nsp, cs.stdin_nsi, read_stdin_handler, -1, NULL, 0); }