tnmain.cpp
上传用户:tigerk9
上传日期:2020-03-10
资源大小:237k
文件大小:19k
源码类别:

Telnet客户端

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //Telnet Win32 : an ANSI telnet client.
  3. //Copyright (C) 1998  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. //
  27. // Module: tnmain.cpp
  28. //
  29. // Contents: telnet main program
  30. //
  31. // Product: telnet
  32. //
  33. // Revisions: August 11, 1998 Thomas Briggs <tbriggs@qmetric.com>
  34. //            May 14, 1998 Paul Brannan <pbranna@clemson.edu>
  35. //            5.April.1997 jbj@nounname.com
  36. //            5.Dec.1996 jbj@nounname.com
  37. //            Version 2.0
  38. //
  39. //            02.Apr.1995 igor.milavec@uni-lj.si
  40. //   Original code
  41. //
  42. ///////////////////////////////////////////////////////////////////////////////
  43. #include <string.h>
  44. #include <locale.h>
  45. #include "tnmain.h"
  46. #include "tnmisc.h"
  47. int telCommandLine (Telnet &MyConnection);
  48. void waitforkey() {
  49. HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
  50. INPUT_RECORD InputRecord;
  51. DWORD dwInput;
  52. BOOL done = FALSE;
  53. while (!done){
  54. WaitForSingleObject( hConsole, INFINITE );
  55. if (!ReadConsoleInput(hConsole, &InputRecord, 1, &dwInput)){
  56. done = TRUE;
  57. continue;
  58. }
  59. if (InputRecord.EventType == KEY_EVENT &&
  60. InputRecord.Event.KeyEvent.bKeyDown )
  61. done = TRUE;
  62. }
  63. }
  64. //char * cfgets ( char * buf, unsigned int length, char pszHistory[][80], int iHistLength){
  65. struct cmdHistory * cfgets (char *buf, unsigned int length, struct cmdHistory *cmdhist) {
  66. HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
  67. unsigned int current=0, cursor =0, iEraseLength=0, i;
  68. char chr;
  69. char temp[2];
  70. char temp1[80];
  71. INPUT_RECORD InputRecord;
  72. BOOL done = FALSE;
  73. temp[1] = 0;
  74. buf[0] = '';
  75. if(!ini.get_input_redir()) {
  76. while (!done) {
  77. DWORD dwInput;
  78. int MustRefresh = 0;
  79. WaitForSingleObject( hConsole, INFINITE );
  80. if (!ReadConsoleInput(hConsole, &InputRecord, 1, &dwInput)){
  81. done = TRUE;
  82. continue;
  83. }
  84. MustRefresh = 0;
  85. if (InputRecord.EventType == KEY_EVENT &&
  86. InputRecord.Event.KeyEvent.bKeyDown ) {
  87. if(InputRecord.Event.KeyEvent.dwControlKeyState &
  88. (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
  89. switch(InputRecord.Event.KeyEvent.wVirtualKeyCode) {
  90. case 'D': // Thomas Briggs 8/11/98
  91. buf[0] = '4';
  92. buf[1] = '';
  93. current = 1;
  94. done = true;
  95. continue;
  96. case 'U': // Paul Brannan 8/11/98
  97. buf[0] = '';
  98. current = 0;
  99. cursor = 0;
  100. MustRefresh = 1;
  101. break;
  102. }
  103. }
  104. switch (InputRecord.Event.KeyEvent.wVirtualKeyCode) {
  105. case VK_UP:
  106. // crn@ozemail.com.au
  107. if (cmdhist != NULL) {
  108. if (!strcmp(buf, ""))
  109. strncpy(buf, cmdhist->cmd, 79);
  110. else if (cmdhist->prev != NULL) {
  111. cmdhist = cmdhist->prev;
  112. strncpy(buf, cmdhist->cmd, 79);
  113. }
  114. current = strlen(buf);
  115. }
  116. ///
  117. MustRefresh = 1;
  118. break;
  119. case VK_DOWN:
  120. // crn@ozemail.com.au
  121. if (cmdhist != NULL) {
  122. if (cmdhist->next != NULL) {
  123. cmdhist = cmdhist->next;
  124. strncpy(buf, cmdhist->cmd, 79);
  125. } else {
  126. strncpy(buf, "", 79);
  127. }
  128. current = strlen(buf);
  129. }
  130. ///
  131. MustRefresh = 1;
  132. break;
  133. case VK_RIGHT: //crn@ozemail.com.au (added ctrl+arrow)
  134. if (cursor < current)
  135. if (InputRecord.Event.KeyEvent.dwControlKeyState &
  136. (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
  137. unsigned int i,j;
  138. for (j = cursor; j <= current; j++)
  139. if (buf[j+1] == ' ' || (j+1)==current)
  140. break;
  141. for (i = ++j; i <= current; i++)
  142. if (buf[i] != ' ' || i == current) {
  143. cursor = i == current ? --i : i;
  144. break;
  145. }
  146. } else
  147. cursor++;
  148. MustRefresh = 1;
  149. break;
  150. case VK_LEFT: //crn@ozemail.com.au (added ctrl+arrow)
  151. if (cursor > 0)
  152. if(InputRecord.Event.KeyEvent.dwControlKeyState &
  153. (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
  154. int i,j;
  155. for (j = cursor; j >= 0; j--)
  156. if (buf[j-1] != ' ')
  157. break;
  158. for (i = --j; i >= 0; i--)
  159. if (buf[i] == ' ' || i == 0) {
  160. cursor = !i ? i : ++i;
  161. break;
  162. }
  163. } else
  164. cursor--;
  165. MustRefresh = 1;
  166. break;
  167. case VK_HOME:
  168. if (cursor>0) cursor = 0;
  169. MustRefresh = 1;
  170. break;
  171. case VK_END:
  172. if (cursor<current) cursor = current;
  173. MustRefresh = 1;
  174. break;
  175. case VK_DELETE:
  176. if (current > 0 && current > cursor) {
  177. strcpy(&buf[cursor],&buf[cursor+1]);
  178. current--;
  179. buf[current] = 0;
  180. printit("r");
  181. for (i = 0; i < current+strlen("telnet>")+1 ;i++)
  182. printit(" ");
  183. }
  184. MustRefresh = 1;
  185. break;
  186. case VK_BACK:
  187. if (cursor > 0 ) {
  188. strcpy(&buf[cursor-1],&buf[cursor]);
  189. current--;
  190. cursor--;
  191. buf[current] = 0;
  192. printit("r");
  193. for (i = 0; i < current+strlen("telnet>")+1 ;i++)
  194. printit(" ");
  195. }
  196. MustRefresh = 1;
  197. break;
  198. default:
  199. chr = InputRecord.Event.KeyEvent.uChar.AsciiChar;
  200. if (chr == 'r') {
  201. done = TRUE;
  202. continue;
  203. }
  204. if (current >= length-1){
  205. done = TRUE;
  206. continue;
  207. }
  208. if ( isprint (chr) ){
  209. strncpy(temp1,&buf[cursor],79);
  210. strncpy(&buf[cursor+1],temp1,79-(cursor+1));
  211. buf[cursor++]=chr;
  212. current++;
  213. buf[current] = 0;
  214. MustRefresh = 1;
  215. }
  216. break;
  217. }
  218. if (MustRefresh == 1)
  219. {
  220. printit("rtelnet");
  221. for (i = 0; i <= iEraseLength ;i++)
  222. printit(" ");
  223. printit("rtelnet>");
  224. printit(buf);
  225. iEraseLength = strlen(buf);
  226. for (i = 0; i < current-cursor; i++)
  227. printit("b");
  228. }
  229. }
  230. }
  231. buf[current] = 0;
  232. if (strcmp(buf, "")) {
  233. if (cmdhist == NULL) {
  234. cmdhist = new struct cmdHistory;
  235. if (cmdhist == NULL) {
  236. printit ("nUnable to allocate memory for history buffer -- use the "flush" command to clear the buffer.n");
  237. return cmdhist;
  238. }
  239. strncpy(cmdhist->cmd, buf, 79);
  240. cmdhist->next = NULL;
  241. cmdhist->prev = NULL;
  242. } else {
  243. while (cmdhist->next != NULL) //  move to the end of the list
  244. cmdhist = cmdhist->next;
  245. cmdhist->next = new struct cmdHistory;
  246. if (cmdhist->next == NULL) {
  247. printit ("nUnable to allocate memory for history buffer -- use the "flush" command to clear the buffer.n");
  248. return cmdhist;
  249. }
  250. cmdhist->next->prev = cmdhist; //  previous is where we are now
  251. cmdhist = cmdhist->next;
  252. strncpy(cmdhist->cmd, buf, 79);
  253. cmdhist->next = NULL;
  254. }
  255. while (cmdhist->next)
  256. cmdhist = cmdhist->next;
  257. }
  258. return cmdhist;
  259. ///
  260. } else {
  261. WaitForSingleObject( hConsole, INFINITE );
  262. DWORD dwInput;
  263. DWORD OldMode;
  264. GetConsoleMode(hConsole, &OldMode);
  265. SetConsoleMode(hConsole,
  266. OldMode &~ (ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT) );
  267. while (ReadFile(hConsole, &chr, 1, &dwInput, NULL)) {
  268. if (chr == 'r') {
  269. temp[0] = chr;
  270. printit(&temp[0]);
  271. break;
  272. }
  273. if (chr == 'b' && current > 0) {
  274. current--;
  275. printit("b b");
  276. }
  277. if (current >= length-1){
  278. break;
  279. }
  280. if ( isprint (chr) ){
  281. temp[0] = chr;
  282. printit(&temp[0]);
  283. buf[current++]=chr;
  284. }
  285. }
  286. buf[current] = 0;
  287. SetConsoleMode(hConsole, OldMode);
  288. return NULL;
  289. }
  290. }
  291. // AVS ** for fix bug in command 'keys load keymapname' without file
  292. // static char keyfile[MAX_PATH*2];
  293. int main(int ArgC, char* ArgV[]) {
  294. CONSOLE_SCREEN_BUFFER_INFO  ConsoleScreenBufferInfo;
  295. GetConsoleScreenBufferInfo(
  296. GetStdHandle(STD_OUTPUT_HANDLE),
  297. &ConsoleScreenBufferInfo
  298. );
  299. char *k;
  300. char startdir[MAX_PATH*2];
  301. char exename[MAX_PATH];
  302. // strncpy(startdir, ArgV[0],MAX_PATH);
  303. // This should be more accurate than using argv[0] (Paul Brannan 9/16/98)
  304. GetModuleFileName(NULL, startdir, sizeof(startdir));
  305. // Get the current console title so it can be set later
  306. // ("Pedro A. Aranda Guti閞rez" <paag@coppi.tid.es>)
  307. TCHAR ConsoleTitle[255];
  308. GetConsoleTitle(ConsoleTitle, sizeof(ConsoleTitle));
  309. k = strrchr(startdir, '\');
  310. if (k == NULL){ // if the  character is not found...
  311. strcpy(exename, startdir);
  312. strcpy(startdir,""); // set the path to nothing
  313. } else {
  314. // end the string after the last '' to get rid of the file name
  315. strcpy(exename, k+1);
  316. k[1] = 0;
  317. }
  318. printm(0, FALSE, MSG_COPYRIGHT);
  319. printm(0, FALSE, MSG_COPYRIGHT_1);
  320. // set up the ini class
  321. ini.init(startdir, exename);
  322. // Process the command line arguments and connect to a host if necessary
  323. if(ini.Process_Params(ArgC, ArgV)) {
  324. const char *szHost = ini.get_host();
  325. const char *strPort = ini.get_port();
  326. if(!*szHost) {
  327. Telnet MyConnection;
  328. while(telCommandLine(MyConnection));
  329. } else {
  330. Telnet MyConnection;
  331. if(MyConnection.Open(szHost, strPort) == TNPROMPT) {
  332. // still connected
  333. printit("n");
  334. telCommandLine(MyConnection);
  335. }
  336. }
  337. }
  338. //// (Paul Brannan 5/14/98)
  339. if(ini.get_term_width() != -1 || ini.get_term_height() != -1) {
  340. SetConsoleScreenBufferSize(
  341. GetStdHandle(STD_OUTPUT_HANDLE), // handle of console screen buffer
  342. ConsoleScreenBufferInfo.dwSize // new size in character rows and cols.
  343. );
  344. SetConsoleWindowInfo(
  345. GetStdHandle(STD_OUTPUT_HANDLE), // handle of console screen buffer
  346. TRUE, // coordinate type flag
  347. &ConsoleScreenBufferInfo.srWindow  // address of new window rectangle
  348. );
  349. }
  350. SetConsoleTextAttribute(
  351. GetStdHandle(STD_OUTPUT_HANDLE), // handle of console screen buffer
  352. ConsoleScreenBufferInfo.wAttributes  // text and background colors
  353. );
  354. // Restore the original console title
  355. // ("Pedro A. Aranda Guti閞rez" <paag@coppi.tid.es>)
  356. SetConsoleTitle(ConsoleTitle);
  357. return 0;
  358. }
  359. // AVS
  360. enum {
  361. BAD_USAGE = -3,
  362. EMPTY_LINE = -2,
  363. INVALID_CMD = -1,
  364. __FIRST_COMMAND = 0,
  365. OPEN = __FIRST_COMMAND,
  366. CLOSE,
  367. KEYS,
  368. QUIT,
  369. HELP,
  370. HELP2, // there is way for synonims
  371. K_LOAD, // subcommand of 'keys'
  372. K_SWITCH, // subcommand of 'keys'
  373. K_DISPLAY, // subcommand of 'keys'
  374. SET, // Paul Brannan 5/30/98
  375. SUSPEND,
  376. FASTQUIT, // Thomas Briggs 8/11/98
  377. CMD_HISTORY, // crn@ozemail.com.au
  378. CLEAR_HISTORY, // crn@ozemail.com.au
  379. ALIASES, // Paul Brannan 1/1/99
  380. __COMMAND_LIST_SIZE // must be last
  381. };
  382. struct command {
  383. char* cmd; // command
  384. int   minLen, // minimal length for match
  385.   minParms, // minimal count of parms
  386.   maxParms; // maximal -/- (negative disables)
  387. int   isSubCmd, // is a subcommand - number of wich command
  388.   haveSubCmd; // have subcommands? 0 or 1
  389. char* usage; // text of usage
  390. };
  391. command cmdList[__COMMAND_LIST_SIZE] = {
  392. {"open",     1, 1,  2, -1, 0, "o[pen] host [port]n"},
  393. {"close",    2, 0,  0, -1, 0, NULL},
  394. {"keys",     2, 1,  3, -1, 1, "ke[ys] l[oad] keymapname [file]n"
  395. "ke[ys] d[isplay]n"
  396. "ke[ys] s[witch] numbern"},
  397. // Ioannou : i change it to q, to be more compatible with unix telnet
  398. {"quit",     1, 0,  0, -1, 0, NULL}, // must type it exactly
  399. {"?",        1, 0,  0, -1, 0, NULL},
  400. {"help",     1, 0,  0, -1, 0, NULL},
  401. {"load",     1, 1,  2, KEYS, 0, NULL},
  402. {"switch",   1, 1,  1, KEYS, 0, NULL},
  403. {"display",  1, 0,  0, KEYS, 0, NULL},
  404. // Paul Brannan 5/30/98
  405. {"set",      3, 0, 2, -1, 0, "set will display available groups.n"
  406. "set groupname will display all variables/values in a group.n"
  407. "set [variable [value]] will set variable to value.n"},
  408. // Thomas Briggs 8/11/98
  409. {"z", 1, 0, 0, -1, 0, "suspend telnetn"},
  410. {"4", 1, 0, 0, -1, 0, NULL},
  411. // crn@ozemail.com.au
  412. {"history", 2, 0, 0, -1, 0, "show command history"},
  413. {"flush", 2, 0, 0, -1, 0, "flush history buffer"},
  414. // Paul Brannan 1/1/99
  415. {"aliases", 5, 0, 0, -1, 0, NULL}
  416. };
  417. // a maximal count of parms
  418. #define MAX_PARM_COUNT 3
  419. #define MAX_TOKEN_COUNT (MAX_PARM_COUNT+2)
  420. static int cmdMatch(const char* cmd, const char* token, int tokenLen, int minM) {
  421.     if ( tokenLen < minM ) return 0;
  422. // The (unsigned) gets rid of a compiler warning (Paul Brannan 5/25/98)
  423.     if ( (unsigned)tokenLen > strlen(cmd) ) return 0;
  424.     if ( strcmp(cmd,token) == 0 ) return 1;
  425.     int i;
  426.     for ( i = 0; i < minM; i++ ) if ( cmd[i] != token[i] ) return 0;
  427.     for ( i = minM; i < tokenLen; i++ ) if ( cmd[i] != token[i] ) return 0;
  428.     return 1;
  429. };
  430. static void printUsage(int cmd) {
  431. if ( cmdList[cmd].usage != NULL ) {
  432. printit(cmdList[cmd].usage);
  433. return;
  434. };
  435. if ( cmdList[cmd].isSubCmd >= 0 ) {
  436. printUsage(cmdList[cmd].isSubCmd);
  437. return;
  438.    }
  439.    printm(0, FALSE, MSG_BADUSAGE);
  440. };
  441. int tokenizeCommand(char* szCommand, int& argc, char** argv) {
  442.     char* tokens[MAX_TOKEN_COUNT];
  443.     char* p;
  444.     int   args = 0;
  445. if(!szCommand || !*szCommand) return EMPTY_LINE;
  446. // Removed strtok to handle tokens with spaces; this is handled with
  447. // quotes.  (Paul Brannan 3/18/99)
  448. char *token_start = szCommand;
  449. for(p = szCommand;; p++) {
  450. if(*p == '"') {
  451. char *tmp = p;
  452. for(p++; *p != '"' && *p != 0; p++); // Find the next quote
  453. if(*p != 0) strcpy(p, p + 1); // Remove quote#2
  454. strcpy(tmp, tmp + 1); // Remove quote#1
  455. }
  456. if(*p == 0 || *p == ' ' || *p == 't') {
  457. tokens[args] = token_start;
  458. args++;
  459. if(args >= MAX_TOKEN_COUNT) break; // Break if too many args
  460. token_start = p + 1;
  461. if(*p == 0) break;
  462. *p = 0;
  463. }
  464. }
  465. // while ( (p = strtok((args?NULL:szCommand), " t")) != NULL && args < MAX_TOKEN_COUNT ) {
  466. //  tokens[args] = p;
  467. //  args++;
  468. // };
  469.     if ( !args ) return EMPTY_LINE;
  470.     argc = args - 1;
  471.     args = 0;
  472.     int curCmd = -1;
  473.     int ok = -1;
  474.     while ( ok < 0 ) {
  475. int tokenLen = strlen(tokens[args]);
  476. int match = 0;
  477. for ( int i = 0; i<__COMMAND_LIST_SIZE; i++ ) {
  478. if ( cmdMatch(cmdList[i].cmd, tokens[args], tokenLen, cmdList[i].minLen) ) {
  479. if (argc < cmdList[i].minParms || argc > cmdList[i].maxParms) {
  480. printUsage(i);
  481. return BAD_USAGE;
  482. };
  483. if ( cmdList[i].haveSubCmd && curCmd == cmdList[i].isSubCmd) {
  484. curCmd = i;
  485. args++;
  486. argc--;
  487. match = 1;
  488. break;
  489. };
  490. if ( curCmd == cmdList[i].isSubCmd ) {
  491. ok = i;
  492. match = 1;
  493. break;
  494. };
  495. printUsage(i);
  496. return BAD_USAGE;
  497. };
  498. };
  499. if ( !match ) {
  500. if ( curCmd < 0 ) return INVALID_CMD;
  501. printUsage(curCmd);
  502. return -3;
  503. };
  504.     };
  505.     for ( int i = 0; i<argc; i++ ) {
  506.         argv[i] = tokens[i+args+1];
  507.     };
  508.     return ok;
  509. };
  510. int telCommandLine (Telnet &MyConnection){
  511. #define HISTLENGTH 25
  512. int i, retval;
  513. char* Parms[MAX_PARM_COUNT];
  514. char szCommand[80];
  515. int bDone = 0;
  516. char *extitle, *newtitle;
  517. struct cmdHistory *cmdhist;
  518. cmdhist = NULL;
  519. // printit("n");  // crn@ozemail.com.au 14/12/98
  520. while (!bDone){
  521. // printit("n"); // Paul Brannan 5/25/98
  522. printit( "telnet>");
  523. cmdhist = cfgets (szCommand, 79, cmdhist);
  524. printit( "n");
  525. strlwr(szCommand);  // convert command line to lower
  526. // i = sscanf(szCommand,"%80s %80s %80s %80s", szCmd, szArg1, szArg2, szArg3);
  527. switch ( tokenizeCommand(szCommand, i, Parms) ) {
  528. case BAD_USAGE:   break;
  529. case EMPTY_LINE:  
  530. if(MyConnection.Resume() == TNPROMPT) {
  531. printit("n");
  532. break;
  533. }
  534. else
  535.   return 1;
  536. case INVALID_CMD:
  537. printm(0, FALSE, MSG_INVCMD);
  538. break;
  539. case OPEN:
  540. if (i == 1)
  541. retval = MyConnection.Open(Parms[0], "23");
  542. else
  543. retval = MyConnection.Open(Parms[0], Parms[1]);
  544. if(retval != TNNOCON && retval != TNPROMPT) return 1;
  545. if(retval == TNPROMPT) printit("n");
  546. break;
  547. case CLOSE:
  548. MyConnection.Close();
  549. break;
  550. case FASTQUIT: // Thomas Briggs 8/11/98
  551. case QUIT:
  552. MyConnection.Close();
  553. bDone = 1;
  554. break;
  555. case HELP:
  556. case HELP2:
  557. printm(0, FALSE, MSG_HELP);
  558. printm(0, FALSE, MSG_HELP_1);
  559. break;
  560. // case KEYS: we should never get it
  561. case K_LOAD:
  562. if ( i == 1 ) {
  563. // Ioannou : changed to ini.get_keyfile()
  564. if(MyConnection.LoadKeyMap( ini.get_keyfile(), Parms[0]) != 1)
  565. printit("Error loading keymap.n");
  566. break;
  567. };
  568. if(MyConnection.LoadKeyMap( Parms[1], Parms[0]) != 1)
  569. printit("Error loading keymap.n");
  570. break;
  571. case K_DISPLAY:
  572. MyConnection.DisplayKeyMap();
  573. break;
  574. case K_SWITCH:
  575. MyConnection.SwitchKeyMap(atoi(Parms[0]));
  576. break;
  577. // Paul Brannan 5/30/98
  578. case SET:
  579. if(i == 0) {
  580. printit("Available groups:n"); // Print out groups
  581. ini.print_groups(); // (Paul Brannan 9/3/98)
  582. } else if(i == 1) {
  583. ini.print_vars(Parms[0]);
  584. } else if(i >= 2) {
  585. ini.set_value(Parms[0], Parms[1]);
  586. // FIX ME !!! Ioannou: here we must call the parser routine for
  587. // wrap line, not the ini.set_value
  588. //  something like Parser.ConLineWrap(Wrap_Line);
  589. }
  590. break;
  591. case SUSPEND: // Thomas Briggs 8/11/98
  592. // remind the user we're suspended -crn@ozemail.com.au 15/12/98
  593. extitle = new char[128];
  594. GetConsoleTitle (extitle, 128);
  595. newtitle = new char[128+sizeof("[suspended]")];
  596. strcpy(newtitle, extitle);
  597. strncat(newtitle, "[suspended]", 128+sizeof("[suspended]"));
  598. if(ini.get_set_title()) SetConsoleTitle (newtitle);
  599. delete[] newtitle;
  600. if (getenv("comspec") == NULL) {
  601. switch (GetWin32Version()) {
  602. case 2: // 'cmd' is faster than 'command' in NT -crn@ozemail.com.au
  603. system ("cmd");
  604. break;
  605. default:
  606. system ("command");
  607. break;
  608. }
  609. } else {
  610. system(getenv("comspec"));
  611. }
  612. if(ini.get_set_title()) SetConsoleTitle (extitle);
  613. delete[] extitle;
  614. ///
  615. break;
  616. case CMD_HISTORY: //crn@ozemail.com.au
  617. if (cmdhist != NULL) {
  618. while (cmdhist->prev != NULL)
  619. cmdhist = cmdhist->prev; //rewind
  620. printf ("Command history:n");
  621. while (1) {
  622. printf ("t%sn", cmdhist->cmd);
  623. if (cmdhist->next != NULL)
  624. cmdhist = cmdhist->next;
  625. else
  626. break;
  627. }
  628. } else
  629. printf ("No command history available.n");
  630. break;
  631. case CLEAR_HISTORY: //crn@ozemail.com.au
  632. if (cmdhist != NULL) {
  633. while (cmdhist->next != NULL)
  634. cmdhist = cmdhist->next; //fast forward
  635. while (cmdhist->prev != NULL) {
  636. cmdhist = cmdhist->prev;
  637. delete cmdhist->next;
  638. }
  639. delete cmdhist;
  640. cmdhist = NULL;
  641. printf ("Command history cleared.n");
  642. } else
  643. printf ("No command history available.n");
  644. case ALIASES: // Paul Brannan 1/1/99
  645. ini.print_aliases();
  646. break;
  647. default: // paranoik
  648. printm(0, FALSE, MSG_INVCMD);
  649. break;
  650. }
  651. }
  652. return 0;
  653. }