summaryrefslogtreecommitdiffstats
path: root/loader2/telnet.c
diff options
context:
space:
mode:
Diffstat (limited to 'loader2/telnet.c')
-rw-r--r--loader2/telnet.c272
1 files changed, 0 insertions, 272 deletions
diff --git a/loader2/telnet.c b/loader2/telnet.c
deleted file mode 100644
index 4b8cf09aa..000000000
--- a/loader2/telnet.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/* telnet.c -- basic telnet protocol handling for ttywatch
- *
- * Copyright © 2001 Michael K. Johnson <johnsonm@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* Shamelessly stolen from ttywatch -- oot */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "telnet.h"
-#include "log.h"
-
-#define IAC "\xff"
-#define DONT "\xfe"
-#define WONT "\xfc"
-#define WILL "\xfb"
-#define DO "\xfd"
-#define SB "\xfa"
-#define SE "\xf0"
-#define ECHO "\x01"
-#define SUPPRESS_GO_AHEAD "\x03"
-#define TERMINAL_TYPE "\x18"
-#define NAWS "\x1f"
-#define LINEMODE "\x22"
-#define NEWENVIRON "\x27"
-#define MODE "\x01"
-
-/* Make a request. Not intended to be RFC-compatible, just enough
- * to convince telnet clients to do what we want... To do this
- * right, we would have to honestly negotiate, not speak blind.
- *
- * For now, assume all responses will be favorable and stripped
- * out in telnet_process_input()... Sending it all in a single
- * write makes it more efficient because it will all go out in a
- * single packet, and the responses are more likely to all come
- * back in a single packet (and thus, practically, a single read)
- * too.
- */
-void
-telnet_negotiate(int socket, char ** term_type_ptr, int * heightPtr,
- int * widthPtr) {
- char ch;
- int done = 0;
- char * termType = NULL;
- int termLength = 0, termAlloced = 0;
- enum { ST_NONE, ST_TERMTYPE, ST_WINDOWSIZE } state;
- char sizeBuf[4];
- int height = -1, width = -1;
- char * sizePtr = sizeBuf;
- char request[]=
- IAC DONT ECHO
- IAC WILL ECHO
- IAC WILL NAWS
- IAC WILL SUPPRESS_GO_AHEAD
- IAC DO SUPPRESS_GO_AHEAD
- IAC DONT NEWENVIRON
- IAC WONT NEWENVIRON
- IAC WONT LINEMODE
- IAC DO NAWS
- IAC SB TERMINAL_TYPE "\x01" IAC SE
- ;
- int ret;
-
- ret = write(socket, request, sizeof(request)-1);
-
- /* Read from the terminal until we get the terminal type. This will
- do bad things if the client doesn't send the terminal type, but
- those clients have existed for aeons (right?) */
-
- do {
- ret = read(socket, &ch, 1);
- if (ch != '\xff') {
- abort();
- }
-
- ret = read(socket, &ch, 1); /* command */
-
- if (ch != '\xfa') {
- ret = read(socket, &ch, 1); /* verb */
- continue;
- }
-
- ret = read(socket, &ch, 1); /* suboption */
- if (ch == '\x18') {
- state = ST_TERMTYPE;
- ret = read(socket, &ch, 1); /* should be 0x0! */
- done = 1;
- } else if (ch == '\x1f') {
- state = ST_WINDOWSIZE;
- } else {
- state = ST_NONE;;
- }
-
- ret = read(socket, &ch, 1); /* data */
- while (ch != '\xff') {
- if (state == ST_TERMTYPE) {
- if (termAlloced == termLength) {
- termAlloced += 10;
- termType = realloc(termType, termAlloced + 1);
- }
-
- termType[termLength++] = tolower(ch);
- } else if (state == ST_WINDOWSIZE) {
- if ((sizePtr - sizeBuf) < (int)sizeof(sizeBuf))
- *sizePtr++ = ch;
- }
-
- ret = read(socket, &ch, 1); /* data */
- }
-
- ret = read(socket, &ch, 1); /* should be a SE */
-
- } while (!done);
-
- termType[termLength] = '\0';
-
- if (sizePtr - sizeBuf == sizeof(sizeBuf)) {
- width = (sizeBuf[0] << 8) + sizeBuf[1];
- height = (sizeBuf[2] << 8) + sizeBuf[3];
- }
-
- if (heightPtr) *heightPtr = height;
- if (widthPtr) *widthPtr = width;
-
- if (term_type_ptr) *term_type_ptr = termType;
-}
-
-int
-telnet_process_input(telnet_state * ts, char *data, int len) {
- char *s, *d; /* source, destination */
-
-# if DEBUG_TELNET
- printf("\nprinting packet:");
- for (s=data; s<data+len; s++) {
- if (!((s-data)%10))
- printf("\n %03d: ", s-data);
- printf("%02x ", *s & 0x000000FF);
- }
- printf("\n");
-# endif /* DEBUG_TELNET */
-
- for (s=data, d=data; s<data+len; s++) {
- switch (*ts) {
- case TS_DATA:
- if (*s == '\xff') { /* IAC */
- *ts = TS_IAC;
- continue;
- }
-#if DEBUG_TELNET
- printf("copying data element '%c'\n", *s);
-#endif /* DEBUG_TELNET */
- if (s>d) {
- *(d++) = *s;
- } else {
- d++;
- }
- break;
-
- case TS_IAC:
- if (*s == '\xfa') { /* SB */
- *ts = TS_SB;
- continue;
- }
- /* if not SB, skip IAC verb object */
-# if DEBUG_TELNET
- printf("skipping verb/object (offset %d)...\n", s-data-1);
-# endif /* DEBUG_TELNET */
- s += 1;
- *ts = TS_DATA;
- break;
-
- case TS_SB:
-# if DEBUG_TELNET
- printf("skipping SB (offset %d)...\n", s-data-1);
-# endif /* DEBUG_TELNET */
- while (s < (data+(len-1))) {
- if (*s == '\xff') {
- break; /* fall through to TS_SB_IAC setting below */
- } else {
- s++;
- }
- }
- if (*s == '\xff') {
- *ts = TS_SB_IAC;
- }
- break;
-
- case TS_SB_IAC:
- if (*s == '\xf0') { /* SE */
-# if DEBUG_TELNET
- printf("SE ends SB (offset %d)...\n", s-data-1);
-# endif /* DEBUG_TELNET */
- *ts = TS_DATA;
- } else {
-# if DEBUG_TELNET
- printf("IAC without SE in SB (offset %d)\n", s-data-1);
-# endif /* DEBUG_TELNET */
- *ts = TS_SB;
- }
- break;
-
- default:
- logMessage(WARNING, "unknown telnet state %d for data element %c",
- *ts, *s);
- *ts = TS_DATA;
- break;
- }
- }
-
- /* calculate new length after copying data around */
- len = d - data;
-#if DEBUG_TELNET
- printf("returning len: %d of packet:", len);
- for (s=data; s<data+len; s++) {
- if (!((s-data)%10))
- printf("\n %03d: ", s-data);
- printf("%02x ", *s & 0x000000FF);
- }
- printf("\n");
-#endif /* DEBUG_TELNET */
-
- return len;
-}
-
-/* The telnet protocol requires CR/NL instead of just NL
- * We normally deal with Unix, which just uses NL, so we need to translate.
- *
- * It would be easy to go through line-by-line and write each line, but
- * that would create more packet overhead by sending out one packet
- * per line, and over things like slow PPP connections, that is painful.
- * Therefore, instead, we create a modified copy of the data and write
- * the whole modified copy at once.
- */
-void
-telnet_send_output(int sock, char *data, int len) {
- char *s, *d; /* source, destination */
- char *buf;
- int ret;
-
- buf = alloca((len*2)+1); /* max necessary size */
-
- /* just may need to add CR before NL (but do not double existing CRs) */
- for (s=data, d=buf; d-buf<len; s++, d++) {
- if ((*s == '\n') && (s == data || (*(s-1) != '\r'))) {
- /* NL without preceding CR */
- *(d++) = '\r';
- len++;
- }
- *d = *s;
- }
-
- /* now send it... */
- ret = write(sock, buf, len);
-}