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