📄 wvdialbrain.cc
字号:
/* * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * The brains behind the WvDialer class. This handles prompt-detection, * menu-guessing, and related tasks. * */#include "wvdialbrain.h"#include "wvdialer.h"#include <ctype.h>#include <string.h>#include <time.h>static char rbrackets[] = ".-:'\">)]}"; static char lbrackets[] = ".-:'\"<([{";static char brackets[] = ".-:'\"<>()[]{}";static char menu_bad_words[] = "press push hit enter type key";//**************************************************// WvDialBrain Public Functions//**************************************************WvDialBrain::WvDialBrain( WvDialer * a_dialer )/*********************************************/: dialer( a_dialer ){ saw_first_compuserve_prompt = 0; reset();}WvDialBrain::~WvDialBrain()/*************************/{}void WvDialBrain::reset()/***********************/{ sent_login = 0; prompt_tries = 0; prompt_response = "";}const char * WvDialBrain::guess_menu( char * buf )/************************************************/// Searches buf for signs of intelligence, and tries to guess how to// start PPP on the remote side. Good for terminal servers with menus,// prompts, and (hopefully) whatever else.// Assumes buf is lowercase already, and has all its nulls turned into// whitespace.{ char * cptr = NULL; char * line; char * nextline; BrainToken * tok; while( strstr( buf, "ppp" ) != NULL ) { cptr = strstr( buf, "ppp" ); // pick out the beginning of the line containing "ppp" for( line=cptr; line >= buf && !isnewline( *line ); line-- ) ; line++; // too far! // find the beginning of the next line in the buffer, or the // end of the buffer... so we know where to stop our searches. for( nextline = line; *nextline && !isnewline( *nextline ); nextline++ ) ; buf = nextline; // now 'continue' will check the next line // Now tokenize the line and perform an IntelliSearch (tm) tok = tokenize( line, nextline ); if( tok ) { guess_menu_guts( tok ); // may call set_prompt_response() token_list_done( tok ); } } if( cptr ) return( cptr + 4 ); // return pointer directly AFTER "ppp". else return( NULL );}const char * WvDialBrain::check_prompt( const char * buffer )/***********************************************************/{ WvString tprompt; // If we've been here too many times, or too long ago, just give up and // start pppd. if( prompt_tries >= 5 || time( NULL ) - dialer->last_rx >= 10 ) { dialer->log( WvLog::Notice, "Don't know what to do! " "Starting pppd and hoping for the best.\n" ); dialer->start_ppp(); } else if( dialer->options.compuserve && is_compuserve_prompt( buffer )) { // We have a login prompt, so send a suitable response. const char * send_this = "CIS"; dialer->log( "Looks like a Compuserve host name prompt.\n" "Sending: %s\n", send_this ); saw_first_compuserve_prompt++; saw_first_compuserve_prompt++; dialer->reset_offset(); prompt_tries++; return( send_this ); } else if( dialer->options.compuserve && !saw_first_compuserve_prompt && is_login_prompt ( buffer )) { // We have a login prompt, so send a suitable response. const char * send_this = "cisv1"; dialer->log( "Looks like a Compuserve New login prompt.\n" "Sending: %s\n", send_this ); dialer->reset_offset(); prompt_tries++; saw_first_compuserve_prompt++; return( send_this ); } else if( is_login_prompt( buffer ) ) { // We have a login prompt, so send a suitable response. WvString login = dialer->options.login; if (dialer->options.compuserve && strstr (dialer->options.login, "/noint") == 0) { login = WvString("%s%s", login, "/noint/go:pppconnect"); } dialer->log( "Looks like a login prompt.\n" "Sending: %s\n", login ); dialer->reset_offset(); prompt_tries++; return( login ); } else if( is_password_prompt( buffer ) ) { const char *passwd = 0; if (dialer->options.compuserve && saw_first_compuserve_prompt == 1) { passwd = "classic"; dialer->log( "Looks like a Compuserve classic password prompt.\nSending: classic\n" ); saw_first_compuserve_prompt++; } else { // We have a password prompt, so send a suitable resonse. dialer->log( "Looks like a password prompt.\nSending: (password)\n" ); } dialer->reset_offset(); prompt_tries++; sent_login = 1; // yes, we've sent a password: // assume we've sent username too. if (!passwd) passwd = dialer->options.password; return( passwd ); } else if( is_welcome_msg( buffer ) ) { dialer->log( "Looks like a welcome message.\n" ); dialer->start_ppp(); } else if( is_prompt( buffer ) ) { // We have some other prompt. if( dialer->is_pending() ) { return( NULL ); // figure it out next time } if( !prompt_response[0] ) prompt_response = dialer->options.default_reply; // wild guess dialer->log( "Hmm... a prompt. Sending \"%s\".\n", prompt_response ); dialer->reset_offset(); prompt_tries++; // only use our prompt guess the first time. // if it fails, go back to the default reply. tprompt = prompt_response; prompt_response = ""; return( tprompt ); } else { // not a prompt at all! if( dialer->is_pending() ) return( NULL ); // figure it out next time } // If we get here, then we aren't at a prompt. return( NULL );}//**************************************************// WvDialBrain Private Functions//**************************************************bool WvDialBrain::is_prompt( const char * c, const char * promptstring, bool dots_wild )/***************************************************/// Searches the buffer 'c' for a prompt. If no promptstring is given, we// return true for ANY prompt. If a prompt string is given, then we are// looking for a SPECIFIC prompt that contains that string.{ const char * cptr; static const char * prompt_punct = ")>}]:.|-?$%=\x11"; // if no promptstring was given, the search is simple: it is a // prompt if the last line ends in punctuation and no newline. if( !promptstring ) { for( cptr = c + strlen( c ) - 1; cptr >= c; cptr-- ) { if( isnewline( *cptr ) ) { if ( !prompt_response[0] ) return( false ); // last line was empty: not a prompt else continue; // we have a guess, so use it anyway, IF the // last non-blank line was a prompt. } if( strchr( prompt_punct, *cptr ) ) return( true ); // first non-whitespace was punctuation! good. if ( !isspace( *cptr ) ) return( false ); // not punctuation or whitespace at end } return( false ); } // seek backwards from the end of the buffer to the beginning of // the last line, or the beginning of the buffer, whichever comes first. // Then skip leading whitespace so that when we are done, (c) points at // the first non-white character on the line. for( cptr = c + strlen( c ) - 1; cptr >= c; cptr-- ) { if( isnewline( *cptr ) ) break; } c = cptr > c ? cptr : c; while( isspace( *c ) ) c++; // find the promptstring in the buffer. if( dots_wild == false ) { // a bit of an obscure case, but: find the _last_ occurrence on the // prompt line, not the first. c = strstr( c, promptstring ); if( !c ) return( false ); else while( strstr( c+1, promptstring ) ) c = strstr( c+1, promptstring ); } else { // dots are wild, like in regular expressions const char * p = c; unsigned int char_count = 0; while( *p != '\0' && char_count != strlen( promptstring ) ) { char tmp = promptstring[ char_count ]; if( tmp == '.' || *p == tmp ) { if( char_count == 0 ) { // If we match the beginning of the promptstring, // set c to point at it. c = p; } char_count++; } else { // Start over, since a letter did not match and was not a dot. char_count = 0; } p++; } // If we hit the end of the promptstring, and char_count does not // equal its length, then it was not there. if( char_count != strlen( promptstring ) ) return( false ); } // now make sure everything after "promptstring" is whitespace // and there is at least one punctuation mark. bool foundpunct = false; for( c += strlen( promptstring ); *c; c++ ) { if( strchr( prompt_punct, *c ) ) foundpunct = true; else if( !isspace( *c ) ) return false; // non-whitespace or punctuation: not a prompt } return( foundpunct ); // found a prompt if the string was followed by punct}bool WvDialBrain::is_login_prompt( const char * buf )/***************************************************/{ return( is_prompt( buf, "login" ) || is_prompt( buf, "name" ) || is_prompt( buf, "user" ) || is_prompt( buf, "id" ) || is_prompt( buf, "userid" ) || is_prompt( buf, "user.id", true ) || is_prompt( buf, "signon" ) || is_prompt( buf, "sign.on", true ) || is_prompt( buf, "usuario", false ) || ( dialer->options.login_prompt[0] && is_prompt( buf, dialer->options.login_prompt ) ) );}bool WvDialBrain::is_compuserve_prompt( const char * buf )/***************************************************/{ return( is_prompt( buf, "host name" ));}bool WvDialBrain::is_password_prompt( const char * buf )/******************************************************/{ return( is_prompt( buf, "password" ) || ( dialer->options.pass_prompt[0] && is_prompt( buf, dialer->options.pass_prompt ) ) );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -