static void read_stdin_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, *tmp = NULL; int nbytes; assert(type == NSE_TYPE_READ); if (status == NSE_STATUS_EOF) { if (o.sendonly) { /* In --send-only mode, exit after EOF on stdin. */ nsock_loop_quit(nsp); } else { shutdown(nsi_getsd(cs.sock_nsi), SHUT_WR); } 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 { assert(status == NSE_STATUS_SUCCESS); } buf = nse_readbuf(evt, &nbytes); /* read from stdin */ if (o.linedelay) ncat_delay_timer(o.linedelay); if (o.crlf) { if (fix_line_endings(buf, &nbytes, &tmp, &cs.crlf_state)) buf = tmp; } nsock_write(nsp, cs.sock_nsi, write_socket_handler, -1, NULL, buf, nbytes); ncat_log_send(buf, nbytes); if (tmp) free(tmp); refresh_idle_timer(nsp); }
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 stdin and broadcast to all client sockets. Return the number of bytes read, or -1 on error. */ int read_stdin(void) { int nbytes; char buf[DEFAULT_TCP_BUF_LEN]; char *tempbuf = NULL; nbytes = read(STDIN_FILENO, buf, sizeof(buf)); if (nbytes <= 0) { if (nbytes < 0 && o.verbose) logdebug("Error reading from stdin: %s\n", strerror(errno)); if (nbytes == 0 && o.debug) logdebug("EOF on stdin\n"); /* Don't close the file because that allows a socket to be fd 0. */ FD_CLR(STDIN_FILENO, &master_readfds); /* Buf mark that we've seen EOF so it doesn't get re-added to the select list. */ stdin_eof = 1; return nbytes; } if (o.crlf) fix_line_endings((char *) buf, &nbytes, &tempbuf, &crlf_state); if (o.linedelay) ncat_delay_timer(o.linedelay); /* Write to everything in the broadcast set. */ if (tempbuf != NULL) { ncat_broadcast(&master_broadcastfds, &broadcast_fdlist, tempbuf, nbytes); free(tempbuf); tempbuf = NULL; } else { ncat_broadcast(&master_broadcastfds, &broadcast_fdlist, buf, nbytes); } return nbytes; }
/* 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; }