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