/* tngets.c */ /* Copyright 1997 by Eberhard Mattes Donated to the public domain. No warranty. 1997-01-04 Initial version 1997-01-17 Rename flags, add flag arg to tn_init() 1997-01-18 Fix various bugs 1997-04-05 Reorganize library, don't trap SIGALRM 1997-04-09 Eat line feed in dumb mode 1007-07-18 Don't backspace if echo is disabled */ #include #include #include #include #include "firewall.h" #include "libemtn.h" #include "tnint.h" static void tn_gets_telnet (tnconn *t, char *buf, size_t buf_size, unsigned flags) { int x, c, cmd, opt; unsigned char cmdbuf[3]; if (!t->suppress_go_ahead) { cmdbuf[0] = IAC; cmdbuf[1] = GA; tn_write (t, (char*) cmdbuf, 2); } x = 0; for (;;) { c = tn_getc (t); if (c == IAC) { cmd = tn_getc (t); if (cmd == DO || cmd == DONT || cmd == WILL || cmd == WONT) { opt = tn_getc (t); /* We have to avoid a negotiation loop, see tn_init(). */ if (opt == TELOPT_SGA && cmd == DO) t->suppress_go_ahead = 1; else if (opt == TELOPT_SGA && cmd == DONT) t->suppress_go_ahead = 0; else if (opt != TELOPT_ECHO && opt != TELOPT_BINARY) { cmdbuf[0] = IAC; cmdbuf[1] = (cmd == DO || cmd == DONT) ? WONT : DONT; cmdbuf[2] = opt; tn_write (t, (char*) cmdbuf, 3); } continue; } else if (cmd == EC) c = 0x08; else if (cmd == EL) c = 0x15; else if (cmd != IAC) continue; } if (c == 0x08 || c == 0x7f) { if (x == 0) tn_putc (t, '\a'); else { --x; if (flags & TN_GETS_ECHO) tn_write (t, "\b \b", 3); } } else if (c == 0x15) { while (x > 0) { --x; if (flags & TN_GETS_ECHO) tn_write (t, "\b \b", 3); } } else if (c == 0x0a || c == 0x00) ; else if (c == 0x0d) { buf[x] = 0; tn_putnl (t); return; } else if (c < 0x20 || x + 1 >= buf_size) tn_putc (t, '\a'); else { buf[x++] = (char)c; if (flags & TN_GETS_ECHO) tn_putc (t, (char)c); } } } static void tn_gets_dumb (tnconn *t, char *buf, size_t buf_size) { int x, c; x = 0; for (;;) { c = tn_getc (t); while (c == 0x0d) c = tn_getc (t); if (c == 0x0a) { buf[x] = 0; return; } else if (c >= 0x20 && x + 1 < buf_size) buf[x++] = (char)c; } } void tn_gets (tnconn *t, char *buf, size_t buf_size, int timeout, unsigned flags) { if (timeout > 0) { /* Terminate without logging to avoid reentrancy problems. */ signal (SIGALRM, SIG_DFL); alarm (timeout); } if (t->init_flags & TN_INIT_TELNET) tn_gets_telnet (t, buf, buf_size, flags); else tn_gets_dumb (t, buf, buf_size); if (timeout > 0) alarm (0); }