Sync up with trunk r61578.
[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 #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
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
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
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
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)
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
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
379 bool find_alias(const char *alias_name) {
380 return false;
381 }
382
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
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
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
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
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
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
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
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
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
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
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
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