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