1 ///////////////////////////////////////////////////////////////////////////////
2 //Telnet Win32 : an ANSI telnet client.
3 //Copyright (C) 1998-2000 Paul Brannan
4 //Copyright (C) 1998 I.Ioannou
5 //Copyright (C) 1997 Brad Johnson
6 //
7 //This program is free software; you can redistribute it and/or
8 //modify it under the terms of the GNU General Public License
9 //as published by the Free Software Foundation; either version 2
10 //of the License, or (at your option) any later version.
11 //
12 //This program is distributed in the hope that it will be useful,
13 //but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //GNU General Public License for more details.
16 //
17 //You should have received a copy of the GNU General Public License
18 //along with this program; if not, write to the Free Software
19 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 //I.Ioannou
22 //roryt@hol.gr
23 //
24 ///////////////////////////////////////////////////////////////////////////
25 
26 // tnconfig.cpp
27 // Written by Paul Brannan <pbranna@clemson.edu>
28 // Last modified August 30, 1998
29 //
30 // This is a class designed for use with Brad Johnson's Console Telnet
31 // see the file tnconfig.h for more information
32 
33 #include "precomp.h"
34 
35 #include <locale.h>
36 #include <io.h>
37 #include <sys/stat.h>
38 
39 // Turn off the "forcing value to bool 'true' or 'false'" warning
40 #ifdef _MSC_VER
41 #pragma warning(disable: 4800)
42 #endif
43 
44 // This is the ini variable that is used for everybody
45 TConfig ini;
46 
TConfig()47 TConfig::TConfig() {
48 	// set all default values
49 	startdir[0] = '\0';
50 	keyfile[0] = '\0';
51 	inifile[0] = '\0';
52 	dumpfile[0] = '\0';
53 	term[0] = '\0';
54 	default_config[0] = '\0';
55 	strcpy(printer_name, "LPT1");
56 
57 	input_redir = 0;
58 	output_redir = 0;
59 	strip_redir = FALSE;
60 
61 	dstrbksp = FALSE;
62 	eightbit_ansi = FALSE;
63 	vt100_mode = FALSE;
64 	disable_break = FALSE;
65 	speaker_beep = TRUE;
66 	do_beep = TRUE;
67 	preserve_colors = FALSE;
68 	wrapline = TRUE;
69 	lock_linewrap = FALSE;
70 	fast_write = TRUE;
71 	enable_mouse = TRUE;
72 	alt_erase = FALSE;
73 	wide_enable = FALSE;
74 	keyboard_paste = FALSE;
75 	set_title = TRUE;
76 
77 	blink_bg = -1;
78 	blink_fg = 2;
79 	underline_bg = -1;
80 	underline_fg = 3;
81 	ulblink_bg = -1;
82 	ulblink_fg = 1;
83 	normal_bg = -1;
84 	normal_fg = -1;
85 	scroll_bg = 0;
86 	scroll_fg = 7;
87 	status_bg = 1;
88 	status_fg = 15;
89 
90 	buffer_size = 2048;
91 
92 	term_width = -1;
93 	term_height = -1;
94 	window_width = -1;
95 	window_height = -1;
96 
97 	strcpy(escape_key, "]");
98 	strcpy(scrollback_key, "[");
99 	strcpy(dial_key, "\\");
100 	strcpy(default_config, "ANSI");
101 	strcpy(term, "ansi");
102 
103 	strcpy(scroll_mode, "DUMP");
104 	scroll_size=32000;
105 	scroll_enable=TRUE;
106 
107 	host[0] = '\0';
108 	port = "23";
109 
110 	init_varlist();
111 
112 	aliases = NULL;
113 }
114 
~TConfig()115 TConfig::~TConfig() {
116 	if(aliases) {
117 		for(int j = 0; j < alias_total; j++) delete[] aliases[j];
118 		delete[] aliases;
119 	}
120 }
121 
122 enum ini_data_type {
123 	INI_STRING,
124 	INI_INT,
125 	INI_BOOL
126 };
127 
128 enum {
129 	INIFILE,
130 	KEYFILE,
131 	DUMPFILE,
132 	DEFAULT_CONFIG,
133 	TERM,
134 	INPUT_REDIR,
135 	OUTPUT_REDIR,
136 	STRIP_REDIR,
137 	DSTRBKSP,
138 	EIGHTBIT_ANSI,
139 	VT100_MODE,
140 	DISABLE_BREAK,
141 	SPEAKER_BEEP,
142 	DO_BEEP,
143 	PRESERVE_COLORS,
144 	WRAP_LINE,
145 	LOCK_LINEWRAP,
146 	FAST_WRITE,
147 	TERM_WIDTH,
148 	TERM_HEIGHT,
149 	WINDOW_WIDTH,
150 	WINDOW_HEIGHT,
151 	WIDE_ENABLE,
152 	CTRLBREAK_AS_CTRLC,
153 	BUFFER_SIZE,
154 	SET_TITLE,
155 	BLINK_BG,
156 	BLINK_FG,
157 	UNDERLINE_BG,
158 	UNDERLINE_FG,
159 	ULBLINK_BG,
160 	ULBLINK_FG,
161 	NORMAL_BG,
162 	NORMAL_FG,
163 	SCROLL_BG,
164 	SCROLL_FG,
165 	STATUS_BG,
166 	STATUS_FG,
167 	PRINTER_NAME,
168 	ENABLE_MOUSE,
169 	ESCAPE_KEY,
170 	SCROLLBACK_KEY,
171 	DIAL_KEY,
172 	ALT_ERASE,
173 	KEYBOARD_PASTE,
174 	SCROLL_MODE,
175 	SCROLL_SIZE,
176 	SCROLL_ENABLE,
177 	SCRIPTNAME,
178 	SCRIPT_ENABLE,
179 	NETPIPE,
180 	IOPIPE,
181 
182 	MAX_INI_VARS			// must be last
183 };
184 
185 struct ini_variable {
186 	const char *name;				// variable name
187 	const char *section;			// name of ini file section the variable is in
188 	enum ini_data_type data_type;		// type of data
189 	void *ini_data;			// pointer to data
190 	int  max_size;			// max size if string
191 };
192 
193 // Note: default values are set in the constructor, TConfig()
194 ini_variable ini_varlist[MAX_INI_VARS];
195 
196 enum {
197 	KEYBOARD,
198 	TERMINAL,
199 	COLORS,
200 	MOUSE,
201 	PRINTER,
202 	SCROLLBACK,
203 	SCRIPTING,
204 	PIPES,
205 
206 	MAX_INI_GROUPS						// Must be last
207 };
208 
209 char *ini_groups[MAX_INI_GROUPS];
210 
init_varlist()211 void TConfig::init_varlist() {
212 	static const ini_variable static_ini_varlist[MAX_INI_VARS] = {
213 		{"Inifile",		NULL,			INI_STRING,		&inifile,	sizeof(inifile)},
214 		{"Keyfile",		"Keyboard",		INI_STRING,		&keyfile,	sizeof(keyfile)},
215 		{"Dumpfile",	"Terminal",		INI_STRING,		&dumpfile,	sizeof(dumpfile)},
216 		{"Default_Config","Keyboard",   INI_STRING,		&default_config, sizeof(default_config)},
217 		{"Term",		"Terminal",		INI_STRING,		&term,		sizeof(term)},
218 		{"Input_Redir",	"Terminal",		INI_INT,		&input_redir, 0},
219 		{"Output_Redir","Terminal",		INI_INT,		&output_redir, 0},
220 		{"Strip_Redir",	"Terminal",		INI_BOOL,		&strip_redir, 0},
221 		{"Destructive_Backspace","Terminal",INI_BOOL,	&dstrbksp, 0},
222 		{"EightBit_Ansi","Terminal",	INI_BOOL,		&eightbit_ansi, 0},
223 		{"VT100_Mode",	"Terminal",		INI_BOOL,		&vt100_mode, 0},
224 		{"Disable_Break","Terminal",	INI_BOOL,		&disable_break, 0},
225 		{"Speaker_Beep","Terminal",		INI_BOOL,		&speaker_beep, 0},
226 		{"Beep",		"Terminal",		INI_BOOL,		&do_beep, 0},
227 		{"Preserve_Colors","Terminal",	INI_BOOL,		&preserve_colors, 0},
228 		{"Wrap_Line",	"Terminal",		INI_BOOL,		&wrapline, 0},
229 		{"Lock_linewrap","Terminal",	INI_BOOL,		&lock_linewrap, 0},
230 		{"Fast_Write",	"Terminal",		INI_BOOL,		&fast_write, 0},
231 		{"Term_Width",	"Terminal",		INI_INT,		&term_width, 0},
232 		{"Term_Height",	"Terminal",		INI_INT,		&term_height, 0},
233 		{"Window_Width","Terminal",		INI_INT,		&window_width, 0},
234 		{"Window_Height","Terminal",	INI_INT,		&window_height, 0},
235 		{"Wide_Enable",	"Terminal",		INI_BOOL,		&wide_enable, 0},
236 		{"Ctrlbreak_as_Ctrlc","Keyboard", INI_BOOL,		&ctrlbreak_as_ctrlc, 0},
237 		{"Buffer_Size",	"Terminal",		INI_INT,		&buffer_size, 0},
238 		{"Set_Title",	"Terminal",		INI_BOOL,		&set_title, 0},
239 		{"Blink_bg",	"Colors",		INI_INT,		&blink_bg, 0},
240 		{"Blink_fg",	"Colors",		INI_INT,		&blink_fg, 0},
241 		{"Underline_bg","Colors",		INI_INT,		&underline_bg, 0},
242 		{"Underline_fg","Colors",		INI_INT,		&underline_fg, 0},
243 		{"UlBlink_bg",	"Colors",		INI_INT,		&ulblink_bg, 0},
244 		{"UlBlink_fg",	"Colors",		INI_INT,		&ulblink_fg, 0},
245 		{"Normal_bg",	"Colors",		INI_INT,		&normal_bg, 0},
246 		{"Normal_fg",	"Colors",		INI_INT,		&normal_fg, 0},
247 		{"Scroll_bg",	"Colors",		INI_INT,		&scroll_bg, 0},
248 		{"Scroll_fg",	"Colors",		INI_INT,		&scroll_fg, 0},
249 		{"Status_bg",	"Colors",		INI_INT,		&status_bg, 0},
250 		{"Status_fg",	"Colors",		INI_INT,		&status_fg,	0},
251 		{"Enable_Mouse","Mouse",		INI_BOOL,		&enable_mouse, 0},
252 		{"Printer_Name","Printer",		INI_STRING,		&printer_name, sizeof(printer_name)},
253 		{"Escape_Key",	"Keyboard",		INI_STRING,		&escape_key, 1},
254 		{"Scrollback_Key","Keyboard",	INI_STRING,		&scrollback_key, 1},
255 		{"Dial_Key",	"Keyboard",		INI_STRING,		&dial_key, 1},
256 		{"Alt_Erase",	"Keyboard",		INI_BOOL,		&alt_erase, 0},
257 		{"Keyboard_Paste","Keyboard",	INI_BOOL,		&keyboard_paste, 0},
258 		{"Scroll_Mode",	"Scrollback",	INI_STRING,		&scroll_mode, sizeof(scroll_mode)},
259 		{"Scroll_Size",	"Scrollback",	INI_INT,		&scroll_size, 0},
260 		{"Scroll_Enable","Scrollback",	INI_BOOL,		&scroll_enable, 0},
261 		{"Scriptname",	"Scripting",	INI_STRING,		&scriptname, sizeof(scriptname)},
262 		{"Script_enable","Scripting",	INI_BOOL,		&script_enable, 0},
263 		{"Netpipe",		"Pipes",		INI_STRING,		&netpipe, sizeof(netpipe)},
264 		{"Iopipe",		"Pipes",		INI_STRING,		&iopipe, sizeof(iopipe)}
265 	};
266 
267 	static const char *static_ini_groups[MAX_INI_GROUPS] = {
268 		"Keyboard",
269 		"Terminal",
270 		"Colors",
271 		"Mouse",
272 		"Printer",
273 		"Scrollback",
274 		"Scripting",
275 		"Pipes"
276 	};
277 
278 	memcpy(ini_varlist, static_ini_varlist, sizeof(ini_varlist));
279 	memcpy(ini_groups, static_ini_groups, sizeof(ini_groups));
280 }
281 
init(char * dirname,char * execname)282 void TConfig::init(char *dirname, char *execname) {
283 	// Copy temporary dirname to permanent startdir
284 	strncpy(startdir, dirname, sizeof(startdir));
285 	startdir[sizeof(startdir) - 1] = 0;
286 
287 	// Copy temp execname to permanent exename (Thomas Briggs 12/7/98)
288 	strncpy(exename, execname, sizeof(exename));
289 	exename[sizeof(exename) - 1] = 0;
290 
291 	// Initialize INI file
292 	inifile_init();
293 
294 	// Initialize redir
295 	// Note that this must be done early, so error messages will be printed
296 	// properly
297 	redir_init();
298 
299 	// Initialize aliases (Paul Brannan 1/1/99)
300 	init_aliases();
301 
302 	// Make sure the file that we're trying to work with exists
303 	int iResult = access(inifile, 04);
304 
305 	// Thomas Briggs 9/14/98
306 	if( iResult == 0 )
307 		// Tell the user what file we are reading
308 		// We cannot print any messages before initializing telnet_redir
309 		printm(0, FALSE, MSG_CONFIG, inifile);
310 	else
311 		// Tell the user that the file doesn't exist, but later read the
312 		// file anyway simply to populate the defaults
313 		printm(0, FALSE, MSG_NOINI, inifile);
314 
315 	init_vars();								// Initialize misc. vars
316 	keyfile_init();								// Initialize keyfile
317 }
318 
319 // Alias support (Paul Brannan 1/1/99)
init_aliases()320 void TConfig::init_aliases() {
321 	char *buffer;
322 	alias_total = 0;
323 
324 	// Find the correct buffer size
325 	// FIX ME!! some implementations of Mingw32 don't have a
326 	// GetPrivateProfileSecionNames function.  What do we do about this?
327 #ifndef __MINGW32__
328 	{
329 		int size=1024, Result = 0;
330 		for(;;) {
331 			buffer = new char[size];
332 			Result = GetPrivateProfileSectionNames(buffer, size, inifile);
333 			if(Result < size - 2) break;
334 			size *= 2;
335 			delete[] buffer;
336 		}
337 	}
338 #else
339 	return;
340 #endif
341 
342 	// Find the maximum number of aliases
343 	int max = 0;
344 	char *tmp;
345 	for(tmp = buffer; *tmp != 0; tmp += strlen(tmp) + 1)
346 		max++;
347 
348 	aliases = new char*[max];
349 
350 	// Load the aliases into an array
351 	for(tmp = buffer; *tmp != 0; tmp += strlen(tmp) + 1) {
352 		int flag = 0;
353 		for(int j = 0; j < MAX_INI_GROUPS; j++) {
354 			if(!stricmp(ini_groups[j], tmp)) flag = 1;
355 		}
356 		if(!flag) {
357 			aliases[alias_total] = new char[strlen(tmp)+1];
358 			strcpy(aliases[alias_total], tmp);
359 			alias_total++;
360 		}
361 	}
362 
363 	delete[] buffer;
364 }
365 
print_aliases()366 void TConfig::print_aliases() {
367 	for(int j = 0; j < alias_total; j++) {
368 		char alias_name[20];
369 		set_string(alias_name, aliases[j], sizeof(alias_name));
370 		for(unsigned int i = strlen(alias_name); i < sizeof(alias_name) - 1; i++)
371 			alias_name[i] = ' ';
372 		alias_name[sizeof(alias_name) - 1] = 0;
373 		printit(alias_name);
374 		if((j % 4) == 3) printit("\n");
375 	}
376 	printit("\n");
377 }
378 
find_alias(const char * alias_name)379 bool find_alias(const char *alias_name) {
380 	return false;
381 }
382 
print_vars()383 void TConfig::print_vars() {
384 	int j;
385 	for(j = 0; j < MAX_INI_VARS; j++) {
386 		if(print_value(ini_varlist[j].name) > 40) printit("\n");
387 		else if(j % 2) printit("\n");
388 		else printit("\t");
389 	}
390 	if(j % 2) printit("\n");
391 }
392 
393 // Paul Brannan 9/3/98
print_vars(char * s)394 void TConfig::print_vars(char *s) {
395 	if(!strnicmp(s, "all", 3)) {					// Print out all vars
396 		print_vars();
397 		return;
398 	}
399 
400 	// See if the group exists
401 	int j;
402 	for(j = 0; j < MAX_INI_GROUPS; j++)
403 		if(!stricmp(ini_groups[j], s)) break;
404 	// If not, print out the value of the variable by that name
405 	if(j == MAX_INI_GROUPS) {
406 		print_value(s);
407 		printit("\n");
408 		return;
409 	}
410 
411 	// Print out the vars in the given group
412 	int count = 0;
413 	for(j = 0; j < MAX_INI_VARS; j++) {
414 		if(ini_varlist[j].section == NULL) continue;
415 		if(!stricmp(ini_varlist[j].section, s)) {
416 			if(print_value(ini_varlist[j].name) > 40) printit("\n");
417 			else if(count % 2) printit("\n");
418 			else printit("\t");
419 			count++;
420 		}
421 	}
422 	if(count % 2) printit("\n");
423 }
424 
425 // Paul Brannan 9/3/98
print_groups()426 void TConfig::print_groups() {
427 	for(int j = 0; j < MAX_INI_GROUPS; j++) {
428 		char group_name[20];
429 		set_string(group_name, ini_groups[j], sizeof(group_name));
430 		for(unsigned int i = strlen(group_name); i < sizeof(group_name) - 1; i++)
431 			group_name[i] = ' ';
432 		group_name[sizeof(group_name) - 1] = 0;
433 		printit(group_name);
434 		if((j % 4) == 3) printit("\n");
435 	}
436 	printit("\n");
437 }
438 
439 // Ioannou : The index in the while causes segfaults if there is no match
440 // changes to for(), and strcmp to stricmp (prompt gives rong names)
441 
set_value(const char * var,const char * value)442 bool TConfig::set_value(const char *var, const char *value) {
443    //int j = 0;
444    //while(strcmp(var, ini_varlist[j].name) && j < MAX_INI_VARS) j++;
445    for (int j = 0; j < MAX_INI_VARS; j++)
446    {
447       if (stricmp(var, ini_varlist[j].name) == 0)
448       {
449          switch(ini_varlist[j].data_type) {
450             case INI_STRING:
451                set_string((char *)ini_varlist[j].ini_data, value,
452                   ini_varlist[j].max_size);
453                break;
454             case INI_INT:
455                *(int *)ini_varlist[j].ini_data = atoi(value);
456                break;
457             case INI_BOOL:
458                set_bool((bool *)ini_varlist[j].ini_data, value);
459                break;
460          }
461          // j = MAX_INI_VARS;
462 		 return TRUE;
463       }
464    }
465    return FALSE;
466 }
467 
print_value(const char * var)468 int TConfig::print_value(const char *var) {
469 	//int j = 0;
470 	//while(strcmp(var, ini_varlist[j].name) && j < MAX_INI_VARS) j++;
471 	int Result = 0;
472 	for (int j = 0; j < MAX_INI_VARS; j++)
473 	{
474 		if (stricmp(var, ini_varlist[j].name) == 0)
475 		{
476 			char var_name[25];
477 			set_string(var_name, var, sizeof(var_name));
478 			for(unsigned int i = strlen(var_name); i < sizeof(var_name) - 1; i++)
479 				var_name[i] = ' ';
480 			var_name[sizeof(var_name) - 1] = 0;
481 			Result = sizeof(var_name);
482 
483 			printit(var_name);
484 			printit("\t");
485 			Result = Result / 8 + 8;
486 
487 			switch(ini_varlist[j].data_type) {
488             case INI_STRING:
489 				printit((char *)ini_varlist[j].ini_data);
490 				Result += strlen((char *)ini_varlist[j].ini_data);
491 				break;
492             case INI_INT:
493 				char buffer[20]; // this may not be safe
494 				// Ioannou : Paul this was _itoa, but Borland needs itoa !!
495 				itoa(*(int *)ini_varlist[j].ini_data, buffer, 10);
496 				printit(buffer);
497 				Result += strlen(buffer);
498 				break;
499             case INI_BOOL:
500 				if(*(bool *)ini_varlist[j].ini_data == true) {
501 					printit("on");
502 					Result += 2;
503 				} else {
504 					printit("off");
505 					Result += 3;
506 				}
507 			}
508 			// printit("\n");
509 			j = MAX_INI_VARS;
510 		}
511 	}
512 	return Result;
513 }
514 
init_vars()515 void TConfig::init_vars() {
516 	char buffer[4096];
517 	for(int j = 0; j < MAX_INI_VARS; j++) {
518 		if(ini_varlist[j].section != NULL) {
519 			GetPrivateProfileString(ini_varlist[j].section, ini_varlist[j].name, "",
520 				buffer, sizeof(buffer), inifile);
521 			if(*buffer != 0) set_value(ini_varlist[j].name, buffer);
522 		}
523 	}
524 }
525 
inifile_init()526 void TConfig::inifile_init() {
527 	// B. K. Oxley 9/16/98
528 	char* env_telnet_ini = getenv (ENV_TELNET_INI);
529 	if (env_telnet_ini && *env_telnet_ini) {
530 		strncpy (inifile, env_telnet_ini, sizeof(inifile));
531 		return;
532 	}
533 
534 	strcpy(inifile, startdir);
535 	if (sizeof(inifile) >= strlen(inifile)+strlen("telnet.ini")) {
536 		strcat(inifile,"telnet.ini"); // add the default filename to the path
537 	} else {
538 		// if there is not enough room set the path to nothing
539 		strcpy(inifile,"");
540 	}
541 }
542 
keyfile_init()543 void TConfig::keyfile_init() {
544 	// check to see if there is a key config file environment variable.
545 	char *k;
546 	if ((k = getenv(ENV_TELNET_CFG)) == NULL){
547 		// if there is no environment variable
548 		GetPrivateProfileString("Keyboard", "Keyfile", "", keyfile,
549 			sizeof(keyfile), inifile);
550 		if(keyfile == 0 || *keyfile == 0) {
551 			// and there is no profile string
552 			strcpy(keyfile, startdir);
553 			if (sizeof(keyfile) >= strlen(keyfile)+strlen("telnet.cfg")) {
554 				struct stat buf;
555 
556 				strcat(keyfile,"telnet.cfg"); // add the default filename to the path
557 				if(stat(keyfile, &buf) != 0) {
558 					char *s = keyfile + strlen(keyfile) - strlen("telnet.cfg");
559 					strcpy(s, "keys.cfg");
560 				}
561 			} else {
562 				// if there is not enough room set the path to nothing
563 				strcpy(keyfile,"");
564 			}
565 
566 		// Vassili Bourdo (vassili_bourdo@softhome.net)
567 		} else {
568 			// check that keyfile really exists
569 			if( access(keyfile,04) == -1 ) {
570 				//it does not...
571 				char pathbuf[MAX_PATH], *fn;
572 				//substitute keyfile path with startdir path
573 				if((fn = strrchr(keyfile,'\\'))) strcpy(keyfile,fn);
574 					strcat(strcpy(pathbuf,startdir),keyfile);
575 				//check that startdir\keyfile does exist
576 				if( access(pathbuf,04) == -1 ) {
577 					//it does not...
578 					//so, look for it in all paths
579 					_searchenv(keyfile, "PATH", pathbuf);
580 					if( *pathbuf == 0 ) //no luck - revert it to INI file value
581 						GetPrivateProfileString("Keyboard", "Keyfile", "",
582 							keyfile, sizeof(keyfile), inifile);
583 				} else {
584 					strcpy(keyfile, pathbuf);
585 				}
586 			}
587 		}
588 		////
589 
590 	} else {
591 		// set the keyfile to the value of the environment variable
592 		strncpy(keyfile, k, sizeof(keyfile));
593 	}
594 }
595 
redir_init()596 void TConfig::redir_init() {
597 	// check to see if the environment variable 'TELNET_REDIR' is not 0;
598 	char* p = getenv(ENV_TELNET_REDIR);
599 	if (p) {
600 		input_redir = output_redir = atoi(p);
601 		if((p = getenv(ENV_INPUT_REDIR))) input_redir = atoi(p);
602 		if((p = getenv(ENV_OUTPUT_REDIR))) output_redir = atoi(p);
603 	} else {
604 		input_redir = output_redir = GetPrivateProfileInt("Terminal",
605 			"Telnet_Redir", 0, inifile);
606 		input_redir = GetPrivateProfileInt("Terminal",
607 			"Input_Redir", input_redir, inifile);
608 		output_redir = GetPrivateProfileInt("Terminal",
609 			"Output_Redir", output_redir, inifile);
610 	}
611 	if ((input_redir > 1) || (output_redir > 1))
612 		setlocale(LC_CTYPE,"");
613 	// tell isprint() to not ignore local characters, if the environment
614 	// variable "LANG" has a valid value (e.g. LANG=de for german characters)
615 	// and the file LOCALE.BLL is installed somewhere along the PATH.
616 }
617 
618 // Modified not to use getopt() by Paul Brannan 12/17/98
Process_Params(int argc,char * argv[])619 bool TConfig::Process_Params(int argc, char *argv[]) {
620 	int optind = 1;
621 	char *optarg = argv[optind];
622 	char c;
623 
624 	while(optind < argc) {
625 		if(argv[optind][0] != '-') break;
626 
627 		// getopt
628 		c = argv[optind][1];
629 		if(argv[optind][2] == 0)
630 			optarg = argv[++optind];
631 		else
632 			optarg = &argv[optind][2];
633 		optind++;
634 
635 		switch(c) {
636 			case 'd':
637 				set_string(dumpfile, optarg, sizeof(dumpfile));
638 				printm(0, FALSE, MSG_DUMPFILE, dumpfile);
639 				break;
640 			// added support for setting options on the command-line
641 			// (Paul Brannan 7/31/98)
642 			case '-':
643 				{
644 					int j;
645 					for(j = 0; optarg[j] != ' ' && optarg[j] != '=' && optarg[j] != 0; j++);
646 					if(optarg == 0) {
647 						printm(0, FALSE, MSG_USAGE);		// print a usage message
648 						printm(0, FALSE, MSG_USAGE_1);
649 						return FALSE;
650 					}
651 					optarg[j] = 0;
652 					if(!set_value(optarg, &optarg[j+1]))
653 						printm(0, FALSE, MSG_BADVAL, optarg);
654 				}
655 				break;
656 			default:
657 				printm(0, FALSE, MSG_USAGE);		// print a usage message
658 				printm(0, FALSE, MSG_USAGE_1);
659 				return FALSE;
660 		}
661 	}
662 	if(optind < argc)
663 		set_string(host, argv[optind++], sizeof(host)-1);
664 	if(!strnicmp(host, "telnet://", 9)) {
665 		// we have a URL to parse
666 		char *s, *t;
667 
668 		for(s = host+9, t = host; *s != 0; *(t++) = *(s++));
669 		*t = 0;
670 		for(s = host; *s != ':' && *s != 0; s++);
671 		if(*s != 0) {
672 			*(s++) = 0;
673 			port = s;
674 		}
675 	}
676 	if(optind < argc)
677 		port = argv[optind++];
678 
679 	return TRUE;
680 }
681 
set_string(char * dest,const char * src,const int length)682 void TConfig::set_string(char *dest, const char *src, const int length) {
683    int l = length;
684    strncpy(dest, src, l);
685  //  dest[length-1] = '\0';
686  // Ioannou : this messes strings - is this really needed ?
687  // The target string, dest, might not be null-terminated
688  // if the length of src is length or more.
689  // it should be dest[length] = '\0' for strings with length 1
690  // (Escape_string etc), but doesn't work with others (like host).
691  // dest is long enough to avoid this in all the tested cases
692 }
693 
694 // Ioannou : ignore case for true or on
695 
set_bool(bool * boolval,const char * str)696 void TConfig::set_bool(bool *boolval, const char *str) {
697    if(!stricmp(str, "true")) *boolval = true;
698    else if(!stricmp(str, "on")) *boolval = true;
699 	else *boolval = (bool)atoi(str);
700 }
701 
702