Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Committer:
Michael J. Spencer
Date:
Fri Feb 28 18:52:52 2014 -0800
Revision:
2:1df0b61d3b5a
Update to latest Smoothie.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Michael J. Spencer 2:1df0b61d3b5a 1 /*
Michael J. Spencer 2:1df0b61d3b5a 2 * Copyright (c) 2003, Adam Dunkels.
Michael J. Spencer 2:1df0b61d3b5a 3 * All rights reserved.
Michael J. Spencer 2:1df0b61d3b5a 4 *
Michael J. Spencer 2:1df0b61d3b5a 5 * Redistribution and use in source and binary forms, with or without
Michael J. Spencer 2:1df0b61d3b5a 6 * modification, are permitted provided that the following conditions
Michael J. Spencer 2:1df0b61d3b5a 7 * are met:
Michael J. Spencer 2:1df0b61d3b5a 8 * 1. Redistributions of source code must retain the above copyright
Michael J. Spencer 2:1df0b61d3b5a 9 * notice, this list of conditions and the following disclaimer.
Michael J. Spencer 2:1df0b61d3b5a 10 * 2. Redistributions in binary form must reproduce the above copyright
Michael J. Spencer 2:1df0b61d3b5a 11 * notice, this list of conditions and the following disclaimer in the
Michael J. Spencer 2:1df0b61d3b5a 12 * documentation and/or other materials provided with the distribution.
Michael J. Spencer 2:1df0b61d3b5a 13 * 3. The name of the author may not be used to endorse or promote
Michael J. Spencer 2:1df0b61d3b5a 14 * products derived from this software without specific prior
Michael J. Spencer 2:1df0b61d3b5a 15 * written permission.
Michael J. Spencer 2:1df0b61d3b5a 16 *
Michael J. Spencer 2:1df0b61d3b5a 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
Michael J. Spencer 2:1df0b61d3b5a 18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Michael J. Spencer 2:1df0b61d3b5a 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Michael J. Spencer 2:1df0b61d3b5a 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
Michael J. Spencer 2:1df0b61d3b5a 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Michael J. Spencer 2:1df0b61d3b5a 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
Michael J. Spencer 2:1df0b61d3b5a 23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Michael J. Spencer 2:1df0b61d3b5a 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
Michael J. Spencer 2:1df0b61d3b5a 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Michael J. Spencer 2:1df0b61d3b5a 26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Michael J. Spencer 2:1df0b61d3b5a 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Michael J. Spencer 2:1df0b61d3b5a 28 *
Michael J. Spencer 2:1df0b61d3b5a 29 * This file is part of the uIP TCP/IP stack
Michael J. Spencer 2:1df0b61d3b5a 30 *
Michael J. Spencer 2:1df0b61d3b5a 31 * $Id: telnetd.c,v 1.2 2006/06/07 09:43:54 adam Exp $
Michael J. Spencer 2:1df0b61d3b5a 32 *
Michael J. Spencer 2:1df0b61d3b5a 33 */
Michael J. Spencer 2:1df0b61d3b5a 34
Michael J. Spencer 2:1df0b61d3b5a 35 #include "uip.h"
Michael J. Spencer 2:1df0b61d3b5a 36 #include "telnetd.h"
Michael J. Spencer 2:1df0b61d3b5a 37 #include "shell.h"
Michael J. Spencer 2:1df0b61d3b5a 38
Michael J. Spencer 2:1df0b61d3b5a 39 #include <string.h>
Michael J. Spencer 2:1df0b61d3b5a 40 #include <stdlib.h>
Michael J. Spencer 2:1df0b61d3b5a 41 #include <stdio.h>
Michael J. Spencer 2:1df0b61d3b5a 42
Michael J. Spencer 2:1df0b61d3b5a 43 #define ISO_nl 0x0a
Michael J. Spencer 2:1df0b61d3b5a 44 #define ISO_cr 0x0d
Michael J. Spencer 2:1df0b61d3b5a 45
Michael J. Spencer 2:1df0b61d3b5a 46 #define STATE_NORMAL 0
Michael J. Spencer 2:1df0b61d3b5a 47 #define STATE_IAC 1
Michael J. Spencer 2:1df0b61d3b5a 48 #define STATE_WILL 2
Michael J. Spencer 2:1df0b61d3b5a 49 #define STATE_WONT 3
Michael J. Spencer 2:1df0b61d3b5a 50 #define STATE_DO 4
Michael J. Spencer 2:1df0b61d3b5a 51 #define STATE_DONT 5
Michael J. Spencer 2:1df0b61d3b5a 52 #define STATE_CLOSE 6
Michael J. Spencer 2:1df0b61d3b5a 53
Michael J. Spencer 2:1df0b61d3b5a 54 #define TELNET_IAC 255
Michael J. Spencer 2:1df0b61d3b5a 55 #define TELNET_WILL 251
Michael J. Spencer 2:1df0b61d3b5a 56 #define TELNET_WONT 252
Michael J. Spencer 2:1df0b61d3b5a 57 #define TELNET_DO 253
Michael J. Spencer 2:1df0b61d3b5a 58 #define TELNET_DONT 254
Michael J. Spencer 2:1df0b61d3b5a 59
Michael J. Spencer 2:1df0b61d3b5a 60 #define TELNET_LINEMODE 0x22
Michael J. Spencer 2:1df0b61d3b5a 61 #define TELNET_GA 0x03
Michael J. Spencer 2:1df0b61d3b5a 62 #define TELNET_X_PROMPT 0x55
Michael J. Spencer 2:1df0b61d3b5a 63
Michael J. Spencer 2:1df0b61d3b5a 64 //#define DEBUG_PRINTF(...)
Michael J. Spencer 2:1df0b61d3b5a 65 #define DEBUG_PRINTF printf
Michael J. Spencer 2:1df0b61d3b5a 66
Michael J. Spencer 2:1df0b61d3b5a 67 static char *alloc_line(int size)
Michael J. Spencer 2:1df0b61d3b5a 68 {
Michael J. Spencer 2:1df0b61d3b5a 69 return (char *)malloc(size);
Michael J. Spencer 2:1df0b61d3b5a 70 }
Michael J. Spencer 2:1df0b61d3b5a 71
Michael J. Spencer 2:1df0b61d3b5a 72 static void dealloc_line(char *line)
Michael J. Spencer 2:1df0b61d3b5a 73 {
Michael J. Spencer 2:1df0b61d3b5a 74 free(line);
Michael J. Spencer 2:1df0b61d3b5a 75 }
Michael J. Spencer 2:1df0b61d3b5a 76
Michael J. Spencer 2:1df0b61d3b5a 77 void Telnetd::close()
Michael J. Spencer 2:1df0b61d3b5a 78 {
Michael J. Spencer 2:1df0b61d3b5a 79 state = STATE_CLOSE;
Michael J. Spencer 2:1df0b61d3b5a 80 }
Michael J. Spencer 2:1df0b61d3b5a 81
Michael J. Spencer 2:1df0b61d3b5a 82 int Telnetd::sendline(char *line)
Michael J. Spencer 2:1df0b61d3b5a 83 {
Michael J. Spencer 2:1df0b61d3b5a 84 int i;
Michael J. Spencer 2:1df0b61d3b5a 85 for (i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
Michael J. Spencer 2:1df0b61d3b5a 86 if (lines[i] == NULL) {
Michael J. Spencer 2:1df0b61d3b5a 87 lines[i] = line;
Michael J. Spencer 2:1df0b61d3b5a 88 return i;
Michael J. Spencer 2:1df0b61d3b5a 89 }
Michael J. Spencer 2:1df0b61d3b5a 90 }
Michael J. Spencer 2:1df0b61d3b5a 91 if (i == TELNETD_CONF_NUMLINES) {
Michael J. Spencer 2:1df0b61d3b5a 92 dealloc_line(line);
Michael J. Spencer 2:1df0b61d3b5a 93 }
Michael J. Spencer 2:1df0b61d3b5a 94 return TELNETD_CONF_NUMLINES;
Michael J. Spencer 2:1df0b61d3b5a 95 }
Michael J. Spencer 2:1df0b61d3b5a 96
Michael J. Spencer 2:1df0b61d3b5a 97 void Telnetd::output_prompt(const char *str)
Michael J. Spencer 2:1df0b61d3b5a 98 {
Michael J. Spencer 2:1df0b61d3b5a 99 if(prompt) output(str);
Michael J. Spencer 2:1df0b61d3b5a 100 }
Michael J. Spencer 2:1df0b61d3b5a 101
Michael J. Spencer 2:1df0b61d3b5a 102 int Telnetd::output(const char *str)
Michael J. Spencer 2:1df0b61d3b5a 103 {
Michael J. Spencer 2:1df0b61d3b5a 104 if(state == STATE_CLOSE) return -1;
Michael J. Spencer 2:1df0b61d3b5a 105
Michael J. Spencer 2:1df0b61d3b5a 106 unsigned chunk = 256; // small chunk size so we don't allocate huge blocks, and must be less than mss
Michael J. Spencer 2:1df0b61d3b5a 107 unsigned len = strlen(str);
Michael J. Spencer 2:1df0b61d3b5a 108 char *line;
Michael J. Spencer 2:1df0b61d3b5a 109 if (len < chunk) {
Michael J. Spencer 2:1df0b61d3b5a 110 // can be sent in one tcp buffer
Michael J. Spencer 2:1df0b61d3b5a 111 line = alloc_line(len + 1);
Michael J. Spencer 2:1df0b61d3b5a 112 if (line != NULL) {
Michael J. Spencer 2:1df0b61d3b5a 113 strcpy(line, str);
Michael J. Spencer 2:1df0b61d3b5a 114 return sendline(line);
Michael J. Spencer 2:1df0b61d3b5a 115 }else{
Michael J. Spencer 2:1df0b61d3b5a 116 // out of memory treat like full
Michael J. Spencer 2:1df0b61d3b5a 117 return TELNETD_CONF_NUMLINES;
Michael J. Spencer 2:1df0b61d3b5a 118 }
Michael J. Spencer 2:1df0b61d3b5a 119 } else {
Michael J. Spencer 2:1df0b61d3b5a 120 // need to split line over multiple send lines
Michael J. Spencer 2:1df0b61d3b5a 121 int size = chunk; // size to copy
Michael J. Spencer 2:1df0b61d3b5a 122 int off = 0;
Michael J. Spencer 2:1df0b61d3b5a 123 int n= 0;
Michael J. Spencer 2:1df0b61d3b5a 124 while (len >= chunk) {
Michael J. Spencer 2:1df0b61d3b5a 125 line = alloc_line(chunk + 1);
Michael J. Spencer 2:1df0b61d3b5a 126 if (line != NULL) {
Michael J. Spencer 2:1df0b61d3b5a 127 memcpy(line, str + off, size);
Michael J. Spencer 2:1df0b61d3b5a 128 line[size] = 0;
Michael J. Spencer 2:1df0b61d3b5a 129 n= sendline(line);
Michael J. Spencer 2:1df0b61d3b5a 130 len -= size;
Michael J. Spencer 2:1df0b61d3b5a 131 off += size;
Michael J. Spencer 2:1df0b61d3b5a 132 }else{
Michael J. Spencer 2:1df0b61d3b5a 133 // out of memory treat like full
Michael J. Spencer 2:1df0b61d3b5a 134 return TELNETD_CONF_NUMLINES;
Michael J. Spencer 2:1df0b61d3b5a 135 }
Michael J. Spencer 2:1df0b61d3b5a 136 }
Michael J. Spencer 2:1df0b61d3b5a 137 if (len > 0) {
Michael J. Spencer 2:1df0b61d3b5a 138 // send rest
Michael J. Spencer 2:1df0b61d3b5a 139 line = alloc_line(len + 1);
Michael J. Spencer 2:1df0b61d3b5a 140 if (line != NULL) {
Michael J. Spencer 2:1df0b61d3b5a 141 strcpy(line, str + off);
Michael J. Spencer 2:1df0b61d3b5a 142 n= sendline(line);
Michael J. Spencer 2:1df0b61d3b5a 143 }else{
Michael J. Spencer 2:1df0b61d3b5a 144 // out of memory treat like full
Michael J. Spencer 2:1df0b61d3b5a 145 return TELNETD_CONF_NUMLINES;
Michael J. Spencer 2:1df0b61d3b5a 146 }
Michael J. Spencer 2:1df0b61d3b5a 147 }
Michael J. Spencer 2:1df0b61d3b5a 148 return n;
Michael J. Spencer 2:1df0b61d3b5a 149 }
Michael J. Spencer 2:1df0b61d3b5a 150 }
Michael J. Spencer 2:1df0b61d3b5a 151
Michael J. Spencer 2:1df0b61d3b5a 152 // check if we can queue or if queue is full
Michael J. Spencer 2:1df0b61d3b5a 153 int Telnetd::can_output()
Michael J. Spencer 2:1df0b61d3b5a 154 {
Michael J. Spencer 2:1df0b61d3b5a 155 if(state == STATE_CLOSE) return -1;
Michael J. Spencer 2:1df0b61d3b5a 156
Michael J. Spencer 2:1df0b61d3b5a 157 int i;
Michael J. Spencer 2:1df0b61d3b5a 158 int cnt = 0;
Michael J. Spencer 2:1df0b61d3b5a 159 for (i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
Michael J. Spencer 2:1df0b61d3b5a 160 if (lines[i] == NULL) cnt++;
Michael J. Spencer 2:1df0b61d3b5a 161 }
Michael J. Spencer 2:1df0b61d3b5a 162 return cnt < 4 ? 0 : 1;
Michael J. Spencer 2:1df0b61d3b5a 163 }
Michael J. Spencer 2:1df0b61d3b5a 164
Michael J. Spencer 2:1df0b61d3b5a 165 void Telnetd::acked(void)
Michael J. Spencer 2:1df0b61d3b5a 166 {
Michael J. Spencer 2:1df0b61d3b5a 167 while (numsent > 0) {
Michael J. Spencer 2:1df0b61d3b5a 168 dealloc_line(lines[0]);
Michael J. Spencer 2:1df0b61d3b5a 169 for (int i = 1; i < TELNETD_CONF_NUMLINES; ++i) {
Michael J. Spencer 2:1df0b61d3b5a 170 lines[i - 1] = lines[i];
Michael J. Spencer 2:1df0b61d3b5a 171 }
Michael J. Spencer 2:1df0b61d3b5a 172 lines[TELNETD_CONF_NUMLINES - 1] = NULL;
Michael J. Spencer 2:1df0b61d3b5a 173 --numsent;
Michael J. Spencer 2:1df0b61d3b5a 174 }
Michael J. Spencer 2:1df0b61d3b5a 175 }
Michael J. Spencer 2:1df0b61d3b5a 176
Michael J. Spencer 2:1df0b61d3b5a 177 void Telnetd::senddata(void)
Michael J. Spencer 2:1df0b61d3b5a 178 {
Michael J. Spencer 2:1df0b61d3b5a 179 // NOTE this sends as many lines as it can fit in one tcp frame
Michael J. Spencer 2:1df0b61d3b5a 180 // we need to keep the lines under the size of the tcp frame
Michael J. Spencer 2:1df0b61d3b5a 181 char *bufptr, *lineptr;
Michael J. Spencer 2:1df0b61d3b5a 182 int buflen, linelen;
Michael J. Spencer 2:1df0b61d3b5a 183
Michael J. Spencer 2:1df0b61d3b5a 184 bufptr = (char *)uip_appdata;
Michael J. Spencer 2:1df0b61d3b5a 185 buflen = 0;
Michael J. Spencer 2:1df0b61d3b5a 186 for (numsent = 0; numsent < TELNETD_CONF_NUMLINES && lines[numsent] != NULL ; ++numsent) {
Michael J. Spencer 2:1df0b61d3b5a 187 lineptr = lines[numsent];
Michael J. Spencer 2:1df0b61d3b5a 188 linelen = strlen(lineptr);
Michael J. Spencer 2:1df0b61d3b5a 189 if (buflen + linelen < uip_mss()) {
Michael J. Spencer 2:1df0b61d3b5a 190 memcpy(bufptr, lineptr, linelen);
Michael J. Spencer 2:1df0b61d3b5a 191 bufptr += linelen;
Michael J. Spencer 2:1df0b61d3b5a 192 buflen += linelen;
Michael J. Spencer 2:1df0b61d3b5a 193 } else {
Michael J. Spencer 2:1df0b61d3b5a 194 break;
Michael J. Spencer 2:1df0b61d3b5a 195 }
Michael J. Spencer 2:1df0b61d3b5a 196 }
Michael J. Spencer 2:1df0b61d3b5a 197 uip_send(uip_appdata, buflen);
Michael J. Spencer 2:1df0b61d3b5a 198 }
Michael J. Spencer 2:1df0b61d3b5a 199
Michael J. Spencer 2:1df0b61d3b5a 200 void Telnetd::get_char(u8_t c)
Michael J. Spencer 2:1df0b61d3b5a 201 {
Michael J. Spencer 2:1df0b61d3b5a 202 if (c == ISO_cr) {
Michael J. Spencer 2:1df0b61d3b5a 203 return;
Michael J. Spencer 2:1df0b61d3b5a 204 }
Michael J. Spencer 2:1df0b61d3b5a 205
Michael J. Spencer 2:1df0b61d3b5a 206 buf[(int)bufptr] = c;
Michael J. Spencer 2:1df0b61d3b5a 207 if (buf[(int)bufptr] == ISO_nl || bufptr == sizeof(buf) - 1) {
Michael J. Spencer 2:1df0b61d3b5a 208 if (bufptr > 0) {
Michael J. Spencer 2:1df0b61d3b5a 209 buf[(int)bufptr] = 0;
Michael J. Spencer 2:1df0b61d3b5a 210 }
Michael J. Spencer 2:1df0b61d3b5a 211 shell->input(buf);
Michael J. Spencer 2:1df0b61d3b5a 212 bufptr = 0;
Michael J. Spencer 2:1df0b61d3b5a 213
Michael J. Spencer 2:1df0b61d3b5a 214 } else {
Michael J. Spencer 2:1df0b61d3b5a 215 ++bufptr;
Michael J. Spencer 2:1df0b61d3b5a 216 }
Michael J. Spencer 2:1df0b61d3b5a 217 }
Michael J. Spencer 2:1df0b61d3b5a 218
Michael J. Spencer 2:1df0b61d3b5a 219 // static void sendopt(u8_t option, u8_t value)
Michael J. Spencer 2:1df0b61d3b5a 220 // {
Michael J. Spencer 2:1df0b61d3b5a 221 // char *line;
Michael J. Spencer 2:1df0b61d3b5a 222 // line = alloc_line(4);
Michael J. Spencer 2:1df0b61d3b5a 223 // if (line != NULL) {
Michael J. Spencer 2:1df0b61d3b5a 224 // line[0] = TELNET_IAC;
Michael J. Spencer 2:1df0b61d3b5a 225 // line[1] = option;
Michael J. Spencer 2:1df0b61d3b5a 226 // line[2] = value;
Michael J. Spencer 2:1df0b61d3b5a 227 // line[3] = 0;
Michael J. Spencer 2:1df0b61d3b5a 228 // sendline(line);
Michael J. Spencer 2:1df0b61d3b5a 229 // }
Michael J. Spencer 2:1df0b61d3b5a 230 // }
Michael J. Spencer 2:1df0b61d3b5a 231
Michael J. Spencer 2:1df0b61d3b5a 232 void Telnetd::newdata(void)
Michael J. Spencer 2:1df0b61d3b5a 233 {
Michael J. Spencer 2:1df0b61d3b5a 234 u16_t len;
Michael J. Spencer 2:1df0b61d3b5a 235 u8_t c;
Michael J. Spencer 2:1df0b61d3b5a 236 char *dataptr;
Michael J. Spencer 2:1df0b61d3b5a 237
Michael J. Spencer 2:1df0b61d3b5a 238 len = uip_datalen();
Michael J. Spencer 2:1df0b61d3b5a 239 dataptr = (char *)uip_appdata;
Michael J. Spencer 2:1df0b61d3b5a 240
Michael J. Spencer 2:1df0b61d3b5a 241 while (len > 0 && bufptr < sizeof(buf)) {
Michael J. Spencer 2:1df0b61d3b5a 242 c = *dataptr;
Michael J. Spencer 2:1df0b61d3b5a 243 ++dataptr;
Michael J. Spencer 2:1df0b61d3b5a 244 --len;
Michael J. Spencer 2:1df0b61d3b5a 245 switch (state) {
Michael J. Spencer 2:1df0b61d3b5a 246 case STATE_IAC:
Michael J. Spencer 2:1df0b61d3b5a 247 if (c == TELNET_IAC) {
Michael J. Spencer 2:1df0b61d3b5a 248 get_char(c);
Michael J. Spencer 2:1df0b61d3b5a 249 state = STATE_NORMAL;
Michael J. Spencer 2:1df0b61d3b5a 250 } else {
Michael J. Spencer 2:1df0b61d3b5a 251 switch (c) {
Michael J. Spencer 2:1df0b61d3b5a 252 case TELNET_WILL:
Michael J. Spencer 2:1df0b61d3b5a 253 state = STATE_WILL;
Michael J. Spencer 2:1df0b61d3b5a 254 break;
Michael J. Spencer 2:1df0b61d3b5a 255 case TELNET_WONT:
Michael J. Spencer 2:1df0b61d3b5a 256 state = STATE_WONT;
Michael J. Spencer 2:1df0b61d3b5a 257 break;
Michael J. Spencer 2:1df0b61d3b5a 258 case TELNET_DO:
Michael J. Spencer 2:1df0b61d3b5a 259 state = STATE_DO;
Michael J. Spencer 2:1df0b61d3b5a 260 break;
Michael J. Spencer 2:1df0b61d3b5a 261 case TELNET_DONT:
Michael J. Spencer 2:1df0b61d3b5a 262 state = STATE_DONT;
Michael J. Spencer 2:1df0b61d3b5a 263 break;
Michael J. Spencer 2:1df0b61d3b5a 264 default:
Michael J. Spencer 2:1df0b61d3b5a 265 state = STATE_NORMAL;
Michael J. Spencer 2:1df0b61d3b5a 266 break;
Michael J. Spencer 2:1df0b61d3b5a 267 }
Michael J. Spencer 2:1df0b61d3b5a 268 }
Michael J. Spencer 2:1df0b61d3b5a 269 break;
Michael J. Spencer 2:1df0b61d3b5a 270 case STATE_WILL:
Michael J. Spencer 2:1df0b61d3b5a 271 if (c == TELNET_LINEMODE) {
Michael J. Spencer 2:1df0b61d3b5a 272 //sendopt(TELNET_DO, c);
Michael J. Spencer 2:1df0b61d3b5a 273 }
Michael J. Spencer 2:1df0b61d3b5a 274 state = STATE_NORMAL;
Michael J. Spencer 2:1df0b61d3b5a 275 break;
Michael J. Spencer 2:1df0b61d3b5a 276
Michael J. Spencer 2:1df0b61d3b5a 277 case STATE_WONT:
Michael J. Spencer 2:1df0b61d3b5a 278 /* Reply with a DONT */
Michael J. Spencer 2:1df0b61d3b5a 279 //sendopt(TELNET_DONT, c);
Michael J. Spencer 2:1df0b61d3b5a 280 state = STATE_NORMAL;
Michael J. Spencer 2:1df0b61d3b5a 281 break;
Michael J. Spencer 2:1df0b61d3b5a 282 case STATE_DO:
Michael J. Spencer 2:1df0b61d3b5a 283 if (c == TELNET_X_PROMPT) {
Michael J. Spencer 2:1df0b61d3b5a 284 prompt= true;
Michael J. Spencer 2:1df0b61d3b5a 285 }else if (c == TELNET_GA) {
Michael J. Spencer 2:1df0b61d3b5a 286 // enable prompt if telnet client running
Michael J. Spencer 2:1df0b61d3b5a 287 prompt= true;
Michael J. Spencer 2:1df0b61d3b5a 288 shell->setConsole(); // tell shell we are a console, as this is sent be telnet clients
Michael J. Spencer 2:1df0b61d3b5a 289 }else{
Michael J. Spencer 2:1df0b61d3b5a 290 /* Reply with a WONT */
Michael J. Spencer 2:1df0b61d3b5a 291 //sendopt(TELNET_WONT, c);
Michael J. Spencer 2:1df0b61d3b5a 292 }
Michael J. Spencer 2:1df0b61d3b5a 293 state = STATE_NORMAL;
Michael J. Spencer 2:1df0b61d3b5a 294 break;
Michael J. Spencer 2:1df0b61d3b5a 295 case STATE_DONT:
Michael J. Spencer 2:1df0b61d3b5a 296 if (c == TELNET_X_PROMPT) {
Michael J. Spencer 2:1df0b61d3b5a 297 prompt= false;
Michael J. Spencer 2:1df0b61d3b5a 298 }else{
Michael J. Spencer 2:1df0b61d3b5a 299 /* Reply with a WONT */
Michael J. Spencer 2:1df0b61d3b5a 300 //sendopt(TELNET_WONT, c);
Michael J. Spencer 2:1df0b61d3b5a 301 }
Michael J. Spencer 2:1df0b61d3b5a 302 state = STATE_NORMAL;
Michael J. Spencer 2:1df0b61d3b5a 303 break;
Michael J. Spencer 2:1df0b61d3b5a 304 case STATE_NORMAL:
Michael J. Spencer 2:1df0b61d3b5a 305 if (c == TELNET_IAC) {
Michael J. Spencer 2:1df0b61d3b5a 306 state = STATE_IAC;
Michael J. Spencer 2:1df0b61d3b5a 307 } else {
Michael J. Spencer 2:1df0b61d3b5a 308 get_char(c);
Michael J. Spencer 2:1df0b61d3b5a 309 }
Michael J. Spencer 2:1df0b61d3b5a 310 break;
Michael J. Spencer 2:1df0b61d3b5a 311 }
Michael J. Spencer 2:1df0b61d3b5a 312 }
Michael J. Spencer 2:1df0b61d3b5a 313
Michael J. Spencer 2:1df0b61d3b5a 314 // if the command queue is getting too big we stop TCP
Michael J. Spencer 2:1df0b61d3b5a 315 if(shell->queue_size() > 20) {
Michael J. Spencer 2:1df0b61d3b5a 316 DEBUG_PRINTF("Telnet: stopped: %d\n", shell->queue_size());
Michael J. Spencer 2:1df0b61d3b5a 317 uip_stop();
Michael J. Spencer 2:1df0b61d3b5a 318 }
Michael J. Spencer 2:1df0b61d3b5a 319 }
Michael J. Spencer 2:1df0b61d3b5a 320
Michael J. Spencer 2:1df0b61d3b5a 321 void Telnetd::poll()
Michael J. Spencer 2:1df0b61d3b5a 322 {
Michael J. Spencer 2:1df0b61d3b5a 323 if(first_time) {
Michael J. Spencer 2:1df0b61d3b5a 324 first_time= false;
Michael J. Spencer 2:1df0b61d3b5a 325 shell->start();
Michael J. Spencer 2:1df0b61d3b5a 326 senddata();
Michael J. Spencer 2:1df0b61d3b5a 327 }
Michael J. Spencer 2:1df0b61d3b5a 328 }
Michael J. Spencer 2:1df0b61d3b5a 329
Michael J. Spencer 2:1df0b61d3b5a 330 Telnetd::Telnetd()
Michael J. Spencer 2:1df0b61d3b5a 331 {
Michael J. Spencer 2:1df0b61d3b5a 332 DEBUG_PRINTF("Telnetd: ctor %p\n", this);
Michael J. Spencer 2:1df0b61d3b5a 333 for (int i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
Michael J. Spencer 2:1df0b61d3b5a 334 lines[i] = NULL;
Michael J. Spencer 2:1df0b61d3b5a 335 }
Michael J. Spencer 2:1df0b61d3b5a 336
Michael J. Spencer 2:1df0b61d3b5a 337 first_time= true;
Michael J. Spencer 2:1df0b61d3b5a 338 bufptr = 0;
Michael J. Spencer 2:1df0b61d3b5a 339 state = STATE_NORMAL;
Michael J. Spencer 2:1df0b61d3b5a 340 prompt= false;
Michael J. Spencer 2:1df0b61d3b5a 341 shell= new Shell(this);
Michael J. Spencer 2:1df0b61d3b5a 342 }
Michael J. Spencer 2:1df0b61d3b5a 343
Michael J. Spencer 2:1df0b61d3b5a 344 Telnetd::~Telnetd()
Michael J. Spencer 2:1df0b61d3b5a 345 {
Michael J. Spencer 2:1df0b61d3b5a 346 DEBUG_PRINTF("Telnetd: dtor %p\n", this);
Michael J. Spencer 2:1df0b61d3b5a 347 for (int i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
Michael J. Spencer 2:1df0b61d3b5a 348 if (lines[i] != NULL) dealloc_line(lines[i]);
Michael J. Spencer 2:1df0b61d3b5a 349 }
Michael J. Spencer 2:1df0b61d3b5a 350 delete shell;
Michael J. Spencer 2:1df0b61d3b5a 351 }
Michael J. Spencer 2:1df0b61d3b5a 352
Michael J. Spencer 2:1df0b61d3b5a 353 // static
Michael J. Spencer 2:1df0b61d3b5a 354 void Telnetd::appcall(void)
Michael J. Spencer 2:1df0b61d3b5a 355 {
Michael J. Spencer 2:1df0b61d3b5a 356 Telnetd *instance= reinterpret_cast<Telnetd *>(uip_conn->appstate);
Michael J. Spencer 2:1df0b61d3b5a 357
Michael J. Spencer 2:1df0b61d3b5a 358 if (uip_connected()) {
Michael J. Spencer 2:1df0b61d3b5a 359 // create a new telnet class instance
Michael J. Spencer 2:1df0b61d3b5a 360 instance= new Telnetd;
Michael J. Spencer 2:1df0b61d3b5a 361 DEBUG_PRINTF("Telnetd new instance: %p\n", instance);
Michael J. Spencer 2:1df0b61d3b5a 362 uip_conn->appstate= instance; // and store it in the appstate of the connection
Michael J. Spencer 2:1df0b61d3b5a 363 instance->rport= uip_conn->rport;
Michael J. Spencer 2:1df0b61d3b5a 364 }
Michael J. Spencer 2:1df0b61d3b5a 365
Michael J. Spencer 2:1df0b61d3b5a 366 if (uip_closed() || uip_aborted() || uip_timedout()) {
Michael J. Spencer 2:1df0b61d3b5a 367 DEBUG_PRINTF("Telnetd: closed: %p\n", instance);
Michael J. Spencer 2:1df0b61d3b5a 368 if(instance != NULL) {
Michael J. Spencer 2:1df0b61d3b5a 369 delete instance;
Michael J. Spencer 2:1df0b61d3b5a 370 uip_conn->appstate= NULL;
Michael J. Spencer 2:1df0b61d3b5a 371 }
Michael J. Spencer 2:1df0b61d3b5a 372 return;
Michael J. Spencer 2:1df0b61d3b5a 373 }
Michael J. Spencer 2:1df0b61d3b5a 374
Michael J. Spencer 2:1df0b61d3b5a 375 // sanity check
Michael J. Spencer 2:1df0b61d3b5a 376 if(instance == NULL || instance->rport != uip_conn->rport) {
Michael J. Spencer 2:1df0b61d3b5a 377 DEBUG_PRINTF("Telnetd: ERROR Null instance or rport is wrong: %p - %u, %d\n", instance, HTONS(uip_conn->rport), uip_flags);
Michael J. Spencer 2:1df0b61d3b5a 378 uip_abort();
Michael J. Spencer 2:1df0b61d3b5a 379 return;
Michael J. Spencer 2:1df0b61d3b5a 380 }
Michael J. Spencer 2:1df0b61d3b5a 381
Michael J. Spencer 2:1df0b61d3b5a 382 if (instance->state == STATE_CLOSE) {
Michael J. Spencer 2:1df0b61d3b5a 383 uip_close();
Michael J. Spencer 2:1df0b61d3b5a 384 }
Michael J. Spencer 2:1df0b61d3b5a 385
Michael J. Spencer 2:1df0b61d3b5a 386
Michael J. Spencer 2:1df0b61d3b5a 387 if (uip_acked()) {
Michael J. Spencer 2:1df0b61d3b5a 388 instance->acked();
Michael J. Spencer 2:1df0b61d3b5a 389 }
Michael J. Spencer 2:1df0b61d3b5a 390
Michael J. Spencer 2:1df0b61d3b5a 391 if (uip_newdata()) {
Michael J. Spencer 2:1df0b61d3b5a 392 instance->newdata();
Michael J. Spencer 2:1df0b61d3b5a 393 }
Michael J. Spencer 2:1df0b61d3b5a 394
Michael J. Spencer 2:1df0b61d3b5a 395 if (uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) {
Michael J. Spencer 2:1df0b61d3b5a 396 instance->senddata();
Michael J. Spencer 2:1df0b61d3b5a 397 }
Michael J. Spencer 2:1df0b61d3b5a 398
Michael J. Spencer 2:1df0b61d3b5a 399 if(uip_poll() && uip_stopped(uip_conn) && instance->shell->queue_size() < 5) {
Michael J. Spencer 2:1df0b61d3b5a 400 DEBUG_PRINTF("restarted %d - %p\n", instance->shell->queue_size(), instance);
Michael J. Spencer 2:1df0b61d3b5a 401 uip_restart();
Michael J. Spencer 2:1df0b61d3b5a 402 }
Michael J. Spencer 2:1df0b61d3b5a 403
Michael J. Spencer 2:1df0b61d3b5a 404 if(uip_poll()) {
Michael J. Spencer 2:1df0b61d3b5a 405 instance->poll();
Michael J. Spencer 2:1df0b61d3b5a 406 }
Michael J. Spencer 2:1df0b61d3b5a 407 }
Michael J. Spencer 2:1df0b61d3b5a 408
Michael J. Spencer 2:1df0b61d3b5a 409 // static
Michael J. Spencer 2:1df0b61d3b5a 410 void Telnetd::init(void)
Michael J. Spencer 2:1df0b61d3b5a 411 {
Michael J. Spencer 2:1df0b61d3b5a 412 uip_listen(HTONS(23));
Michael J. Spencer 2:1df0b61d3b5a 413 }