📄 wvdialer.cc
字号:
start_ppp(); } } else { log( "Carrier detected. Waiting for prompt.\n" ); stat = WaitAnything; } return; case 1: // NO CARRIER log( WvLog::Warning, "No Carrier! Trying again.\n" ); stat = PreDial1; connect_attempts++; dial_stat = 2; continue_select(2000); //if Attempts in wvdial.conf is 0..dont do anything if(options.dial_attempts != 0) { if(check_attempts_exceeded(connect_attempts)) { hangup(); } } return; case 2: // NO DIALTONE case 3: // NO DIAL TONE if( options.abort_on_no_dialtone == true ) { err( "No dial tone.\n" ); stat = ModemError; } else { log( "No dial tone. Trying again in 5 seconds.\n" ); stat = PreDial2; connect_attempts++; dial_stat = 3; //if Attempts in wvdial.conf is 0..dont do anything if(options.dial_attempts != 0) { if(check_attempts_exceeded(connect_attempts)) { hangup(); } } } return; case 4: // BUSY if( options.abort_on_busy == true ) { err( "The line is busy.\n" ); stat = ModemError; } else { if( phnum_count++ == phnum_max ) phnum_count = 0; if( phnum_count == 0 ) log( WvLog::Warning, "The line is busy. Trying again.\n" ); else log( WvLog::Warning, "The line is busy. Trying other number.\n"); stat = PreDial1; connect_attempts++; dial_stat = 4; continue_select(2000); } return; case 5: // ERROR err( "Invalid dial command.\n" ); stat = ModemError; //if Attempts in wvdial.conf is 0..dont do anything if(options.dial_attempts != 0) { if(check_attempts_exceeded(connect_attempts)) { hangup(); } } return; case 6: // VOICE log( "Voice line detected. Trying again.\n" ); connect_attempts++; dial_stat = 5; stat = PreDial2; //if Attempts in wvdial.conf is 0..dont do anything if(options.dial_attempts != 0) { if(check_attempts_exceeded(connect_attempts)) { hangup(); } } return; case 7: // FCLASS log( "Fax line detected. Trying again.\n" ); connect_attempts++; dial_stat = 6; stat = PreDial2; if(options.dial_attempts != 0) { if(check_attempts_exceeded(connect_attempts)) { hangup(); } } return; case 8: // NO ANSWER log( WvLog::Warning, "No Answer. Trying again.\n" ); stat = PreDial1; connect_attempts++; dial_stat = 7; if(options.dial_attempts != 0) { if(check_attempts_exceeded(connect_attempts)) { hangup(); } } continue_select(2000); return; default: err( "Unknown dial response string.\n" ); stat = ModemError; return; }}bool WvDialer::check_attempts_exceeded(int no_of_attempts)/********************************************************/{ if(no_of_attempts > options.dial_attempts) { log( WvLog::Warning, "Maximum Attempts Exceeded..Aborting!!\n" ); return true; } else { return false; }}static int set_echo( int desc, int value )/****************************************/{ struct termios settings; if( isatty( desc ) != 1 ) return 0; if( tcgetattr (desc, &settings) < 0 ) { perror ("error in tcgetattr"); return 0; } if( value ) settings.c_lflag |= ECHO; else settings.c_lflag &= ~ECHO; if( tcsetattr (desc, TCSANOW, &settings) < 0 ) { perror ("error in tcgetattr"); return 0; } return 1;}int WvDialer::ask_password()/**************************/{ char tmp[60]; log("Please enter password (or empty password to stop):\n" ); // fflush( stdout ); // kinternet needs this - WvLog should do it // automagically // set_echo( STDOUT_FILENO, 0 ); fgets( tmp, 50, stdin ); set_echo( STDOUT_FILENO, 1 ); if( tmp[ strlen(tmp)-1 ] == '\n' ) tmp[ strlen(tmp)-1 ] = '\0'; options.password = tmp; return 1;}void WvDialer::start_ppp()/************************/{ if( chat_mode ) exit(0); // pppd is already started... WvString addr_colon( "%s:", options.force_addr ); WvString speed( options.baud ); WvString idle_seconds( options.idle_seconds ); const char *dev_str = (const char *)options.modem; if (!(strncmp(options.modem, "/dev/", 5))) dev_str += 5; // open a pipe to access the messages of pppd if( pipe( pppd_msgfd ) == -1 ) { err("pipe failed: %s\n", strerror(errno) ); exit( EXIT_FAILURE ); } pppd_log = new WvFDStream( pppd_msgfd[0] ); WvString buffer1("%s", pppd_msgfd[1] ); // open a pipe to pass password to pppd WvString buffer2; if (!options.password) { if( pipe( pppd_passwdfd ) == -1 ) { err("pipe failed: %s\n", strerror(errno) ); exit( EXIT_FAILURE ); } ::write( pppd_passwdfd[1], (const char *) options.password, options.password.len() ); ::close( pppd_passwdfd[1] ); buffer2.append("%s", pppd_passwdfd[0] ); } char const *argv_raw[] = { options.where_pppd, speed, "modem", "crtscts", "defaultroute", "usehostname", "-detach", "user", options.login, (!!options.force_addr) ? (const char *)addr_colon : "noipdefault", options.new_pppd ? "call" : NULL, options.new_pppd ? "wvdial" : NULL, options.new_pppd && options.auto_dns ? "usepeerdns" : NULL, options.new_pppd && options.isdn ? "default-asyncmap" : NULL, options.new_pppd && (!!options.pppd_option) ? (const char *) options.pppd_option : NULL, options.new_pppd && options.idle_seconds >= 0 ? "idle" : NULL, options.new_pppd && options.idle_seconds >= 0 ? (const char *)idle_seconds : NULL, "logfd", buffer1,// !!buffer2 ? "passwordfd" : NULL, !!buffer2 ? (const char *)buffer2 : NULL, NULL }; /* Filter out NULL holes in the raw argv list: */ char * argv[sizeof(argv_raw)]; int argv_index = 0; for (unsigned int i = 0; i < sizeof(argv_raw)/sizeof(char *); i++) { if (argv_raw[i]) argv[argv_index++] = (char *)argv_raw[i]; } argv[argv_index] = NULL; if( access( options.where_pppd, X_OK ) != 0 ) { err( "Unable to run %s.\n", options.where_pppd ); err( "Check permissions, or specify a \"PPPD Path\" option " "in wvdial.conf.\n" ); return; } if (options.dialmessage1.len() || options.dialmessage2.len()) { log( WvLog::Notice, "\==========================================================================\n"); log( WvLog::Notice, "> %s\n", options.dialmessage1); if (options.dialmessage2.len()) log( WvLog::Notice, "> %s\n", options.dialmessage2); log( WvLog::Notice, "\==========================================================================\n"); if (options.homepage.len()) log( WvLog::Notice, "Homepage of %s: %s\n", options.provider.len() ? (const char *)options.provider : "this provider", options.homepage); } time_t now; time( &now ); log( WvLog::Notice, "Starting pppd at %s", ctime( &now ) ); // PP - Put this back in, since we're not using passwordfd unless we're // SuSE... how did this work without this? WvPapChap papchap; papchap.put_secret( options.login, options.password, options.remote ); if( papchap.isok_pap() == false ) { err( "Warning: Could not modify %s: %s\n" "--> PAP (Password Authentication Protocol) may be flaky.\n", PAP_SECRETS, strerror( errno ) ); } if( papchap.isok_chap() == false ) { err( "Warning: Could not modify %s: %s\n" "--> CHAP (Challenge Handshake) may be flaky.\n", CHAP_SECRETS, strerror( errno ) ); } ppp_pipe = new WvPipe( argv[0], argv, false, false, false, modem, modem, modem ); log( WvLog::Notice, "Pid of pppd: %s\n", ppp_pipe->getpid() ); stat = Online; been_online = true; connected_at = time( NULL );}void WvDialer::async_waitprompt()/*******************************/{ int received; const char *prompt_response; if( options.carrier_check == true ) { if( !modem || !modem->carrier() ) { err( "Connected, but carrier signal lost! Retrying...\n" ); stat = PreDial2; return; } } received = async_wait_for_modem( prompt_strings, false, true ); if( received >= 0 ) { // We have a PPP sequence! log( "PPP negotiation detected.\n" ); start_ppp(); } else if( received == -1 ) { // some milliseconds must have passed without receiving anything, // or async_wait_for_modem() would not have returned yet. // check to see if we are at a prompt. // Note: the buffer has been lowered by strlwr() already. prompt_response = brain->check_prompt( buffer ); if( prompt_response != NULL ) modem->print( "%s\r", prompt_response ); }}static void strip_parity( char * buf, size_t size )/*************************************************/// clear the parity bit on incoming data (to allow 7e1 connections){ while( size-- > 0 ) { *buf = *buf & 0x7f; buf++; }}int WvDialer::wait_for_modem( char * strs[], int timeout, bool neednewline, bool verbose )/***********************************************/{ off_t onset; char * soff; int result = -1; int len; const char *ppp_marker = NULL; while( modem->select( timeout, true, false ) ) { last_rx = time( NULL ); onset = offset; offset += modem->read( buffer + offset, INBUF_SIZE - offset ); // make sure we do not split lines TOO arbitrarily, or the // logs will look bad. while( offset < INBUF_SIZE && modem->select( 100, true, false ) ) offset += modem->read( buffer + offset, INBUF_SIZE - offset ); // Make sure there is a NULL on the end of the buffer. buffer[ offset ] = '\0'; // Now turn all the NULLs in the middle of the buffer to spaces, for // easier parsing. replace_char( buffer + onset, '\0', ' ', offset - onset ); strip_parity( buffer + onset, offset - onset ); replace_char( buffer + onset, '\0', ' ', offset - onset ); if( verbose ) modemrx.write( buffer + onset, offset - onset ); strlwr( buffer + onset ); // Now we can search using strstr. for( result = 0; strs[ result ] != NULL; result++ ) { len = strlen( strs[ result ] ); soff = strstr( buffer, strs[ result ] ); if( soff && ( !neednewline || strchr( soff, '\n' ) || strchr( soff, '\r' ) ) ) { memmove( buffer, soff + len, offset - (int)( soff+len - buffer ) ); offset -= (int)( soff+len - buffer ); break; } } if( strs[ result ] == NULL ) result = -1; // Search the buffer for a valid menu option... // If guess_menu returns an offset, we zap everything before it in // the buffer. This prevents finding the same menu option twice. ppp_marker = brain->guess_menu( buffer ); if (strs != dial_responses) { if( ppp_marker != NULL ) memset( buffer, ' ', ppp_marker-buffer ); } // Looks like we didn't find anything. Is the buffer full yet? if( offset == INBUF_SIZE ) { // yes, move the second half to the first half for next time. memmove( buffer, buffer + INBUF_SIZE/2, INBUF_SIZE - INBUF_SIZE/2 ); offset = INBUF_SIZE/2; } if( result != -1 ) break; } buffer[ offset ] = 0; return( result ); // -1 == timeout}int WvDialer::async_wait_for_modem( char * strs[], bool neednl, bool verbose )/****************************************************************************/{ return( wait_for_modem( strs, 10, neednl, verbose ) );}void WvDialer::reset_offset()/***************************/{ offset = 0; buffer[0] = '\0';}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -