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 702