aboutsummaryrefslogtreecommitdiff
path: root/networking/telnet.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/telnet.c')
-rw-r--r--networking/telnet.c142
1 files changed, 68 insertions, 74 deletions
diff --git a/networking/telnet.c b/networking/telnet.c
index 9085c5848..78229cd01 100644
--- a/networking/telnet.c
+++ b/networking/telnet.c
@@ -101,6 +101,7 @@ static void iacflush(void)
101 101
102#define write_str(fd, str) write(fd, str, sizeof(str) - 1) 102#define write_str(fd, str) write(fd, str, sizeof(str) - 1)
103 103
104static void doexit(int ev) ATTRIBUTE_NORETURN;
104static void doexit(int ev) 105static void doexit(int ev)
105{ 106{
106 cookmode(); 107 cookmode();
@@ -157,31 +158,29 @@ static void conescape(void)
157 158
158static void handlenetoutput(int len) 159static void handlenetoutput(int len)
159{ 160{
160 /* here we could do smart tricks how to handle 0xFF:s in output 161 /* here we could do smart tricks how to handle 0xFF:s in output
161 * stream like writing twice every sequence of FF:s (thus doing 162 * stream like writing twice every sequence of FF:s (thus doing
162 * many write()s. But I think interactive telnet application does 163 * many write()s. But I think interactive telnet application does
163 * not need to be 100% 8-bit clean, so changing every 0xff:s to 164 * not need to be 100% 8-bit clean, so changing every 0xff:s to
164 * 0x7f:s 165 * 0x7f:s
165 * 166 *
166 * 2002-mar-21, Przemyslaw Czerpak (druzus@polbox.com) 167 * 2002-mar-21, Przemyslaw Czerpak (druzus@polbox.com)
167 * I don't agree. 168 * I don't agree.
168 * first - I cannot use programs like sz/rz 169 * first - I cannot use programs like sz/rz
169 * second - the 0x0D is sent as one character and if the next 170 * second - the 0x0D is sent as one character and if the next
170 * char is 0x0A then it's eaten by a server side. 171 * char is 0x0A then it's eaten by a server side.
171 * third - whay doy you have to make 'many write()s'? 172 * third - whay doy you have to make 'many write()s'?
172 * I don't understand. 173 * I don't understand.
173 * So I implemented it. It's realy useful for me. I hope that 174 * So I implemented it. It's realy useful for me. I hope that
174 * others people will find it interesting to. 175 * others people will find it interesting too.
175 */ 176 */
176 177
177 int i, j; 178 int i, j;
178 byte * p = (byte*)G.buf; 179 byte * p = (byte*)G.buf;
179 byte outbuf[4*DATABUFSIZE]; 180 byte outbuf[4*DATABUFSIZE];
180 181
181 for (i = len, j = 0; i > 0; i--, p++) 182 for (i = len, j = 0; i > 0; i--, p++) {
182 { 183 if (*p == 0x1d) {
183 if (*p == 0x1d)
184 {
185 conescape(); 184 conescape();
186 return; 185 return;
187 } 186 }
@@ -200,68 +199,59 @@ static void handlenetinput(int len)
200 int i; 199 int i;
201 int cstart = 0; 200 int cstart = 0;
202 201
203 for (i = 0; i < len; i++) 202 for (i = 0; i < len; i++) {
204 {
205 byte c = G.buf[i]; 203 byte c = G.buf[i];
206 204
207 if (G.telstate == 0) /* most of the time state == 0 */ 205 if (G.telstate == 0) { /* most of the time state == 0 */
208 { 206 if (c == IAC) {
209 if (c == IAC)
210 {
211 cstart = i; 207 cstart = i;
212 G.telstate = TS_IAC; 208 G.telstate = TS_IAC;
213 } 209 }
214 } 210 } else
215 else 211 switch (G.telstate) {
216 switch (G.telstate) 212 case TS_0:
217 { 213 if (c == IAC)
218 case TS_0: 214 G.telstate = TS_IAC;
219 if (c == IAC) 215 else
220 G.telstate = TS_IAC; 216 G.buf[cstart++] = c;
221 else 217 break;
222 G.buf[cstart++] = c; 218
223 break; 219 case TS_IAC:
224 220 if (c == IAC) { /* IAC IAC -> 0xFF */
225 case TS_IAC: 221 G.buf[cstart++] = c;
226 if (c == IAC) /* IAC IAC -> 0xFF */ 222 G.telstate = TS_0;
227 { 223 break;
228 G.buf[cstart++] = c; 224 }
229 G.telstate = TS_0; 225 /* else */
230 break; 226 switch (c) {
231 } 227 case SB:
232 /* else */ 228 G.telstate = TS_SUB1;
233 switch (c) 229 break;
234 { 230 case DO:
235 case SB: 231 case DONT:
236 G.telstate = TS_SUB1; 232 case WILL:
237 break; 233 case WONT:
238 case DO: 234 G.telwish = c;
239 case DONT: 235 G.telstate = TS_OPT;
240 case WILL: 236 break;
241 case WONT: 237 default:
242 G.telwish = c; 238 G.telstate = TS_0; /* DATA MARK must be added later */
243 G.telstate = TS_OPT; 239 }
244 break; 240 break;
245 default: 241 case TS_OPT: /* WILL, WONT, DO, DONT */
246 G.telstate = TS_0; /* DATA MARK must be added later */ 242 telopt(c);
247 } 243 G.telstate = TS_0;
248 break; 244 break;
249 case TS_OPT: /* WILL, WONT, DO, DONT */ 245 case TS_SUB1: /* Subnegotiation */
250 telopt(c); 246 case TS_SUB2: /* Subnegotiation */
251 G.telstate = TS_0; 247 if (subneg(c))
252 break; 248 G.telstate = TS_0;
253 case TS_SUB1: /* Subnegotiation */ 249 break;
254 case TS_SUB2: /* Subnegotiation */ 250 }
255 if (subneg(c))
256 G.telstate = TS_0;
257 break;
258 }
259 } 251 }
260 if (G.telstate) 252 if (G.telstate) {
261 { 253 if (G.iaclen) iacflush();
262 if (G.iaclen) iacflush();
263 if (G.telstate == TS_0) G.telstate = 0; 254 if (G.telstate == TS_0) G.telstate = 0;
264
265 len = cstart; 255 len = cstart;
266 } 256 }
267 257
@@ -440,7 +430,8 @@ static void to_sga(void)
440 } else if (G.telwish == WONT) 430 } else if (G.telwish == WONT)
441 return; 431 return;
442 432
443 if ((G.telflags ^= UF_SGA) & UF_SGA) /* toggle */ 433 G.telflags ^= UF_SGA; /* toggle */
434 if (G.telflags & UF_SGA)
444 putiac2(DO, TELOPT_SGA); 435 putiac2(DO, TELOPT_SGA);
445 else 436 else
446 putiac2(DONT, TELOPT_SGA); 437 putiac2(DONT, TELOPT_SGA);
@@ -550,6 +541,9 @@ static void cookmode(void)
550 tcsetattr(0, TCSADRAIN, &G.termios_def); 541 tcsetattr(0, TCSADRAIN, &G.termios_def);
551} 542}
552 543
544/* poll gives smaller (-70 bytes) code */
545#define USE_POLL 1
546
553int telnet_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 547int telnet_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
554int telnet_main(int argc, char **argv) 548int telnet_main(int argc, char **argv)
555{ 549{