From f18f1e401a8190d29a3ba2fdc8dcbb9170de2c78 Mon Sep 17 00:00:00 2001 From: Kevin Lange Date: Sun, 4 Dec 2011 03:43:33 -0600 Subject: Use setjmp and alarm to break out of options handling --- src/nyancat.c | 154 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 86 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/nyancat.c b/src/nyancat.c index 21abfa8..5f5939f 100644 --- a/src/nyancat.c +++ b/src/nyancat.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "telnet.h" /* The animation frames are stored separately. */ @@ -89,6 +90,18 @@ void SIGINT_handler(int sig){ exit(0); } +jmp_buf environment; + +/* + * Handle the alarm which breaks us off of options + * handling if we didn't receive a terminal + */ +void SIGALRM_handler(int sig) { + alarm(0); + longjmp(environment, 1); + /* Unreachable */ +} + void newline(int n) { int i = 0; for (i = 0; i < n; ++i) { @@ -200,77 +213,82 @@ int main(int argc, char ** argv) { } } + signal(SIGALRM, SIGALRM_handler); /* Negotiate options */ - while (!feof(stdin) && !done) { - unsigned char i = getchar(); - unsigned char opt = 0; - if (i == IAC) { - i = getchar(); - switch (i) { - case SE: - /* End of extended option mode */ - sb_mode = 0; - if (sb[0] == TTYPE) { - strcpy(term, &sb[2]); - goto ready; - } - break; - case NOP: - /* No Op */ - send_command(NOP, 0); - fflush(stdout); - break; - case WILL: - case WONT: - /* Will / Won't Negotiation */ - opt = getchar(); - if (!telnet_willack[opt]) { - telnet_willack[opt] = WONT; - } - send_command(telnet_willack[opt], opt); - fflush(stdout); - if ((i == WILL) && (opt == TTYPE)) { - /* WILL TTYPE? Great, let's do that now! */ - printf("%c%c%c%c%c%c", IAC, SB, TTYPE, SEND, IAC, SE); + if (!setjmp(environment)) { + alarm(1); + while (!feof(stdin) && !done) { + unsigned char i = getchar(); + unsigned char opt = 0; + if (i == IAC) { + i = getchar(); + switch (i) { + case SE: + /* End of extended option mode */ + sb_mode = 0; + if (sb[0] == TTYPE) { + alarm(0); + strcpy(term, &sb[2]); + goto ready; + } + break; + case NOP: + /* No Op */ + send_command(NOP, 0); fflush(stdout); - } - break; - case DO: - case DONT: - /* Do / Don't Negotation */ - opt = getchar(); - if (!telnet_options[opt]) { - telnet_options[opt] = DONT; - } - send_command(telnet_options[opt], opt); - if (opt == ECHO) { - /* We don't really need this, as we don't accept input, but, - * in case we do in the future, set our echo mode */ - do_echo = (i == DO); - } - fflush(stdout); - break; - case SB: - /* Begin Extended Option Mode */ - sb_mode = 1; - sb_len = 0; - memset(sb, 0, 1024); - break; - case IAC: - /* Connection Closed During Negotiation */ - done = 1; - break; - default: - break; - } - } else if (sb_mode) { - /* Extended Option Mode -> Accept character */ - if (sb_len < 1023) { - sb[sb_len] = i; - sb_len++; + break; + case WILL: + case WONT: + /* Will / Won't Negotiation */ + opt = getchar(); + if (!telnet_willack[opt]) { + telnet_willack[opt] = WONT; + } + send_command(telnet_willack[opt], opt); + fflush(stdout); + if ((i == WILL) && (opt == TTYPE)) { + /* WILL TTYPE? Great, let's do that now! */ + printf("%c%c%c%c%c%c", IAC, SB, TTYPE, SEND, IAC, SE); + fflush(stdout); + } + break; + case DO: + case DONT: + /* Do / Don't Negotation */ + opt = getchar(); + if (!telnet_options[opt]) { + telnet_options[opt] = DONT; + } + send_command(telnet_options[opt], opt); + if (opt == ECHO) { + /* We don't really need this, as we don't accept input, but, + * in case we do in the future, set our echo mode */ + do_echo = (i == DO); + } + fflush(stdout); + break; + case SB: + /* Begin Extended Option Mode */ + sb_mode = 1; + sb_len = 0; + memset(sb, 0, 1024); + break; + case IAC: + /* Connection Closed During Negotiation */ + done = 1; + break; + default: + break; + } + } else if (sb_mode) { + /* Extended Option Mode -> Accept character */ + if (sb_len < 1023) { + sb[sb_len] = i; + sb_len++; + } + } else { + goto ready; } - } else { - goto ready; } } } -- cgit v1.2.3 pan>/+6 2014-12-28Imported Upstream version 0+git20141218.b46a22cupstream/0+git20141218.b46a22cJonathan McCrohan535-639/+317 2014-10-20Release 0+git20141009.d26b627-1debian/0+git20141009.d26b627-1Jonathan McCrohan1-2/+2 2014-10-20Fix up packaging to account for move to DVBv5Jonathan McCrohan2-2/+6 2014-10-20delete d/dtv-scan-files.install; Upstream now supplies a MakefileJonathan McCrohan2-4/+1 2014-10-15d/control: update Standards Version to 3.9.6Jonathan McCrohan2-1/+3 2014-10-15d/control: add Build-Depends on dvb-toolsJonathan McCrohan2-1/+2 2014-10-15New Upstream Snapshot (commit d26b627)Jonathan McCrohan1-0/+10 2014-10-15Imported Upstream version 0+git20141009.d26b627upstream/0+git20141009.d26b627Jonathan McCrohan2010-11120/+159271 2014-07-23Release 0+git20140611.14bd6c7-1debian/0+git20140611.14bd6c7-1Jonathan McCrohan1-2/+2 2014-07-23New Upstream Snapshot (commit 14bd6c7)Jonathan McCrohan1-2/+3 2014-07-23Imported Upstream version 0+git20140611.14bd6c7upstream/0+git20140611.14bd6c7Jonathan McCrohan7-11/+60 2014-05-13New Upstream Snapshot (commit 1246b27)Jonathan McCrohan1-0/+6 2014-05-13Imported Upstream version 0+git20140512.1246b27upstream/0+git20140512.1246b27Jonathan McCrohan391-301/+3983 2014-04-05Release 0+git20140326.cfc2975-1debian/0+git20140326.cfc2975-1Jonathan McCrohan1-2/+2 2014-04-05d/control: update Homepage (upstream has moved from Gitweb to cgit)Jonathan McCrohan2-1/+2 2014-04-05New Upstream Snapshot (commit cfc2975)Jonathan McCrohan1-0/+6 2014-04-05Imported Upstream version 0+git20140326.cfc2975upstream/0+git20140326.cfc2975Jonathan McCrohan118-656/+877 2014-01-16Release 0+git20140107.1850cf8-1debian/0+git20140107.1850cf8-1Jonathan McCrohan1-2/+2 2014-01-16Update Standards Version to 3.9.5Jonathan McCrohan2-1/+9 No changes required