Index: nbase/nbase_winunix.c =================================================================== --- nbase/nbase_winunix.c (revision 13505) +++ nbase/nbase_winunix.c (working copy) @@ -153,10 +153,26 @@ return 0; } +/* Get the newline translation mode (_O_TEXT or _O_BINARY) of a file + descriptor. _O_TEXT does CRLF-LF translation and _O_BINARY does none. + Complementary to _setmode. */ +static int _getmode(int fd) +{ + int mode; + + /* There is no standard _getmode function, but _setmode returns the + previous value. Set it to a dummy value and set it back. */ + mode = _setmode(fd, _O_BINARY); + _setmode(fd, mode); + + return mode; +} + /* Start the reader thread and do all the file handle/descriptor redirection. Returns nonzero on success, zero on error. */ int win_stdin_start_thread(void) { int stdin_fd; + int stdin_fmode; assert(stdin_thread == NULL); assert(stdin_pipe_r == NULL); @@ -188,7 +204,10 @@ } /* Need to redirect file descriptor 0 also. _open_osfhandle makes a new file descriptor from an existing handle. */ - stdin_fd = _open_osfhandle((intptr_t) GetStdHandle(STD_INPUT_HANDLE), _O_RDONLY); + /* Remember the newline translation mode (_O_TEXT or _O_BINARY), and + restore it in the new file descriptor. */ + stdin_fmode = _getmode(STDIN_FILENO); + stdin_fd = _open_osfhandle((intptr_t) GetStdHandle(STD_INPUT_HANDLE), _O_RDONLY | stdin_fmode); if (stdin_fd == -1) { CloseHandle(stdin_pipe_r); CloseHandle(stdin_pipe_w); Index: ncat/ncat_core.h =================================================================== --- ncat/ncat_core.h (revision 13499) +++ ncat/ncat_core.h (working copy) @@ -102,3 +102,7 @@ extern void ncat_log_recv(const char *data, size_t len); extern int ncat_hostaccess(char *matchaddr, char *filename, char *remoteip); + +/* Make it so that line endings read from a console are always \n (not \r\n). + Defined in ncat_posix.c and ncat_win.c. */ +extern void set_lf_mode(void); Index: ncat/ncat_win.c =================================================================== --- ncat/ncat_win.c (revision 13499) +++ ncat/ncat_win.c (working copy) @@ -3,6 +3,19 @@ #include "nbase.h" #include "ncat.h" +void set_lf_mode(void) +{ + /* _O_TEXT (the default setting) converts \r\n to \n on input, making the + terminal look like a Unix terminal. However, use _O_BINARY if stdin is + not a terminal, to avoid breaking data from a pipe or other source. */ + if (isatty(STDIN_FILENO)) + _setmode(STDIN_FILENO, _O_TEXT); + else + _setmode(STDIN_FILENO, _O_BINARY); + /* Do not translate \n to \r\n on output. */ + _setmode(STDOUT_FILENO, _O_BINARY); +} + #ifdef HAVE_OPENSSL int ssl_load_default_ca_certs(SSL_CTX *ctx) Index: ncat/ncat_posix.c =================================================================== --- ncat/ncat_posix.c (revision 13499) +++ ncat/ncat_posix.c (working copy) @@ -128,6 +128,11 @@ return cmdargs; } +void set_lf_mode(void) +{ + /* Nothing needed. */ +} + #ifdef HAVE_OPENSSL #define NCAT_CA_CERTS_PATH (NCAT_DATADIR "/" NCAT_CA_CERTS_FILE) Index: ncat/ncat_main.c =================================================================== --- ncat/ncat_main.c (revision 13499) +++ ncat/ncat_main.c (working copy) @@ -568,6 +568,10 @@ if (o.cmdexec && o.hexlogfd != -1) bye("Invalid option combination: `-e' and `-x'."); + /* Do whatever is necessary to receive \n for line endings on input from + the console. A no-op on Unix. */ + set_lf_mode(); + if (o.listen) return ncat_listen_mode(); else