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); }
/* Read from a client socket into buf, returning the number of bytes read, or -1 on an error. This takes care of delays, Telnet negotiation, and logging. If there is more data pending that won't be noticed by select, a 1 is stored in *pending, otherwise 0 is stored there. The caller must loop, processing read data until *pending is false. The reason for this is the SSL_read function that this function may call, which takes data out of the socket buffer (so select may not indicate the socket is readable) and keeps it in its own buffer. *pending holds the result of calling SSL_pending. See http://www.mail-archive.com/[email protected]/msg24324.html. */ int ncat_recv(struct fdinfo *fdn, char *buf, size_t size, int *pending) { int n; *pending = 0; n = fdinfo_recv(fdn, buf, size); if (n <= 0) return n; if (o.linedelay) ncat_delay_timer(o.linedelay); if (o.telnet) dotelnet(fdn->fd, (unsigned char *) buf, n); ncat_log_recv(buf, n); /* SSL can buffer our input, so doing another select() won't necessarily work for us. Indicate to the caller that this function must be called again to get more data. */ *pending = fdinfo_pending(fdn); return n; }