Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728/////////////////////////////////////////////////////////////////////////////////Telnet Win32 : an ANSI telnet client.//Copyright (C) 1998 Paul Brannan//Copyright (C) 1998 I.Ioannou//Copyright (C) 1997 Brad Johnson////This program is free software; you can redistribute it and/or//modify it under the terms of the GNU General Public License//as published by the Free Software Foundation; either version 2//of the License, or (at your option) any later version.////This program is distributed in the hope that it will be useful,//but WITHOUT ANY WARRANTY; without even the implied warranty of//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the//GNU General Public License for more details.////You should have received a copy of the GNU General Public License//along with this program; if not, write to the Free Software//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.////I.Ioannou//roryt@hol.gr/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// Module: tnmain.cpp//// Contents: telnet main program//// Product: telnet//// Revisions: August 11, 1998 Thomas Briggs <tbriggs@qmetric.com>// May 14, 1998 Paul Brannan <pbranna@clemson.edu>// 5.April.1997 jbj@nounname.com// 5.Dec.1996 jbj@nounname.com// Version 2.0//// 02.Apr.1995 igor.milavec@uni-lj.si// Original code/////////////////////////////////////////////////////////////////////////////////
#include "precomp.h"
#include "tnmain.h"
int telCommandLine (Telnet &MyConnection);
void waitforkey() { HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); INPUT_RECORD InputRecord; DWORD dwInput; BOOL done = FALSE; while (!done){ WaitForSingleObject( hConsole, INFINITE ); if (!ReadConsoleInput(hConsole, &InputRecord, 1, &dwInput)){ done = TRUE; continue; } if (InputRecord.EventType == KEY_EVENT && InputRecord.Event.KeyEvent.bKeyDown ) done = TRUE; }}
//char * cfgets ( char * buf, unsigned int length, char pszHistory[][80], int iHistLength){struct cmdHistory * cfgets (char *buf, unsigned int length, struct cmdHistory *cmdhist) {
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); unsigned int current=0, cursor =0, iEraseLength=0, i; char chr; char temp[2]; char temp1[80];
INPUT_RECORD InputRecord; BOOL done = FALSE;
temp[1] = 0; buf[0] = '\0';
if(!ini.get_input_redir()) { while (!done) { DWORD dwInput; int MustRefresh = 0; WaitForSingleObject( hConsole, INFINITE ); if (!ReadConsoleInput(hConsole, &InputRecord, 1, &dwInput)){ done = TRUE; continue; } MustRefresh = 0; if (InputRecord.EventType == KEY_EVENT && InputRecord.Event.KeyEvent.bKeyDown ) {
if(InputRecord.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
switch(InputRecord.Event.KeyEvent.wVirtualKeyCode) { case 'D': // Thomas Briggs 8/11/98 buf[0] = '\04'; buf[1] = '\0'; current = 1; done = true; continue; case 'U': // Paul Brannan 8/11/98 buf[0] = '\0'; current = 0; cursor = 0; MustRefresh = 1; break; } }
switch (InputRecord.Event.KeyEvent.wVirtualKeyCode) { case VK_UP: // crn@ozemail.com.au if (cmdhist != NULL) { if (!strcmp(buf, "")) strncpy(buf, cmdhist->cmd, 79); else if (cmdhist->prev != NULL) { cmdhist = cmdhist->prev; strncpy(buf, cmdhist->cmd, 79); } current = strlen(buf); } /// MustRefresh = 1; break; case VK_DOWN: // crn@ozemail.com.au if (cmdhist != NULL) { if (cmdhist->next != NULL) { cmdhist = cmdhist->next; strncpy(buf, cmdhist->cmd, 79); } else { strncpy(buf, "", 79); } current = strlen(buf); } /// MustRefresh = 1; break; case VK_RIGHT: //crn@ozemail.com.au (added ctrl+arrow) if (cursor < current) { if (InputRecord.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) { unsigned int j, k; for (j = cursor; j <= current; j++) { if (buf[j + 1] == ' ' || (j + 1) == current) break; for (k = ++j; k <= current; k++) { if (buf[k] != ' ' || k == current) { cursor = k == current ? --k : k; break; } } } } else cursor++; MustRefresh = 1; break; } case VK_LEFT: //crn@ozemail.com.au (added ctrl+arrow) if (cursor > 0) { if(InputRecord.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) { int j, k; for (j = cursor; j >= 0; j--) { if (buf[j - 1] != ' ') break; for (k = --j; k >= 0; k--) { if (buf[k] == ' ' || k == 0) { cursor = !k ? k : ++k; break; } } } } else cursor--; MustRefresh = 1; break; } case VK_HOME: if (cursor>0) cursor = 0; MustRefresh = 1; break; case VK_END: if (cursor<current) cursor = current; MustRefresh = 1; break; case VK_DELETE: if (current > 0 && current > cursor) { strcpy(&buf[cursor],&buf[cursor+1]); current--; buf[current] = 0; printit("\r"); for (i = 0; i < current+strlen("telnet>")+1 ;i++) printit(" "); } MustRefresh = 1; break; case VK_BACK: if (cursor > 0 ) { strcpy(&buf[cursor-1],&buf[cursor]); current--; cursor--; buf[current] = 0; printit("\r"); for (i = 0; i < current+strlen("telnet>")+1 ;i++) printit(" "); } MustRefresh = 1; break;
default: chr = InputRecord.Event.KeyEvent.uChar.AsciiChar; if (chr == '\r') { done = TRUE; continue; } if (current >= length-1){ done = TRUE; continue; } if ( isprint (chr) ){ strncpy(temp1,&buf[cursor],79); strncpy(&buf[cursor+1],temp1,79-(cursor+1)); buf[cursor++]=chr; current++; buf[current] = 0; MustRefresh = 1; } break; } if (MustRefresh == 1) { printit("\rtelnet"); for (i = 0; i <= iEraseLength ;i++) printit(" "); printit("\rtelnet>"); printit(buf); iEraseLength = strlen(buf); for (i = 0; i < current-cursor; i++) printit("\b"); } } } buf[current] = 0; if (strcmp(buf, "")) { if (cmdhist == NULL) { cmdhist = new struct cmdHistory; if (cmdhist == NULL) { printit ("\nUnable to allocate memory for history buffer -- use the \"flush\" command to clear the buffer.\n"); return cmdhist; } strncpy(cmdhist->cmd, buf, 79); cmdhist->next = NULL; cmdhist->prev = NULL; } else { while (cmdhist->next != NULL) // move to the end of the list cmdhist = cmdhist->next; cmdhist->next = new struct cmdHistory; if (cmdhist->next == NULL) { printit ("\nUnable to allocate memory for history buffer -- use the \"flush\" command to clear the buffer.\n"); return cmdhist; } cmdhist->next->prev = cmdhist; // previous is where we are now cmdhist = cmdhist->next; strncpy(cmdhist->cmd, buf, 79); cmdhist->next = NULL; } while (cmdhist->next) cmdhist = cmdhist->next; } return cmdhist; /// } else { WaitForSingleObject( hConsole, INFINITE ); DWORD dwInput; DWORD OldMode; GetConsoleMode(hConsole, &OldMode); SetConsoleMode(hConsole, OldMode &~ (ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT) ); while (ReadFile(hConsole, &chr, 1, &dwInput, NULL)) { if (chr == '\r') { temp[0] = chr; printit(&temp[0]); break; } if (chr == '\b' && current > 0) { current--; printit("\b \b"); } if (current >= length-1){ break; } if ( isprint (chr) ){ temp[0] = chr; printit(&temp[0]); buf[current++]=chr; } } buf[current] = 0; SetConsoleMode(hConsole, OldMode); return NULL; }}
// AVS ** for fix bug in command 'keys load keymapname' without file// static char keyfile[MAX_PATH*2];
int main(int ArgC, char* ArgV[]) {
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo; GetConsoleScreenBufferInfo( GetStdHandle(STD_OUTPUT_HANDLE), &ConsoleScreenBufferInfo );
char *k; char startdir[MAX_PATH*2]; char exename[MAX_PATH];
// strncpy(startdir, ArgV[0],MAX_PATH); // This should be more accurate than using argv[0] (Paul Brannan 9/16/98) GetModuleFileName(NULL, startdir, sizeof(startdir));
// Get the current console title so it can be set later // ("Pedro A. Aranda Guti�rrez" <paag@coppi.tid.es>) TCHAR ConsoleTitle[255]; GetConsoleTitle(ConsoleTitle, sizeof(ConsoleTitle));
k = strrchr(startdir, '\\'); if (k == NULL){ // if the \ character is not found... strcpy(exename, startdir); strcpy(startdir,""); // set the path to nothing } else { // end the string after the last '\' to get rid of the file name strcpy(exename, k+1); k[1] = 0; }
printm(0, FALSE, MSG_COPYRIGHT); printm(0, FALSE, MSG_COPYRIGHT_1);
// set up the ini class ini.init(startdir, exename);
// Process the command line arguments and connect to a host if necessary if(ini.Process_Params(ArgC, ArgV)) { const char *szHost = ini.get_host(); const char *strPort = ini.get_port(); if(!*szHost) { Telnet MyConnection; while(telCommandLine(MyConnection)); } else { Telnet MyConnection; if(MyConnection.Open(szHost, strPort) == TNPROMPT) { // still connected printit("\n"); telCommandLine(MyConnection); } } } //// (Paul Brannan 5/14/98)
if(ini.get_term_width() != -1 || ini.get_term_height() != -1) { SetConsoleScreenBufferSize( GetStdHandle(STD_OUTPUT_HANDLE), // handle of console screen buffer ConsoleScreenBufferInfo.dwSize // new size in character rows and cols. ); SetConsoleWindowInfo( GetStdHandle(STD_OUTPUT_HANDLE), // handle of console screen buffer TRUE, // coordinate type flag &ConsoleScreenBufferInfo.srWindow // address of new window rectangle ); } SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), // handle of console screen buffer ConsoleScreenBufferInfo.wAttributes // text and background colors );
// Restore the original console title // ("Pedro A. Aranda Guti�rrez" <paag@coppi.tid.es>) SetConsoleTitle(ConsoleTitle);
return 0;}
// AVSenum { BAD_USAGE = -3, EMPTY_LINE = -2, INVALID_CMD = -1, __FIRST_COMMAND = 0,
OPEN = __FIRST_COMMAND, CLOSE, KEYS, QUIT, HELP, HELP2, // there is way for synonims K_LOAD, // subcommand of 'keys' K_SWITCH, // subcommand of 'keys' K_DISPLAY, // subcommand of 'keys'
SET, // Paul Brannan 5/30/98
SUSPEND, FASTQUIT, // Thomas Briggs 8/11/98 CMD_HISTORY, // crn@ozemail.com.au CLEAR_HISTORY, // crn@ozemail.com.au
ALIASES, // Paul Brannan 1/1/99
__COMMAND_LIST_SIZE // must be last};
struct command { const char* cmd; // command int minLen, // minimal length for match minParms, // minimal count of parms maxParms; // maximal -/- (negative disables) int isSubCmd, // is a subcommand - number of wich command haveSubCmd; // have subcommands? 0 or 1 const char* usage; // text of usage};
command cmdList[__COMMAND_LIST_SIZE] = { {"open", 1, 1, 2, -1, 0, "o[pen] host [port]\n"}, {"close", 2, 0, 0, -1, 0, NULL}, {"keys", 2, 1, 3, -1, 1, "ke[ys] l[oad] keymapname [file]\n" "ke[ys] d[isplay]\n" "ke[ys] s[witch] number\n"}, // Ioannou : i change it to q, to be more compatible with unix telnet {"quit", 1, 0, 0, -1, 0, NULL}, // must type it exactly {"?", 1, 0, 0, -1, 0, NULL}, {"help", 1, 0, 0, -1, 0, NULL}, {"load", 1, 1, 2, KEYS, 0, NULL}, {"switch", 1, 1, 1, KEYS, 0, NULL}, {"display", 1, 0, 0, KEYS, 0, NULL}, // Paul Brannan 5/30/98 {"set", 3, 0, 2, -1, 0, "set will display available groups.\n" "set groupname will display all variables/values in a group.\n" "set [variable [value]] will set variable to value.\n"}, // Thomas Briggs 8/11/98 {"z", 1, 0, 0, -1, 0, "suspend telnet\n"}, {"\04", 1, 0, 0, -1, 0, NULL}, // crn@ozemail.com.au {"history", 2, 0, 0, -1, 0, "show command history"}, {"flush", 2, 0, 0, -1, 0, "flush history buffer"}, // Paul Brannan 1/1/99 {"aliases", 5, 0, 0, -1, 0, NULL}};
// a maximal count of parms#define MAX_PARM_COUNT 3#define MAX_TOKEN_COUNT (MAX_PARM_COUNT+2)
static int cmdMatch(const char* cmd, const char* token, int tokenLen, int minM) { if ( tokenLen < minM ) return 0; // The (unsigned) gets rid of a compiler warning (Paul Brannan 5/25/98) if ( (unsigned)tokenLen > strlen(cmd) ) return 0; if ( strcmp(cmd,token) == 0 ) return 1;
int i; for ( i = 0; i < minM; i++ ) if ( cmd[i] != token[i] ) return 0;
for ( i = minM; i < tokenLen; i++ ) if ( cmd[i] != token[i] ) return 0;
return 1;};
static void printUsage(int cmd) { if ( cmdList[cmd].usage != NULL ) { printit(cmdList[cmd].usage); return; }; if ( cmdList[cmd].isSubCmd >= 0 ) { printUsage(cmdList[cmd].isSubCmd); return; } printm(0, FALSE, MSG_BADUSAGE);};
int tokenizeCommand(char* szCommand, int& argc, char** argv) { char* tokens[MAX_TOKEN_COUNT]; char* p; int args = 0;
if(!szCommand || !*szCommand) return EMPTY_LINE;
// Removed strtok to handle tokens with spaces; this is handled with // quotes. (Paul Brannan 3/18/99) char *token_start = szCommand; for(p = szCommand;; p++) { if(*p == '\"') { char *tmp = p; for(p++; *p != '\"' && *p != 0; p++); // Find the next quote if(*p != 0) strcpy(p, p + 1); // Remove quote#2 strcpy(tmp, tmp + 1); // Remove quote#1 } if(*p == 0 || *p == ' ' || *p == '\t') { tokens[args] = token_start; args++; if(args >= MAX_TOKEN_COUNT) break; // Break if too many args token_start = p + 1; if(*p == 0) break; *p = 0; } } // while ( (p = strtok((args?NULL:szCommand), " \t")) != NULL && args < MAX_TOKEN_COUNT ) { // tokens[args] = p; // args++; // };
if ( !args ) return EMPTY_LINE; argc = args - 1; args = 0; int curCmd = -1; int ok = -1; while ( ok < 0 ) { int tokenLen = strlen(tokens[args]); int match = 0; for ( int i = 0; i<__COMMAND_LIST_SIZE; i++ ) { if ( cmdMatch(cmdList[i].cmd, tokens[args], tokenLen, cmdList[i].minLen) ) { if (argc < cmdList[i].minParms || argc > cmdList[i].maxParms) { printUsage(i); return BAD_USAGE; }; if ( cmdList[i].haveSubCmd && curCmd == cmdList[i].isSubCmd) { curCmd = i; args++; argc--; match = 1; break; }; if ( curCmd == cmdList[i].isSubCmd ) { ok = i; match = 1; break; }; printUsage(i); return BAD_USAGE; }; }; if ( !match ) { if ( curCmd < 0 ) return INVALID_CMD; printUsage(curCmd); return -3; }; };
for ( int i = 0; i<argc; i++ ) { argv[i] = tokens[i+args+1]; }; return ok;
};
int telCommandLine (Telnet &MyConnection){#define HISTLENGTH 25 int i, retval; char* Parms[MAX_PARM_COUNT]; char szCommand[80]; int bDone = 0; char *extitle, *newtitle; struct cmdHistory *cmdhist; cmdhist = NULL;
// printit("\n"); // crn@ozemail.com.au 14/12/98 while (!bDone){ // printit("\n"); // Paul Brannan 5/25/98 printit( "telnet>"); cmdhist = cfgets (szCommand, 79, cmdhist); printit( "\n");
strlwr(szCommand); // convert command line to lower // i = sscanf(szCommand,"%80s %80s %80s %80s", szCmd, szArg1, szArg2, szArg3); switch ( tokenizeCommand(szCommand, i, Parms) ) { case BAD_USAGE: break; case EMPTY_LINE: if(MyConnection.Resume() == TNPROMPT) { printit("\n"); break; } else return 1; case INVALID_CMD: printm(0, FALSE, MSG_INVCMD); break; case OPEN: if (i == 1) retval = MyConnection.Open(Parms[0], "23"); else retval = MyConnection.Open(Parms[0], Parms[1]); if(retval != TNNOCON && retval != TNPROMPT) return 1; if(retval == TNPROMPT) printit("\n"); break; case CLOSE: MyConnection.Close(); break; case FASTQUIT: // Thomas Briggs 8/11/98 case QUIT: MyConnection.Close(); bDone = 1; break; case HELP: case HELP2: printm(0, FALSE, MSG_HELP); printm(0, FALSE, MSG_HELP_1); break; // case KEYS: we should never get it case K_LOAD: if ( i == 1 ) { // Ioannou : changed to ini.get_keyfile() if(MyConnection.LoadKeyMap( ini.get_keyfile(), Parms[0]) != 1) printit("Error loading keymap.\n"); break; }; if(MyConnection.LoadKeyMap( Parms[1], Parms[0]) != 1) printit("Error loading keymap.\n"); break; case K_DISPLAY: MyConnection.DisplayKeyMap(); break; case K_SWITCH: MyConnection.SwitchKeyMap(atoi(Parms[0])); break;
// Paul Brannan 5/30/98 case SET: if(i == 0) { printit("Available groups:\n"); // Print out groups ini.print_groups(); // (Paul Brannan 9/3/98) } else if(i == 1) { ini.print_vars(Parms[0]); } else if(i >= 2) { ini.set_value(Parms[0], Parms[1]); // FIX ME !!! Ioannou: here we must call the parser routine for // wrap line, not the ini.set_value // something like Parser.ConLineWrap(Wrap_Line); } break;
case SUSPEND: // Thomas Briggs 8/11/98
// remind the user we're suspended -crn@ozemail.com.au 15/12/98 extitle = new char[128]; GetConsoleTitle (extitle, 128);
newtitle = new char[128+sizeof("[suspended]")]; strcpy(newtitle, extitle); strncat(newtitle, "[suspended]", 128+sizeof("[suspended]")); if(ini.get_set_title()) SetConsoleTitle (newtitle); delete[] newtitle;
if (getenv("comspec") == NULL) { switch (GetWin32Version()) { case 2: // 'cmd' is faster than 'command' in NT -crn@ozemail.com.au system ("cmd"); break; default: system ("command"); break; } } else { system(getenv("comspec")); }
if(ini.get_set_title()) SetConsoleTitle (extitle); delete[] extitle; ///
break;
case CMD_HISTORY: //crn@ozemail.com.au if (cmdhist != NULL) { while (cmdhist->prev != NULL) cmdhist = cmdhist->prev; //rewind printf ("Command history:\n"); while (1) { printf ("\t%s\n", cmdhist->cmd);
if (cmdhist->next != NULL) cmdhist = cmdhist->next; else break; } } else printf ("No command history available.\n");
break;
case CLEAR_HISTORY: //crn@ozemail.com.au if (cmdhist != NULL) { while (cmdhist->next != NULL) cmdhist = cmdhist->next; //fast forward while (cmdhist->prev != NULL) { cmdhist = cmdhist->prev; delete cmdhist->next; } delete cmdhist; cmdhist = NULL; printf ("Command history cleared.\n"); } else printf ("No command history available.\n");
case ALIASES: // Paul Brannan 1/1/99 ini.print_aliases(); break;
default: // paranoik printm(0, FALSE, MSG_INVCMD); break; }
}
return 0;}