1 /******************************************************************************
2 *   This file is part of TinTin++                                             *
3 *                                                                             *
4 *   Copyright 2004-2020 Igor van den Hoven                                    *
5 *                                                                             *
6 *   TinTin++ is free software; you can redistribute it and/or modify          *
7 *   it under the terms of the GNU General Public License as published by      *
8 *   the Free Software Foundation; either version 3 of the License, or         *
9 *   (at your option) any later version.                                       *
10 *                                                                             *
11 *   This program is distributed in the hope that it will be useful,           *
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of            *
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
14 *   GNU General Public License for more details.                              *
15 *                                                                             *
16 *   You should have received a copy of the GNU General Public License         *
17 *   along with TinTin++.  If not, see https://www.gnu.org/licenses.           *
18 ******************************************************************************/
19 
20 /******************************************************************************
21 *                               T I N T I N + +                               *
22 *                                                                             *
23 *                      coded by Igor van den Hoven 2004                       *
24 ******************************************************************************/
25 
26 
27 #include "tintin.h"
28 
29 
DO_COMMAND(do_configure)30 DO_COMMAND(do_configure)
31 {
32 	struct listnode *node;
33 	int index;
34 
35 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
36 	arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN);
37 
38 	if (*arg1 == 0)
39 	{
40 		tintin_header(ses, 80, " CONFIGURATIONS ");
41 
42 		for (index = 0 ; *config_table[index].name != 0 ; index++)
43 		{
44 			node = search_node_list(ses->list[LIST_CONFIG], config_table[index].name);
45 
46 			if (node)
47 			{
48 				strcpy(arg2, "");
49 
50 				config_table[index].config(ses, arg1, arg2, index);
51 
52 				tintin_printf2(ses, "[%-14s] [%12s] %s",
53 					node->arg1,
54 					arg2,
55 					strcmp(node->arg2, "OFF") ? config_table[index].msg_on : config_table[index].msg_off);
56 			}
57 		}
58 
59 		tintin_header(ses, 80, "");
60 	}
61 	else
62 	{
63 		// fixing silly config name
64 
65 		if (is_abbrev(arg1, "MOUSE TRACKING"))
66 		{
67 			str_cpy(&arg1, "MOUSE");
68 		}
69 
70 		for (index = 0 ; *config_table[index].name != 0 ; index++)
71 		{
72 			if (is_abbrev(arg1, config_table[index].name))
73 			{
74 				if (*arg2)
75 				{
76 					if (config_table[index].config(ses, arg1, arg2, index) != NULL)
77 					{
78 						update_node_list(ses->list[LIST_CONFIG], config_table[index].name, arg2, "", "");
79 
80 						node = search_node_list(ses->list[LIST_CONFIG], config_table[index].name);
81 
82 						if (node)
83 						{
84 							show_message(ses, LIST_CONFIG, "#CONFIG {%s} HAS BEEN SET TO {%s}.", config_table[index].name, node->arg2);
85 						}
86 					}
87 				}
88 				else
89 				{
90 					config_table[index].config(ses, arg1, arg2, index);
91 
92 					show_message(ses, LIST_CONFIG, "#CONFIG {%s} IS SET TO {%s}.", config_table[index].name, arg2);
93 				}
94 				return ses;
95 			}
96 		}
97 		show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG {%s} IS NOT A VALID OPTION.", capitalize(arg1));
98 	}
99 	return ses;
100 }
101 
DO_CONFIG(config_autotab)102 DO_CONFIG(config_autotab)
103 {
104 	if (*arg2)
105 	{
106 		if (!is_number(arg2))
107 		{
108 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {AUTO TAB} <NUMBER>");
109 
110 			return NULL;
111 		}
112 
113 		if (atoi(arg2) < 1 || atoi(arg2) > 999999)
114 		{
115 			show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG BUFFER: PROVIDE A NUMBER BETWEEN 1 and 999999");
116 
117 			return NULL;
118 		}
119 
120 		ses->scrollback_tab = atoi(arg2);
121 	}
122 	sprintf(arg2, "%d", ses->scrollback_tab);
123 
124 	return ses;
125 }
126 
127 
DO_CONFIG(config_buffersize)128 DO_CONFIG(config_buffersize)
129 {
130 	if (*arg2)
131 	{
132 		if (!is_number(arg2))
133 		{
134 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {BUFFER SIZE} <NUMBER>");
135 
136 			return NULL;
137 		}
138 
139 		switch (atoi(arg2))
140 		{
141 			case 100:
142 			case 1000:
143 			case 10000:
144 			case 100000:
145 			case 1000000:
146 				break;
147 
148 			default:
149 				show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG BUFFER: SIZE MUST BE 100, 1000, 10000, 100000, or 1000000.");
150 				return NULL;
151 		}
152 		init_buffer(ses, atoi(arg2));
153 	}
154 	sprintf(arg2, "%d", ses->scroll->size);
155 
156 	return ses;
157 }
158 
DO_CONFIG(config_charset)159 DO_CONFIG(config_charset)
160 {
161 	if (*arg2)
162 	{
163 		if (is_abbrev(arg2, "AUTO"))
164 		{
165 			if (strcasestr(gtd->system->lang, "UTF-8"))
166 			{
167 				DEL_BIT(ses->charset, CHARSET_FLAG_ALL);
168 				SET_BIT(ses->charset, CHARSET_FLAG_UTF8);
169 			}
170 			else if (strcasestr(gtd->system->lang, "BIG-5"))
171 			{
172 				DEL_BIT(ses->charset, CHARSET_FLAG_ALL);
173 				SET_BIT(ses->charset, CHARSET_FLAG_BIG5);
174 			}
175 			else if (strcasestr(gtd->system->term, "XTERM"))
176 			{
177 				DEL_BIT(ses->charset, CHARSET_FLAG_ALL);
178 				SET_BIT(ses->charset, CHARSET_FLAG_UTF8);
179 			}
180 			else
181 			{
182 				DEL_BIT(ses->charset, CHARSET_FLAG_ALL);
183 			}
184 		}
185 		else
186 		{
187 			for (index = 0 ; *charset_table[index].name ; index++)
188 			{
189 				if (is_abbrev(arg2, charset_table[index].name))
190 				{
191 					break;
192 				}
193 			}
194 
195 			if (*charset_table[index].name == 0)
196 			{
197 				show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {CHARSET} <AUTO|ASCII|BIG-5|BIG5TOUTF8|CP1251TOUTF8|CP949|CP949TOUTF8|FANSI|GBK-1|GBK1TOUTF8|ISO1TOUTF8|ISO2TOUTF8|KOI8TOUTF8|UTF-8>");
198 
199 				return NULL;
200 			}
201 
202 			DEL_BIT(ses->charset, CHARSET_FLAG_ALL);
203 
204 			SET_BIT(ses->charset, charset_table[index].flags);
205 		}
206 	}
207 	else
208 	{
209 		for (index = 0 ; *charset_table[index].name ; index++)
210 		{
211 			if (ses->charset == charset_table[index].flags)
212 			{
213 				break;
214 			}
215 		}
216 
217 		if (*charset_table[index].name == 0)
218 		{
219 			show_error(ses, LIST_CONFIG, "#CONFIG CHARSET: INVALID FLAG: %d", ses->charset);
220 
221 			return NULL;
222 		}
223 	}
224 
225 	strcpy(arg2, charset_table[index].name);
226 
227 	return ses;
228 }
229 
DO_CONFIG(config_childlock)230 DO_CONFIG(config_childlock)
231 {
232 	if (*arg2)
233 	{
234 		if (is_abbrev(arg2, "ON"))
235 		{
236 			SET_BIT(gtd->flags, TINTIN_FLAG_CHILDLOCK);
237 		}
238 		else if (is_abbrev(arg2, "OFF"))
239 		{
240 			DEL_BIT(gtd->flags, TINTIN_FLAG_CHILDLOCK);
241 		}
242 		else
243 		{
244 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
245 
246 			return NULL;
247 		}
248 	}
249 	strcpy(arg2, HAS_BIT(gtd->flags, TINTIN_FLAG_CHILDLOCK) ? "ON" : "OFF");
250 
251 	return ses;
252 }
253 
DO_CONFIG(config_colormode)254 DO_CONFIG(config_colormode)
255 {
256 	if (*arg2)
257 	{
258 		if (is_abbrev(arg2, "NONE") || is_abbrev(arg2, "OFF"))
259 		{
260 			ses->color = 0;
261 		}
262 		else if (is_abbrev(arg2, "REVERSE"))
263 		{
264 			ses->color = 0;
265 			printf("\e[30m");
266 		}
267 		else if (is_abbrev(arg2, "ANSI"))
268 		{
269 			ses->color = 16;
270 		}
271 		else if (is_abbrev(arg2, "256"))
272 		{
273 			ses->color = 256;
274 		}
275 		else if (is_abbrev(arg2, "TRUE") || is_abbrev(arg2, "ON") || is_abbrev(arg2, "AUTO"))
276 		{
277 			ses->color = 4096;
278 		}
279 		else
280 		{
281 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF|ANSI|256|TRUE>", config_table[index].name);
282 
283 			return NULL;
284 		}
285 	}
286 	strcpy(arg2, ses->color == 0 ? "OFF" : ses->color == 16 ? "ANSI" : ses->color == 256 ? "256" : "TRUE");
287 
288 	return ses;
289 }
290 
DO_CONFIG(config_colorpatch)291 DO_CONFIG(config_colorpatch)
292 {
293 	if (*arg2)
294 	{
295 		if (is_abbrev(arg2, "ON"))
296 		{
297 			SET_BIT(ses->config_flags, CONFIG_FLAG_COLORPATCH);
298 		}
299 		else if (is_abbrev(arg2, "OFF"))
300 		{
301 			DEL_BIT(ses->config_flags, CONFIG_FLAG_COLORPATCH);
302 		}
303 		else
304 		{
305 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
306 
307 			return NULL;
308 		}
309 	}
310 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_COLORPATCH) ? "ON" : "OFF");
311 
312 	return ses;
313 }
314 
DO_CONFIG(config_commandcolor)315 DO_CONFIG(config_commandcolor)
316 {
317 	if (*arg2)
318 	{
319 		get_color_names(ses, arg2, arg1);
320 
321 		RESTRING(ses->cmd_color, arg1);
322 	}
323 	convert_meta(ses->cmd_color, arg2, SUB_EOL);
324 
325 	return ses;
326 }
327 
DO_CONFIG(config_commandecho)328 DO_CONFIG(config_commandecho)
329 {
330 	if (*arg2)
331 	{
332 		if (is_abbrev(arg2, "ON"))
333 		{
334 			SET_BIT(ses->config_flags, CONFIG_FLAG_ECHOCOMMAND);
335 		}
336 		else if (is_abbrev(arg2, "OFF"))
337 		{
338 			DEL_BIT(ses->config_flags, CONFIG_FLAG_ECHOCOMMAND);
339 		}
340 		else
341 		{
342 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
343 
344 			return NULL;
345 		}
346 	}
347 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_ECHOCOMMAND) ? "ON" : "OFF");
348 
349 	return ses;
350 }
351 
DO_CONFIG(config_connectretry)352 DO_CONFIG(config_connectretry)
353 {
354 	if (*arg2)
355 	{
356 		if (!is_number(arg2))
357 		{
358 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {CONNECT RETRY} <NUMBER>");
359 
360 			return NULL;
361 		}
362 		else if (atof(arg2) < 0 || atof(arg2) > 10000)
363 		{
364 			show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG CONNECT RETRY: PROVIDE A NUMBER BETWEEN 0.0 and 10000.0");
365 
366 			return NULL;
367 		}
368 		gts->connect_retry = atoll(arg2) * 1000000LL;
369 	}
370 
371 	sprintf(arg2, "%.1Lf", (long double) gts->connect_retry / 1000000);
372 
373 	return ses;
374 }
375 
DO_CONFIG(config_convertmeta)376 DO_CONFIG(config_convertmeta)
377 {
378 	if (*arg2)
379 	{
380 		if (is_abbrev(arg2, "ON"))
381 		{
382 			SET_BIT(ses->config_flags, CONFIG_FLAG_CONVERTMETA);
383 		}
384 		else if (is_abbrev(arg2, "OFF"))
385 		{
386 			DEL_BIT(ses->config_flags, CONFIG_FLAG_CONVERTMETA);
387 		}
388 		else
389 		{
390 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
391 
392 			return NULL;
393 		}
394 	}
395 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_CONVERTMETA) ? "ON" : "OFF");
396 
397 	return ses;
398 }
399 
DO_CONFIG(config_debugtelnet)400 DO_CONFIG(config_debugtelnet)
401 {
402 	if (*arg2)
403 	{
404 		if (is_abbrev(arg2, "ON"))
405 		{
406 			SET_BIT(ses->telopts, TELOPT_FLAG_DEBUG);
407 		}
408 		else if (is_abbrev(arg2, "OFF"))
409 		{
410 			DEL_BIT(ses->telopts, TELOPT_FLAG_DEBUG);
411 		}
412 		else
413 		{
414 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
415 
416 			return NULL;
417 		}
418 	}
419 	strcpy(arg2, HAS_BIT(ses->telopts, TELOPT_FLAG_DEBUG) ? "ON" : "OFF");
420 
421 	return ses;
422 }
423 
DO_CONFIG(config_historysize)424 DO_CONFIG(config_historysize)
425 {
426 	if (*arg2)
427 	{
428 		if (!is_number(arg2))
429 		{
430 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {HISTORY SIZE} <NUMBER>");
431 
432 			return NULL;
433 		}
434 
435 		if (atoi(arg2) < 0 || atoi(arg2) > 9999)
436 		{
437 			show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG HISTORY: PROVIDE A NUMBER BETWEEN 0 and 9999");
438 
439 			return NULL;
440 		}
441 
442 		gtd->history_size = atoi(arg2);
443 	}
444 	sprintf(arg2, "%d", gtd->history_size);
445 
446 	return ses;
447 }
448 
DO_CONFIG(config_inheritance)449 DO_CONFIG(config_inheritance)
450 {
451 	if (*arg2)
452 	{
453 		if (is_abbrev(arg2, "ON"))
454 		{
455 			SET_BIT(gtd->flags, TINTIN_FLAG_INHERITANCE);
456 		}
457 		else if (is_abbrev(arg2, "OFF"))
458 		{
459 			DEL_BIT(gtd->flags, TINTIN_FLAG_INHERITANCE);
460 		}
461 		else
462 		{
463 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
464 
465 			return NULL;
466 		}
467 	}
468 	strcpy(arg2, HAS_BIT(gtd->flags, TINTIN_FLAG_INHERITANCE) ? "ON" : "OFF");
469 
470 	return ses;
471 }
472 
473 
DO_CONFIG(config_loglevel)474 DO_CONFIG(config_loglevel)
475 {
476 	if (*arg2)
477 	{
478 		if (is_abbrev(arg2, "LOW"))
479 		{
480 			SET_BIT(ses->log->mode, LOG_FLAG_LOW);
481 		}
482 		else if (is_abbrev(arg2, "HIGH"))
483 		{
484 			DEL_BIT(ses->log->mode, LOG_FLAG_LOW);
485 		}
486 		else
487 		{
488 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <LOW|HIGH>", config_table[index].name);
489 
490 			return NULL;
491 		}
492 	}
493 	strcpy(arg2, HAS_BIT(ses->log->mode, LOG_FLAG_LOW) ? "LOW" : "HIGH");
494 
495 	return ses;
496 }
497 
498 
DO_CONFIG(config_logmode)499 DO_CONFIG(config_logmode)
500 {
501 	if (*arg2)
502 	{
503 		if (is_abbrev(arg2, "HTML"))
504 		{
505 			SET_BIT(ses->log->mode, LOG_FLAG_HTML);
506 			DEL_BIT(ses->log->mode, LOG_FLAG_PLAIN);
507 			DEL_BIT(ses->log->mode, LOG_FLAG_RAW);
508 		}
509 		else if (is_abbrev(arg2, "PLAIN"))
510 		{
511 			DEL_BIT(ses->log->mode, LOG_FLAG_HTML);
512 			SET_BIT(ses->log->mode, LOG_FLAG_PLAIN);
513 			DEL_BIT(ses->log->mode, LOG_FLAG_RAW);
514 		}
515 		else if (is_abbrev(arg2, "RAW"))
516 		{
517 			DEL_BIT(ses->log->mode, LOG_FLAG_HTML);
518 			DEL_BIT(ses->log->mode, LOG_FLAG_PLAIN);
519 			SET_BIT(ses->log->mode, LOG_FLAG_RAW);
520 		}
521 		else
522 		{
523 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG LOG <HTML|PLAIN|RAW>");
524 
525 			return NULL;
526 		}
527 	}
528 	strcpy(arg2, HAS_BIT(ses->log->mode, LOG_FLAG_HTML) ? "HTML" : HAS_BIT(ses->log->mode, LOG_FLAG_PLAIN) ? "PLAIN" : "RAW");
529 
530 	return ses;
531 }
532 
533 
DO_CONFIG(config_mccp)534 DO_CONFIG(config_mccp)
535 {
536 	if (*arg2)
537 	{
538 		if (is_abbrev(arg2, "ON"))
539 		{
540 			SET_BIT(ses->config_flags, CONFIG_FLAG_MCCP);
541 		}
542 		else if (is_abbrev(arg2, "OFF"))
543 		{
544 			DEL_BIT(ses->config_flags, CONFIG_FLAG_MCCP);
545 		}
546 		else
547 		{
548 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
549 
550 			return NULL;
551 		}
552 	}
553 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_MCCP) ? "ON" : "OFF");
554 
555 	return ses;
556 }
557 
DO_CONFIG(config_mousetracking)558 DO_CONFIG(config_mousetracking)
559 {
560 	if (*arg2)
561 	{
562 		DEL_BIT(ses->config_flags, CONFIG_FLAG_MOUSEDEBUG);
563 		DEL_BIT(ses->config_flags, CONFIG_FLAG_MOUSEINFO);
564 		DEL_BIT(ses->config_flags, CONFIG_FLAG_MOUSEPIXELS);
565 		DEL_BIT(ses->config_flags, CONFIG_FLAG_MOUSEPIXELS);
566 		DEL_BIT(gtd->flags, TINTIN_FLAG_MOUSETRACKING);
567 
568 		if (is_member(arg2, "DEBUG"))
569 		{
570 			SET_BIT(ses->config_flags, CONFIG_FLAG_MOUSEDEBUG);
571 			SET_BIT(gtd->flags, TINTIN_FLAG_MOUSETRACKING);
572 		}
573 		if (is_member(arg2, "INFO"))
574 		{
575 			SET_BIT(ses->config_flags, CONFIG_FLAG_MOUSEINFO);
576 			SET_BIT(gtd->flags, TINTIN_FLAG_MOUSETRACKING);
577 		}
578 		if (is_member(arg2, "ON"))
579 		{
580 			SET_BIT(gtd->flags, TINTIN_FLAG_MOUSETRACKING);
581 		}
582 		if (is_member(arg2, "PIXELS"))
583 		{
584 			SET_BIT(ses->config_flags, CONFIG_FLAG_MOUSEPIXELS);
585 			SET_BIT(gtd->flags, TINTIN_FLAG_MOUSETRACKING);
586 		}
587 
588 		if (is_abbrev(arg2, "OFF"))
589 		{
590 			print_stdout(0, 0, "\e[?1000l\e[?1002l\e[?1006l\e[?1016l");
591 		}
592 		else
593 		{
594 			if (HAS_BIT(gtd->flags, TINTIN_FLAG_MOUSETRACKING))
595 			{
596 				if (HAS_BIT(ses->config_flags, CONFIG_FLAG_MOUSEPIXELS))
597 				{
598 					print_stdout(0, 0, "\e[?1000h\e[?1002h\e[?1016h");
599 				}
600 				else
601 				{
602 					print_stdout(0, 0, "\e[?1000h\e[?1002h\e[?1006h");
603 				}
604 			}
605 			else
606 			{
607 				show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF|DEBUG|INFO|PIXELS>", config_table[index].name);
608 
609 				return NULL;
610 			}
611 		}
612 	}
613 
614 	if (HAS_BIT(gtd->flags, TINTIN_FLAG_MOUSETRACKING))
615 	{
616 		if (!HAS_BIT(ses->config_flags, CONFIG_FLAG_MOUSEDEBUG|CONFIG_FLAG_MOUSEINFO|CONFIG_FLAG_MOUSEPIXELS))
617 		{
618 			strcpy(arg2, "ON");
619 		}
620 		else
621 		{
622 			strcpy(arg2, "");
623 
624 			if (HAS_BIT(ses->config_flags, CONFIG_FLAG_MOUSEPIXELS))
625 			{
626 				strcpy(arg2, "PIXELS");
627 			}
628 
629 			if (HAS_BIT(ses->config_flags, CONFIG_FLAG_MOUSEDEBUG))
630 			{
631 				strcat(arg2, *arg2 ? " DEBUG" : "DEBUG");
632 			}
633 
634 			if (HAS_BIT(ses->config_flags, CONFIG_FLAG_MOUSEINFO))
635 			{
636 				strcat(arg2, *arg2 ? " INFO" : "INFO");
637 			}
638 		}
639 	}
640 	else
641 	{
642 		strcpy(arg2, "OFF");
643 	}
644 	return ses;
645 }
646 
647 
DO_CONFIG(config_packetpatch)648 DO_CONFIG(config_packetpatch)
649 {
650 	if (*arg2)
651 	{
652 		if (is_abbrev(arg2, "AUTO PROMPT") || is_abbrev(arg2, "AUTO TELNET") || is_abbrev(arg2, "AUTO OFF"))
653 		{
654 			ses->packet_patch = 0;
655 
656 			SET_BIT(ses->config_flags, CONFIG_FLAG_AUTOPATCH);
657 		}
658 		else if (!is_number(arg2))
659 		{
660 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {PACKET PATCH} <NUMBER>");
661 
662 			return NULL;
663 		}
664 		else if (atof(arg2) < 0 || atof(arg2) > 10)
665 		{
666 			show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG PACKET PATCH: PROVIDE A NUMBER BETWEEN 0.00 and 10.00");
667 
668 			return NULL;
669 		}
670 		else
671 		{
672 			DEL_BIT(ses->config_flags, CONFIG_FLAG_AUTOPATCH);
673 
674 			ses->packet_patch = (unsigned long long) (tintoi(arg2) * 1000000ULL);
675 		}
676 	}
677 
678 	if (HAS_BIT(ses->config_flags, CONFIG_FLAG_AUTOPATCH))
679 	{
680 		if (ses->list[LIST_PROMPT]->list[0])
681 		{
682 			strcpy(arg2, "AUTO PROMPT");
683 		}
684 		else if (HAS_BIT(ses->config_flags, CONFIG_FLAG_AUTOPROMPT))
685 		{
686 			strcpy(arg2, "AUTO TELNET");
687 		}
688 		else
689 		{
690 			strcpy(arg2, "AUTO OFF");
691 		}
692 	}
693 	else
694 	{
695 		sprintf(arg2, "%4.2Lf", (long double) ses->packet_patch / 1000000);
696 	}
697 	return ses;
698 }
699 
DO_CONFIG(config_randomseed)700 DO_CONFIG(config_randomseed)
701 {
702 	if (*arg2)
703 	{
704 		if (is_abbrev(arg2, "AUTO"))
705 		{
706 			seed_rand(ses, ++gtd->utime);
707 		}
708 		else if (is_number(arg2))
709 		{
710 			seed_rand(ses, get_number(ses, arg2));
711 		}
712 		else
713 		{
714 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <AUTO|NUMBER>", config_table[index].name);
715 
716 			return NULL;
717 		}
718 	}
719 	sprintf(arg2, "%u", (unsigned int) ses->rand);
720 
721 	return ses;
722 }
723 
DO_CONFIG(config_repeatchar)724 DO_CONFIG(config_repeatchar)
725 {
726 	if (*arg2)
727 	{
728 		if (!ispunct((int) arg2[0]))
729 		{
730 			show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG REPEAT CHAR: INVALID CHARACTER {%c}", arg2[0]);
731 
732 			return NULL;
733 		}
734 
735 		gtd->repeat_char = arg2[0];
736 
737 		arg2[1] = 0;
738 	}
739 
740 	sprintf(arg2, "%c", gtd->repeat_char);
741 
742 	return ses;
743 }
744 
DO_CONFIG(config_repeatenter)745 DO_CONFIG(config_repeatenter)
746 {
747 	if (*arg2)
748 	{
749 		if (is_abbrev(arg2, "ON"))
750 		{
751 			SET_BIT(ses->config_flags, CONFIG_FLAG_REPEATENTER);
752 		}
753 		else if (is_abbrev(arg2, "OFF"))
754 		{
755 			DEL_BIT(ses->config_flags, CONFIG_FLAG_REPEATENTER);
756 		}
757 		else
758 		{
759 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
760 
761 			return NULL;
762 		}
763 	}
764 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_REPEATENTER) ? "ON" : "OFF");
765 
766 	return ses;
767 }
768 
769 
DO_CONFIG(config_screenreader)770 DO_CONFIG(config_screenreader)
771 {
772 	if (*arg2)
773 	{
774 		if (is_abbrev(arg2, "ON"))
775 		{
776 			SET_BIT(ses->config_flags, CONFIG_FLAG_SCREENREADER);
777 		}
778 		else if (is_abbrev(arg2, "OFF"))
779 		{
780 			DEL_BIT(ses->config_flags, CONFIG_FLAG_SCREENREADER);
781 		}
782 		else
783 		{
784 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
785 
786 			return NULL;
787 		}
788 	}
789 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_SCREENREADER) ? "ON" : "OFF");
790 
791 	return ses;
792 }
793 
794 
795 
796 
DO_CONFIG(config_scrolllock)797 DO_CONFIG(config_scrolllock)
798 {
799 	if (*arg2)
800 	{
801 		if (is_abbrev(arg2, "ON"))
802 		{
803 			SET_BIT(ses->config_flags, CONFIG_FLAG_SCROLLLOCK);
804 		}
805 		else if (is_abbrev(arg2, "OFF"))
806 		{
807 			DEL_BIT(ses->config_flags, CONFIG_FLAG_SCROLLLOCK);
808 		}
809 		else
810 		{
811 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
812 
813 			return NULL;
814 		}
815 	}
816 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_SCROLLLOCK) ? "ON" : "OFF");
817 
818 	return ses;
819 }
820 
DO_CONFIG(config_speedwalk)821 DO_CONFIG(config_speedwalk)
822 {
823 	if (*arg2)
824 	{
825 		if (is_abbrev(arg2, "ON"))
826 		{
827 			SET_BIT(ses->config_flags, CONFIG_FLAG_SPEEDWALK);
828 		}
829 		else if (is_abbrev(arg2, "OFF"))
830 		{
831 			DEL_BIT(ses->config_flags, CONFIG_FLAG_SPEEDWALK);
832 		}
833 		else
834 		{
835 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
836 
837 			return NULL;
838 		}
839 	}
840 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_SPEEDWALK) ? "ON" : "OFF");
841 
842 	return ses;
843 }
844 
DO_CONFIG(config_tabwidth)845 DO_CONFIG(config_tabwidth)
846 {
847 	if (*arg2)
848 	{
849 		if (is_abbrev(arg2, "AUTO"))
850 		{
851 			ses->tab_width = 8;
852 		}
853 		else if (!is_number(arg2))
854 		{
855 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {TAB WIDTH} <NUMBER>");
856 
857 			return NULL;
858 		}
859 		else if (atof(arg2) < 1 || atof(arg2) > 16)
860 		{
861 			show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG TAB WIDTH: PROVIDE A NUMBER BETWEEN 1 and 16");
862 
863 			return NULL;
864 		}
865 		else
866 		{
867 			ses->tab_width = (int) tintoi(arg2);
868 		}
869 	}
870 	sprintf(arg2, "%d", ses->tab_width);
871 
872 	return ses;
873 }
874 
DO_CONFIG(config_telnet)875 DO_CONFIG(config_telnet)
876 {
877 	if (*arg2)
878 	{
879 		if (is_abbrev(arg2, "ON"))
880 		{
881 			DEL_BIT(ses->telopts, TELOPT_FLAG_DEBUG);
882 			SET_BIT(ses->config_flags, CONFIG_FLAG_TELNET);
883 		}
884 		else if (is_abbrev(arg2, "OFF"))
885 		{
886 			DEL_BIT(ses->telopts, TELOPT_FLAG_DEBUG);
887 			DEL_BIT(ses->config_flags, CONFIG_FLAG_TELNET);
888 		}
889 		else if (is_abbrev(arg2, "DEBUG"))
890 		{
891 			SET_BIT(ses->telopts, TELOPT_FLAG_DEBUG);
892 			SET_BIT(ses->config_flags, CONFIG_FLAG_TELNET);
893 		}
894 		else if (is_abbrev(arg2, "INFO"))
895 		{
896 			SET_BIT(ses->telopts, TELOPT_FLAG_DEBUG);
897 			SET_BIT(ses->config_flags, CONFIG_FLAG_TELNET);
898 		}
899 		else
900 		{
901 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF|DEBUG|INFO>", config_table[index].name);
902 
903 			return NULL;
904 		}
905 	}
906 	strcpy(arg2, HAS_BIT(ses->telopts, TELOPT_FLAG_DEBUG) ? "DEBUG" : HAS_BIT(ses->config_flags, CONFIG_FLAG_TELNET) ? "ON" : "OFF");
907 
908 	return ses;
909 }
910 
911 
DO_CONFIG(config_tintinchar)912 DO_CONFIG(config_tintinchar)
913 {
914 	if (*arg2)
915 	{
916 		if (!ispunct((int) arg2[0]))
917 		{
918 			show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG TINTIN CHAR: INVALID CHARACTER {%c}", arg2[0]);
919 
920 			return NULL;
921 		}
922 
923 		gtd->tintin_char = arg2[0];
924 	}
925 	sprintf(arg2, "%c", gtd->tintin_char);
926 
927 	return ses;
928 }
929 
DO_CONFIG(config_verbatim)930 DO_CONFIG(config_verbatim)
931 {
932 	if (*arg2)
933 	{
934 		if (is_abbrev(arg2, "ON"))
935 		{
936 			SET_BIT(ses->config_flags, CONFIG_FLAG_VERBATIM);
937 		}
938 		else if (is_abbrev(arg2, "OFF"))
939 		{
940 			DEL_BIT(ses->config_flags, CONFIG_FLAG_VERBATIM);
941 		}
942 		else
943 		{
944 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
945 
946 			return NULL;
947 		}
948 	}
949 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_VERBATIM) ? "ON" : "OFF");
950 
951 	return ses;
952 }
953 
DO_CONFIG(config_verbatimchar)954 DO_CONFIG(config_verbatimchar)
955 {
956 	if (*arg2)
957 	{
958 		if (!ispunct((int) arg2[0]))
959 		{
960 			show_error(ses, LIST_CONFIG, "#ERROR: #CONFIG VERBATIM CHAR: INVALID CHARACTER {%c}", arg2[0]);
961 
962 			return NULL;
963 		}
964 		gtd->verbatim_char = arg2[0];
965 	}
966 	sprintf(arg2, "%c", gtd->verbatim_char);
967 
968 	return ses;
969 }
970 
971 
DO_CONFIG(config_verbose)972 DO_CONFIG(config_verbose)
973 {
974 	if (*arg2)
975 	{
976 		if (is_abbrev(arg2, "ON"))
977 		{
978 			SET_BIT(ses->config_flags, CONFIG_FLAG_VERBOSE);
979 		}
980 		else if (is_abbrev(arg2, "OFF"))
981 		{
982 			DEL_BIT(ses->config_flags, CONFIG_FLAG_VERBOSE);
983 		}
984 		else
985 		{
986 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
987 
988 			return NULL;
989 		}
990 	}
991 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_VERBOSE) ? "ON" : "OFF");
992 
993 	return ses;
994 }
995 
DO_CONFIG(config_wordwrap)996 DO_CONFIG(config_wordwrap)
997 {
998 	if (*arg2)
999 	{
1000 		if (is_abbrev(arg2, "ON"))
1001 		{
1002 			SET_BIT(ses->config_flags, CONFIG_FLAG_WORDWRAP);
1003 		}
1004 		else if (is_abbrev(arg2, "OFF"))
1005 		{
1006 			DEL_BIT(ses->config_flags, CONFIG_FLAG_WORDWRAP);
1007 		}
1008 		else
1009 		{
1010 			show_error(ses, LIST_CONFIG, "#SYNTAX: #CONFIG {%s} <ON|OFF>", config_table[index].name);
1011 
1012 			return NULL;
1013 		}
1014 	}
1015 	strcpy(arg2, HAS_BIT(ses->config_flags, CONFIG_FLAG_WORDWRAP) ? "ON" : "OFF");
1016 
1017 	return ses;
1018 }
1019