⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wvdialer.cc

📁 wvdial 软件包是一个自动拨号程序
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* * Worldvisions Weaver Software: *   Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * Implementation of the WvDialer smart-dialer class.   * */#include "wvdialer.h"#include "wvver.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <signal.h>#include <termios.h>#include <time.h>#include <unistd.h>#include <ctype.h>#include <errno.h>#include <assert.h>#include <xplc/xplc.h>static char *	init_responses[] = {	"ok",	"error",	NULL};static char *	dial_responses[] = {	"connect",	"no carrier",	"no dialtone",	"no dial tone",	"busy",	"error",	"voice",	"fclass",	"no answer",	NULL};static char *	prompt_strings[] = {	"}!}",	"!}!",	NULL};static int messagetail_pid = 0;//**************************************************//       WvDialer Public Functions//**************************************************WvDialer::WvDialer( WvConf &_cfg, WvStringList *_sect_list, bool _chat_mode )/***************************************************************************/: WvStreamClone( 0 ),    cfg(_cfg), log( "WvDial", WvLog::Debug ),    err( log.split( WvLog::Error ) ),    modemrx( "WvDial Modem", WvLog::Debug ){    ppp_pipe 		 = NULL;    pppd_log		 = NULL;    been_online 	 = false;    stat 		 = Idle;    offset 		 = 0;    prompt_tries 	 = 0;    last_rx 		 = last_execute = 0;    prompt_response 	 = "";    auto_reconnect_delay = 0;    auto_reconnect_at    = 0;    connected_at         = 0;    phnum_count = 0;    phnum_max = 0;          // tell wvstreams we need our own subtask    uses_continue_select = true;    brain = NULL;    modem = NULL;    sect_list = _sect_list;    chat_mode = _chat_mode;        log("WvDial: Internet dialer version " WVDIAL_VER_STRING "\n");    // Ensure all sections in sect_list actually exist, warning if not.    WvStringList::Iter iter(*sect_list);    for(iter.rewind(); iter.next();)     {    	if(cfg[*iter] == NULL)         {    	    err(WvLog::Warning,		"Warning: section [%s] does not exist in wvdial.conf.\n",		*iter);    	}    }    // Ensure all inherited sections exist, warning if not.    WvConfigSectionList::Iter iter2 (cfg);    for (iter2.rewind(); iter2.next();)     {         WvConfigSection & sect2 = *iter2;        WvConfigEntry * entry = sect2["Inherits"];        if (entry)         {            WvString inherits = entry->value;            if (cfg[inherits] == NULL)                err( WvLog::Warning,                       "Warning: inherited section [%s] does not exist in wvdial.conf\n",                     inherits);       }    }       // Activate the brain and read configuration.    brain = new WvDialBrain(this);    // init_modem() reads the config options.  It MUST run here!        if(!init_modem())    {	// init_modem() printed an error	stat = ModemError;	return;    }        if (options.provider.len())     {	log( WvLog::Notice, "Dialing %s %s.\n",		options.provider,		options.product);    }    if (options.homepage.len())     {        log(WvLog::Notice, "Homepage of %s: %s\n",	    options.provider.len() ? options.provider.cstr() : "this provider",	    options.homepage);    }    if(options.auto_reconnect && options.idle_seconds > 0)     {	err(WvLog::Notice,	    "Idle Seconds = %s, disabling automatic reconnect.\n",	    options.idle_seconds);        options.auto_reconnect = false;    }        pppd_mon.setdnstests(options.dnstest1, options.dnstest2);    pppd_mon.setcheckdns(options.check_dns);    pppd_mon.setcheckdfr(options.check_dfr);}WvDialer::~WvDialer()/*******************/{    terminate_continue_select();    WVRELEASE(ppp_pipe);    WVRELEASE(pppd_log);    delete brain;}bool WvDialer::dial()/*******************/// Returns false on error, or true to go asynchronous while dialing.{    if(stat == Online)    	return(true);	    if(stat != Idle)     {	// error message has already been printed elsewhere    	return(false);    }    if (!options.phnum)     {	err( "Configuration does not specify a valid phone number.\n" );    	stat = OtherError;    }    if (!options.login)     {	err( "Configuration does not specify a valid login name.\n" );    	stat = OtherError;    }    if (!options.password)     {	err( "Configuration does not specify a valid password.\n" );    	stat = OtherError;    }        if( stat != Idle )	return( false );    phnum_max = 0;    if(options.phnum1.len())     { 	phnum_max++;        if(options.phnum2.len()) 	{ 	    phnum_max++;            if(options.phnum3.len()) 	    { 		phnum_max++;          	if(options.phnum4.len()) 		    phnum_max++;	    }	}    }    // we need to re-init the modem if we were online before.    if(been_online && !init_modem())	stat = ModemError;    else    {	stat = Dial;	connect_attempts = 1;	dial_stat = 0;	brain->reset();    }        return(true);}void WvDialer::hangup()/*********************/{    WVRELEASE(ppp_pipe);        if( !chat_mode )      pppd_watch( 250 );        if( stat != Idle )     {	time_t 	now;	time( &now );	log( "Disconnecting at %s", ctime( &now ) );	del_modem();	stat = Idle;    }    if (messagetail_pid > 0)     {	kill(messagetail_pid, 15);	messagetail_pid = 0;    }}bool WvDialer::pre_select( SelectInfo& si )/*******************************************/{    if( isok() && stat != Online && stat != Idle	&& time( NULL ) - last_execute > 1 )    {	// Pretend we have "data ready," so execute() gets called.	// select() already returns true whenever the modem is readable,	// but when we are doing a timeout (eg. PreDial1/2) for example,	// we need to execute() even if no modem data is incoming.	return( true );    }     else     {	return WvStreamClone::pre_select( si );    }}bool WvDialer::isok() const/*************************/{    bool b = ( !modem || modem->isok() )	&& stat != ModemError && stat != OtherError;    /*     if (!b)        err("Returning not ok!!\n" );     */    return( b );}char *WvDialer::connect_status() const/*************************************/{    static char msg[ 160 ];    switch( stat )     {    case PreDial2:    case PreDial1:    case Dial:    case WaitDial:	if( dial_stat == 1 )	    strcpy( msg, "Last attempt timed out.  Trying again." );	else if( dial_stat == 2 )	    strcpy( msg, "Modem did not connect last attempt.  Trying again." );	else if( dial_stat == 3 )	    strcpy( msg, "No dial tone last attempt.  Trying again." );    	else if( dial_stat == 4 )    	    strcpy( msg, "Busy signal on last attempt.  Trying again." );    	else if( dial_stat == 5 )    	    strcpy( msg, "Voice answer on last attempt.  Trying again." );    	else if( dial_stat == 6 )    	    strcpy( msg, "Fax answer on last attempt.  Trying again." );	else if( dial_stat == 7 )            strcpy( msg, "No answer on last attempt.  Trying again." );    	else    	    return( NULL );	break;    case WaitAnything:    	strcpy( msg, "Waiting for a response from Internet Provider." );    	break;    case WaitPrompt:    	strcpy( msg, "Waiting for a prompt from Internet Provider." );    	break;    case AutoReconnectDelay:    	sprintf( msg, "Next attempt in 00:%02ld:%02ld.",     		 ( auto_reconnect_at - time( NULL ) ) / 60,    		 ( auto_reconnect_at - time( NULL ) ) % 60 );    	break;    default:    	return( NULL );    }    return( msg );}void WvDialer::pppd_watch( int ms )/*********************************/{  // see if pppd has a message, analyse it and output to log      if( pppd_log != NULL && pppd_log->isok() )     {    	char *line;        	while ( (line = pppd_log->blocking_getline( ms )) )    	{	    WvString buffer1(pppd_mon.analyse_line( line ));	    if (!!buffer1)	    {	    	log("pppd: %s\n", buffer1);    	    }        }    }}void WvDialer::execute()/**********************/{    WvStreamClone::execute();        // the modem object might not exist, if we just disconnected and are    // redialing.    if( !modem && !init_modem() )    	return;    last_execute = time( NULL );        if( !chat_mode )      pppd_watch( 100 );        switch( stat )     {    case Dial:    case WaitDial:    case PreDial1:    case PreDial2:	async_dial();	break;    case WaitAnything:	// we allow some time after connection for silly servers/modems.	if( modem->select( 500, true, false ) ) 	{	    // if any data comes in at all, switch to impatient mode.	    stat = WaitPrompt;	    last_rx = time( NULL );	} 	else if( time( NULL ) - last_rx >= 30 ) 	{	    // timed out - do what WaitPrompt would do on a timeout.	    stat = WaitPrompt;	} 	else 	{	    // We prod the server with a CR character every once in a while.	    // FIXME: Does this cause problems with login prompts?	    modem->write( "\r", 1 );	}	break;    case WaitPrompt:    	async_waitprompt();    	break;    case Online:	assert( !chat_mode );    	// If already online, we only need to make sure pppd is still there.	if( ppp_pipe && ppp_pipe->child_exited() ) 	{	    int pppd_exit_status = ppp_pipe->exit_status();	    if( ppp_pipe->child_killed() ) 	    {		log( WvLog::Error, "PPP was killed! (signal = %s)\n",		      ppp_pipe->exit_status() );	    }	    // we must delete the WvModem object so it can be recreated	    // later; starting pppd seems to screw up the file descriptor.	    hangup();	    del_modem();	    	    time_t call_duration = time( NULL ) - connected_at;	    	    if( pppd_mon.auth_failed() ) 	    {	      log("Authentication error.\n"		  "We failed to authenticate ourselves to the peer.\n"		  "Maybe bad account or password?\n" );	    } 	    else 	    {		WvString msg = "";		switch (pppd_exit_status) 		{		case  2: 		    msg = "pppd options error"; 		    break;		case  3: 		    msg = "No root priv error"; 		    break;		case  4: 		    msg = "No ppp module error"; 		    break;		case 10: 		    msg = "PPP negotiation failed"; 		    break;		case 11: 		    msg = "Peer didn't authenticatie itself"; 		    break;		case 12: 		    msg = "Link idle: Idle Seconds reached."; 		    break;		case 13: 		    msg = "Connect time limit reached."; 		    break;		case 14: 		    msg = "Callback negotiated, call should come back.";		    break;		case 15: 		    msg = "Lack of LCP echo responses"; 		    break;		case 17: 		    msg = "Loopback detected"; 		    break;		case 19: 		    msg = "Authentication error.\n"			"We failed to authenticate ourselves to the peer.\n"			"Maybe bad account or password?";		    break;		}		if (msg.len()) 		{		    // Note: exit code = %s is parsed by kinternet:		    log("The PPP daemon has died: %s (exit code = %s)\n",			msg, pppd_exit_status);		    log("man pppd explains pppd error codes in more detail.\n");		    err(WvLog::Notice, "I guess that's it for now, exiting\n");		    if (pppd_exit_status == 12 && options.auto_reconnect)			err(WvLog::Notice, "Idle parameter is passed to pppd\n"			    "If you don't want an idle timeout per default,\n"			    "comment out the idle parameter in /etc/ppp/options\n");		    if (pppd_exit_status == 15) 		    {		        log("Provider is overloaded(often the case) or line problem.\n");		    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -