|
|
|
/*
|
|
|
|
* kPPP: A pppd front end for the KDE project
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Copyright (C) 1997 Bernd Johannes Wuebben
|
|
|
|
* wuebben@math.cornell.edu
|
|
|
|
* Copyright (C) 1998-2001 Harri Porten <porten@kde.org>
|
|
|
|
*
|
|
|
|
* based on EzPPP:
|
|
|
|
* Copyright (C) 1997 Jay Painter
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library 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
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this program; if not, write to the Free
|
|
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <tdemessagebox.h>
|
|
|
|
#include <kpushbutton.h>
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <netdb.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#ifdef _XPG4_2
|
|
|
|
#define __xnet_connect connect
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_PARAM_H
|
|
|
|
#include <sys/param.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __linux__
|
|
|
|
#include "runtests.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "auth.h"
|
|
|
|
#include "connect.h"
|
|
|
|
#include "docking.h"
|
|
|
|
#include "main.h"
|
|
|
|
#include "modem.h"
|
|
|
|
#include "kpppconfig.h"
|
|
|
|
#include "pppdata.h"
|
|
|
|
#include "pppstats.h"
|
|
|
|
#include "requester.h"
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
extern KPPPWidget *p_kppp;
|
|
|
|
|
|
|
|
TQString old_hostname;
|
|
|
|
bool modified_hostname;
|
|
|
|
|
|
|
|
|
|
|
|
ConnectWidget::ConnectWidget(TQWidget *parent, const char *name, PPPStats *st)
|
|
|
|
: TQWidget(parent, name),
|
|
|
|
// initialize some important variables
|
|
|
|
myreadbuffer(""),
|
|
|
|
main_timer_ID(0),
|
|
|
|
vmain(0),
|
|
|
|
substate(-1),
|
|
|
|
scriptindex(0),
|
|
|
|
loopnest(0),
|
|
|
|
loopend(false),
|
|
|
|
semaphore(false),
|
|
|
|
expecting(false),
|
|
|
|
readbuffer(""),
|
|
|
|
scanvar(""),
|
|
|
|
scanning(false),
|
|
|
|
pausing(false),
|
|
|
|
termwindow(0),
|
|
|
|
dialnumber(0),
|
|
|
|
stats(st)
|
|
|
|
{
|
|
|
|
modified_hostname = false;
|
|
|
|
|
|
|
|
TQVBoxLayout *tl = new TQVBoxLayout(this, 8, 10);
|
|
|
|
TQString tit = i18n("Connecting to: ");
|
|
|
|
setCaption(tit);
|
|
|
|
|
|
|
|
TQHBoxLayout *l0 = new TQHBoxLayout(10);
|
|
|
|
tl->addLayout(l0);
|
|
|
|
l0->addSpacing(10);
|
|
|
|
messg = new TQLabel(this, "messg");
|
|
|
|
messg->setFrameStyle(TQFrame::Panel|TQFrame::Sunken);
|
|
|
|
messg->setAlignment(AlignCenter);
|
|
|
|
messg->setText(i18n("Unable to create modem lock file."));
|
|
|
|
messg->setMinimumHeight(messg->sizeHint().height() + 5);
|
|
|
|
int messw = (messg->sizeHint().width() * 12) / 10;
|
|
|
|
messw = TQMAX(messw,280);
|
|
|
|
messg->setMinimumWidth(messw);
|
|
|
|
messg->setText(i18n("Looking for modem..."));
|
|
|
|
l0->addWidget(messg);
|
|
|
|
l0->addSpacing(10);
|
|
|
|
|
|
|
|
TQHBoxLayout *l1 = new TQHBoxLayout(10);
|
|
|
|
tl->addLayout(l1);
|
|
|
|
l1->addStretch(1);
|
|
|
|
|
|
|
|
debug = new TQPushButton(i18n("&Log"), this);
|
|
|
|
debug->setToggleButton(true);
|
|
|
|
connect(debug, TQ_SIGNAL(clicked()), TQ_SIGNAL(toggleDebugWindow()));
|
|
|
|
|
|
|
|
cancel = new KPushButton(KStdGuiItem::cancel(), this);
|
|
|
|
cancel->setFocus();
|
|
|
|
connect(cancel, TQ_SIGNAL(clicked()), TQ_SLOT(cancelbutton()));
|
|
|
|
|
|
|
|
int maxw = TQMAX(cancel->sizeHint().width(),
|
|
|
|
debug->sizeHint().width());
|
|
|
|
maxw = TQMAX(maxw,65);
|
|
|
|
debug->setFixedWidth(maxw);
|
|
|
|
cancel->setFixedWidth(maxw);
|
|
|
|
l1->addWidget(debug);
|
|
|
|
l1->addWidget(cancel);
|
|
|
|
l1->addSpacing(10);
|
|
|
|
|
|
|
|
setFixedSize(sizeHint());
|
|
|
|
|
|
|
|
pausetimer = new TQTimer(this);
|
|
|
|
connect(pausetimer, TQ_SIGNAL(timeout()), TQ_SLOT(pause()));
|
|
|
|
|
|
|
|
kapp->processEvents();
|
|
|
|
|
|
|
|
timeout_timer = new TQTimer(this);
|
|
|
|
connect(timeout_timer, TQ_SIGNAL(timeout()), TQ_SLOT(script_timed_out()));
|
|
|
|
|
|
|
|
inittimer = new TQTimer(this);
|
|
|
|
connect(inittimer, TQ_SIGNAL(timeout()), TQ_SLOT(init()));
|
|
|
|
|
|
|
|
if_timeout_timer = new TQTimer(this);
|
|
|
|
connect(if_timeout_timer, TQ_SIGNAL(timeout()), TQ_SLOT(if_waiting_timed_out()));
|
|
|
|
|
|
|
|
connect(this,TQ_SIGNAL(if_waiting_signal()),this,TQ_SLOT(if_waiting_slot()));
|
|
|
|
|
|
|
|
prompt = new PWEntry( this, "pw" );
|
|
|
|
if_timer = new TQTimer(this);
|
|
|
|
connect(if_timer,TQ_SIGNAL(timeout()), TQ_SLOT(if_waiting_slot()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ConnectWidget::~ConnectWidget() {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::disableButtons()
|
|
|
|
{
|
|
|
|
debug->setEnabled(false);
|
|
|
|
cancel->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectWidget::enableButtons()
|
|
|
|
{
|
|
|
|
debug->setEnabled(true);
|
|
|
|
cancel->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectWidget::preinit() {
|
|
|
|
// this is all just to keep the GUI nice and snappy ....
|
|
|
|
// you have to see to believe ...
|
|
|
|
messg->setText(i18n("Looking for modem..."));
|
|
|
|
inittimer->start(100);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectWidget::init() {
|
|
|
|
gpppdata.setpppdError(0);
|
|
|
|
inittimer->stop();
|
|
|
|
vmain = 0;
|
|
|
|
substate = -1;
|
|
|
|
expecting = false;
|
|
|
|
pausing = false;
|
|
|
|
scriptindex = 0;
|
|
|
|
myreadbuffer = "";
|
|
|
|
scanning = false;
|
|
|
|
scanvar = "";
|
|
|
|
firstrunID = true;
|
|
|
|
firstrunPW = true;
|
|
|
|
stats->totalbytes = 0;
|
|
|
|
dialnumber = 0;
|
|
|
|
|
|
|
|
p_kppp->con_speed = "";
|
|
|
|
|
|
|
|
p_kppp->setQuitOnDisconnect (p_kppp->quitOnDisconnect() || gpppdata.quit_on_disconnect());
|
|
|
|
|
|
|
|
comlist = &gpppdata.scriptType();
|
|
|
|
arglist = &gpppdata.script();
|
|
|
|
|
|
|
|
TQString tit = i18n("Connecting to: %1").arg(gpppdata.accname());
|
|
|
|
setCaption(tit);
|
|
|
|
|
|
|
|
kapp->processEvents();
|
|
|
|
|
|
|
|
// signal other applications that we are about to get connected
|
|
|
|
kapp->dcopClient()->emitDCOPSignal("KpppIface", "aboutToConnect()", TQByteArray());
|
|
|
|
|
|
|
|
// run the "before-connect" command
|
|
|
|
if (!gpppdata.command_before_connect().isEmpty()) {
|
|
|
|
messg->setText(i18n("Running pre-startup command..."));
|
|
|
|
emit debugMessage(i18n("Running pre-startup command..."));
|
|
|
|
|
|
|
|
kapp->processEvents();
|
|
|
|
TQApplication::flushX();
|
|
|
|
pid_t id = execute_command(gpppdata.command_before_connect());
|
|
|
|
int i, status;
|
|
|
|
|
|
|
|
do {
|
|
|
|
kapp->processEvents();
|
|
|
|
i = waitpid(id, &status, WNOHANG);
|
|
|
|
usleep(100000);
|
|
|
|
} while (i == 0 && errno == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int lock = Modem::modem->lockdevice();
|
|
|
|
|
|
|
|
if (lock == 1) {
|
|
|
|
messg->setText(i18n("Modem device is locked."));
|
|
|
|
vmain = 20; // wait until cancel is pressed
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lock == -1) {
|
|
|
|
messg->setText(i18n("Unable to create modem lock file."));
|
|
|
|
vmain = 20; // wait until cancel is pressed
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Modem::modem->opentty()) {
|
|
|
|
messg->setText(Modem::modem->modemMessage());
|
|
|
|
kapp->processEvents();
|
|
|
|
if(Modem::modem->hangup()) {
|
|
|
|
|
|
|
|
kapp->processEvents();
|
|
|
|
|
|
|
|
semaphore = false;
|
|
|
|
|
|
|
|
Modem::modem->stop();
|
|
|
|
Modem::modem->notify(this, TQ_SLOT(readChar(unsigned char)));
|
|
|
|
|
|
|
|
// if we are stuck anywhere we will time out
|
|
|
|
timeout_timer->start(gpppdata.modemTimeout()*1000);
|
|
|
|
|
|
|
|
// this timer will run the script etc.
|
|
|
|
main_timer_ID = startTimer(10);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// initialization failed
|
|
|
|
messg->setText(Modem::modem->modemMessage());
|
|
|
|
vmain = 20; // wait until cancel is pressed
|
|
|
|
Modem::modem->unlockdevice();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::timerEvent(TQTimerEvent *) {
|
|
|
|
if (semaphore || pausing)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(vmain == 0) {
|
|
|
|
#ifdef DEBUG_WO_DIALING
|
|
|
|
vmain = 10;
|
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
assert(PPPData::NumInitStrings > 0);
|
|
|
|
// first init string ?
|
|
|
|
if(substate == -1) {
|
|
|
|
messg->setText(i18n("Initializing modem..."));
|
|
|
|
emit debugMessage(i18n("Initializing modem..."));
|
|
|
|
substate = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString initStr = gpppdata.modemInitStr(substate);
|
|
|
|
if (!initStr.isEmpty()) {
|
|
|
|
// send a carriage return and then wait a bit so that the modem will
|
|
|
|
// let us issue commands.
|
|
|
|
if(gpppdata.modemPreInitDelay() > 0) {
|
|
|
|
usleep(gpppdata.modemPreInitDelay() * 5000);
|
|
|
|
writeline("");
|
|
|
|
usleep(gpppdata.modemPreInitDelay() * 5000);
|
|
|
|
}
|
|
|
|
setExpect(gpppdata.modemInitResp());
|
|
|
|
writeline(initStr);
|
|
|
|
usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 sec
|
|
|
|
}
|
|
|
|
|
|
|
|
substate++;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FIXME after 3.0: Make it possible to disable ATS11 since it
|
|
|
|
* seems to be incompatible with some ISDN adapters (e.g. DataBox
|
|
|
|
* Speed Dragon). Even better would be to detect this when doing
|
|
|
|
* a "Modem Query"
|
|
|
|
*/
|
|
|
|
if (MODEM_TONEDURATION != gpppdata.modemToneDuration())
|
|
|
|
vmain = 5;
|
|
|
|
else
|
|
|
|
vmain = 3;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vmain == 5) {
|
|
|
|
if(!expecting) {
|
|
|
|
TQString sToneDuration = "ATS11=" + TQString::number(gpppdata.modemToneDuration());
|
|
|
|
TQString msg = i18n("Setting ") + sToneDuration;
|
|
|
|
messg->setText(msg);
|
|
|
|
emit debugMessage(msg);
|
|
|
|
setExpect(gpppdata.modemInitResp());
|
|
|
|
writeline(sToneDuration);
|
|
|
|
}
|
|
|
|
vmain = 3;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(vmain == 3) {
|
|
|
|
if(!expecting) {
|
|
|
|
// done with all init strings ?
|
|
|
|
if(substate < PPPData::NumInitStrings) {
|
|
|
|
vmain = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
substate = -1;
|
|
|
|
// skip setting the volume if command is empty
|
|
|
|
if(gpppdata.volumeInitString().isEmpty()) {
|
|
|
|
vmain = 4;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
messg->setText(i18n("Setting speaker volume..."));
|
|
|
|
emit debugMessage(i18n("Setting speaker volume..."));
|
|
|
|
|
|
|
|
setExpect(gpppdata.modemInitResp());
|
|
|
|
TQString vol("AT");
|
|
|
|
vol += gpppdata.volumeInitString();
|
|
|
|
writeline(vol);
|
|
|
|
usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 sec
|
|
|
|
vmain = 4;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(vmain == 4) {
|
|
|
|
if(!expecting) {
|
|
|
|
if(!gpppdata.waitForDialTone() || gpppdata.waitCallback()) {
|
|
|
|
TQString msg = i18n("Turning off dial tone waiting...");
|
|
|
|
messg->setText(msg);
|
|
|
|
emit debugMessage(msg);
|
|
|
|
setExpect(gpppdata.modemInitResp());
|
|
|
|
writeline(gpppdata.modemNoDialToneDetectionStr());
|
|
|
|
}
|
|
|
|
vmain = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// dial the number and wait to connect
|
|
|
|
if(vmain == 1) {
|
|
|
|
if(!expecting) {
|
|
|
|
|
|
|
|
timeout_timer->stop();
|
|
|
|
timeout_timer->start(gpppdata.modemTimeout()*1000);
|
|
|
|
|
|
|
|
if(gpppdata.waitCallback()) {
|
|
|
|
TQString msg = i18n("Waiting for callback...");
|
|
|
|
messg->setText(msg);
|
|
|
|
emit debugMessage(msg);
|
|
|
|
setExpect(gpppdata.modemRingResp());
|
|
|
|
vmain = 102;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList &plist = gpppdata.phonenumbers();
|
|
|
|
TQString bmarg= gpppdata.dialPrefix();
|
|
|
|
bmarg += *plist.at(dialnumber);
|
|
|
|
TQString bm = i18n("Dialing %1").arg(bmarg);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
TQString pn = gpppdata.modemDialStr();
|
|
|
|
pn += gpppdata.dialPrefix();
|
|
|
|
pn += *plist.at(dialnumber);
|
|
|
|
if(++dialnumber >= plist.count())
|
|
|
|
dialnumber = 0;
|
|
|
|
writeline(pn);
|
|
|
|
|
|
|
|
setExpect(gpppdata.modemConnectResp());
|
|
|
|
vmain = 100;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait for connect, but redial if BUSY or wait for user cancel
|
|
|
|
// if NO CARRIER or NO DIALTONE
|
|
|
|
if(vmain == 100) {
|
|
|
|
if(!expecting) {
|
|
|
|
myreadbuffer = gpppdata.modemConnectResp();
|
|
|
|
setExpect("\n");
|
|
|
|
vmain = 101;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(readbuffer.contains(gpppdata.modemBusyResp())) {
|
|
|
|
timeout_timer->stop();
|
|
|
|
timeout_timer->start(gpppdata.modemTimeout()*1000);
|
|
|
|
|
|
|
|
messg->setText(i18n("Line busy. Hanging up..."));
|
|
|
|
emit debugPutChar('\n');
|
|
|
|
Modem::modem->hangup();
|
|
|
|
|
|
|
|
if(gpppdata.busyWait() > 0) {
|
|
|
|
TQString bm = i18n("Line busy. Waiting: %1 seconds").arg(gpppdata.busyWait());
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
pausing = true;
|
|
|
|
|
|
|
|
pausetimer->start(gpppdata.busyWait()*1000, true);
|
|
|
|
timeout_timer->stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
Modem::modem->setDataMode(false);
|
|
|
|
vmain = 0;
|
|
|
|
substate = -1;
|
|
|
|
gpppdata.setWaitCallback(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(readbuffer.contains(gpppdata.modemNoDialtoneResp())) {
|
|
|
|
timeout_timer->stop();
|
|
|
|
|
|
|
|
messg->setText(i18n("No Dial Tone"));
|
|
|
|
vmain = 20;
|
|
|
|
Modem::modem->unlockdevice();
|
|
|
|
gpppdata.setWaitCallback(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(readbuffer.contains(gpppdata.modemNoCarrierResp())) {
|
|
|
|
if (gpppdata.get_redial_on_nocarrier()) {
|
|
|
|
timeout_timer->stop();
|
|
|
|
timeout_timer->start(gpppdata.modemTimeout()*1000);
|
|
|
|
|
|
|
|
if(gpppdata.busyWait() > 0) {
|
|
|
|
TQString bm = i18n("No carrier. Waiting: %1 seconds").arg(gpppdata.busyWait());
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
pausing = true;
|
|
|
|
|
|
|
|
pausetimer->start(gpppdata.busyWait()*1000, true);
|
|
|
|
timeout_timer->stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
Modem::modem->setDataMode(false);
|
|
|
|
vmain = 0;
|
|
|
|
substate = -1;
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
timeout_timer->stop();
|
|
|
|
|
|
|
|
messg->setText(i18n("No Carrier"));
|
|
|
|
vmain = 20;
|
|
|
|
Modem::modem->unlockdevice();
|
|
|
|
gpppdata.setWaitCallback(false);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(readbuffer.contains(gpppdata.modemDLPResp())) {
|
|
|
|
timeout_timer->stop();
|
|
|
|
|
|
|
|
messg->setText(i18n("Digital Line Protection Detected."));
|
|
|
|
vmain = 20;
|
|
|
|
Modem::modem->unlockdevice();
|
|
|
|
KMessageBox::error(this,
|
|
|
|
i18n("A Digital Line Protection (DLP) error response "
|
|
|
|
"has been detected.\n"
|
|
|
|
"Please disconnect the phone line.\n\n"
|
|
|
|
"Do NOT connect this modem to a digital phone "
|
|
|
|
"line or the modem could get permanently "
|
|
|
|
"damaged"));
|
|
|
|
gpppdata.setWaitCallback(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait for newline after CONNECT response (so we get the speed)
|
|
|
|
if(vmain == 101) {
|
|
|
|
if(!expecting) {
|
|
|
|
Modem::modem->setDataMode(true); // modem will no longer respond to AT commands
|
|
|
|
|
|
|
|
emit startAccounting();
|
|
|
|
p_kppp->con_win->startClock();
|
|
|
|
|
|
|
|
vmain = 2;
|
|
|
|
scriptTimeout=gpppdata.modemTimeout()*1000;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// send answer on callback phase
|
|
|
|
if(vmain == 102) {
|
|
|
|
if(!expecting) {
|
|
|
|
writeline(gpppdata.modemAnswerStr());
|
|
|
|
setExpect(gpppdata.modemConnectResp());
|
|
|
|
vmain = 100;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// execute the script
|
|
|
|
if(vmain == 2) {
|
|
|
|
if(!expecting && !pausing && !scanning) {
|
|
|
|
|
|
|
|
timeout_timer->stop();
|
|
|
|
timeout_timer->start(scriptTimeout);
|
|
|
|
|
|
|
|
if((unsigned) scriptindex < comlist->count()) {
|
|
|
|
scriptCommand = *(comlist->at(scriptindex));
|
|
|
|
scriptArgument = *(arglist->at(scriptindex));
|
|
|
|
} else {
|
|
|
|
kdDebug(5002) << "End of script" << endl;
|
|
|
|
vmain = 10;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "Scan") {
|
|
|
|
TQString bm = i18n("Scanning %1").arg(scriptArgument);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
setScan(scriptArgument);
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "Save") {
|
|
|
|
TQString bm = i18n("Saving %1").arg(scriptArgument);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
if (scriptArgument.lower() == "password") {
|
|
|
|
gpppdata.setPassword(scanvar);
|
|
|
|
p_kppp->setPW_Edit(scanvar);
|
|
|
|
if(gpppdata.storePassword())
|
|
|
|
gpppdata.setStoredPassword(scanvar);
|
|
|
|
firstrunPW = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (scriptCommand == "Send" || scriptCommand == "SendNoEcho") {
|
|
|
|
TQString bm = i18n("Sending %1");
|
|
|
|
|
|
|
|
// replace %USERNAME% and %PASSWORD%
|
|
|
|
TQString arg = scriptArgument;
|
|
|
|
TQRegExp re1("%USERNAME%");
|
|
|
|
TQRegExp re2("%PASSWORD%");
|
|
|
|
arg = arg.replace(re1, gpppdata.storedUsername());
|
|
|
|
arg = arg.replace(re2, gpppdata.storedPassword());
|
|
|
|
|
|
|
|
if (scriptCommand == "Send")
|
|
|
|
bm = bm.arg(scriptArgument);
|
|
|
|
else {
|
|
|
|
for(uint i = 0; i < scriptArgument.length(); i++)
|
|
|
|
bm = bm.arg("*");
|
|
|
|
}
|
|
|
|
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
writeline(scriptArgument);
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "Expect") {
|
|
|
|
TQString bm = i18n("Expecting %1").arg(scriptArgument);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
// The incrementing of the scriptindex MUST be before the
|
|
|
|
// call to setExpect otherwise the expect will miss a string that is
|
|
|
|
// already in the buffer.
|
|
|
|
scriptindex++;
|
|
|
|
setExpect(scriptArgument);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (scriptCommand == "Pause") {
|
|
|
|
TQString bm = i18n("Pause %1 seconds").arg(scriptArgument);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
pausing = true;
|
|
|
|
|
|
|
|
pausetimer->start(scriptArgument.toInt()*1000, true);
|
|
|
|
timeout_timer->stop();
|
|
|
|
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "Timeout") {
|
|
|
|
|
|
|
|
timeout_timer->stop();
|
|
|
|
|
|
|
|
TQString bm = i18n("Timeout %1 seconds").arg(scriptArgument);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
scriptTimeout=scriptArgument.toInt()*1000;
|
|
|
|
timeout_timer->start(scriptTimeout);
|
|
|
|
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "Hangup") {
|
|
|
|
messg->setText(i18n("Hangup"));
|
|
|
|
emit debugMessage(i18n("Hangup"));
|
|
|
|
|
|
|
|
writeline(gpppdata.modemHangupStr());
|
|
|
|
setExpect(gpppdata.modemHangupResp());
|
|
|
|
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "Answer") {
|
|
|
|
|
|
|
|
timeout_timer->stop();
|
|
|
|
|
|
|
|
messg->setText(i18n("Answer"));
|
|
|
|
emit debugMessage(i18n("Answer"));
|
|
|
|
|
|
|
|
setExpect(gpppdata.modemRingResp());
|
|
|
|
vmain = 150;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "ID") {
|
|
|
|
TQString bm = i18n("ID %1").arg(scriptArgument);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
TQString idstring = gpppdata.storedUsername();
|
|
|
|
|
|
|
|
if(!idstring.isEmpty() && firstrunID) {
|
|
|
|
// the user entered an Id on the main kppp dialog
|
|
|
|
writeline(idstring);
|
|
|
|
firstrunID = false;
|
|
|
|
scriptindex++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// the user didn't enter and Id on the main kppp dialog
|
|
|
|
// let's query for an ID
|
|
|
|
/* if not around yet, then post window... */
|
|
|
|
if (prompt->Consumed()) {
|
|
|
|
if (!(prompt->isVisible())) {
|
|
|
|
prompt->setPrompt(scriptArgument);
|
|
|
|
prompt->setEchoModeNormal();
|
|
|
|
prompt->show();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* if prompt withdrawn ... then, */
|
|
|
|
if(!(prompt->isVisible())) {
|
|
|
|
writeline(prompt->text());
|
|
|
|
prompt->setConsumed();
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* replace timeout value */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "Password") {
|
|
|
|
TQString bm = i18n("Password %1").arg(scriptArgument);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
TQString pwstring = gpppdata.password();
|
|
|
|
|
|
|
|
if(!pwstring.isEmpty() && firstrunPW) {
|
|
|
|
// the user entered a password on the main kppp dialog
|
|
|
|
writeline(pwstring);
|
|
|
|
firstrunPW = false;
|
|
|
|
scriptindex++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// the user didn't enter a password on the main kppp dialog
|
|
|
|
// let's query for a password
|
|
|
|
/* if not around yet, then post window... */
|
|
|
|
if (prompt->Consumed()) {
|
|
|
|
if (!(prompt->isVisible())) {
|
|
|
|
prompt->setPrompt(scriptArgument);
|
|
|
|
prompt->setEchoModePassword();
|
|
|
|
prompt->show();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* if prompt withdrawn ... then, */
|
|
|
|
if(!(prompt->isVisible())) {
|
|
|
|
p_kppp->setPW_Edit(prompt->text());
|
|
|
|
writeline(prompt->text());
|
|
|
|
prompt->setConsumed();
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* replace timeout value */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "Prompt") {
|
|
|
|
TQString bm = i18n("Prompting %1");
|
|
|
|
|
|
|
|
// if the scriptindex (aka the prompt text) includes a ## marker
|
|
|
|
// this marker should get substituted with the contents of our stored
|
|
|
|
// variable (from the subsequent scan).
|
|
|
|
|
|
|
|
TQString ts = scriptArgument;
|
|
|
|
int vstart = ts.find( "##" );
|
|
|
|
if( vstart != -1 ) {
|
|
|
|
ts.remove( vstart, 2 );
|
|
|
|
ts.insert( vstart, scanvar );
|
|
|
|
}
|
|
|
|
|
|
|
|
bm = bm.arg(ts);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
/* if not around yet, then post window... */
|
|
|
|
if (prompt->Consumed()) {
|
|
|
|
if (!(prompt->isVisible())) {
|
|
|
|
prompt->setPrompt( ts );
|
|
|
|
prompt->setEchoModeNormal();
|
|
|
|
prompt->show();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* if prompt withdrawn ... then, */
|
|
|
|
if (!(prompt->isVisible())) {
|
|
|
|
writeline(prompt->text());
|
|
|
|
prompt->setConsumed();
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* replace timeout value */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "PWPrompt") {
|
|
|
|
TQString bm = i18n("PW Prompt %1").arg(scriptArgument);
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
/* if not around yet, then post window... */
|
|
|
|
if (prompt->Consumed()) {
|
|
|
|
if (!(prompt->isVisible())) {
|
|
|
|
prompt->setPrompt(scriptArgument);
|
|
|
|
prompt->setEchoModePassword();
|
|
|
|
prompt->show();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* if prompt withdrawn ... then, */
|
|
|
|
if (!(prompt->isVisible())) {
|
|
|
|
writeline(prompt->text());
|
|
|
|
prompt->setConsumed();
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* replace timeout value */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "LoopStart") {
|
|
|
|
|
|
|
|
TQString bm = i18n("Loop Start %1").arg(scriptArgument);
|
|
|
|
|
|
|
|
// The incrementing of the scriptindex MUST be before the
|
|
|
|
// call to setExpect otherwise the expect will miss a string that is
|
|
|
|
// already in the buffer.
|
|
|
|
scriptindex++;
|
|
|
|
|
|
|
|
if ( loopnest > (MAXLOOPNEST-2) ) {
|
|
|
|
bm += i18n("ERROR: Nested too deep, ignored.");
|
|
|
|
vmain=20;
|
|
|
|
cancelbutton();
|
|
|
|
KMessageBox::error(0, i18n("Loops nested too deeply."));
|
|
|
|
} else {
|
|
|
|
setExpect(scriptArgument);
|
|
|
|
loopstartindex[loopnest] = scriptindex;
|
|
|
|
loopstr[loopnest] = scriptArgument;
|
|
|
|
loopend = false;
|
|
|
|
loopnest++;
|
|
|
|
}
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scriptCommand == "LoopEnd") {
|
|
|
|
TQString bm = i18n("Loop End %1").arg(scriptArgument);
|
|
|
|
if ( loopnest <= 0 ) {
|
|
|
|
bm = i18n("LoopEnd without matching Start. Line: %1").arg(bm);
|
|
|
|
vmain=20;
|
|
|
|
cancelbutton();
|
|
|
|
KMessageBox::error(0, bm);
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
// NB! The incrementing of the scriptindex MUST be before the
|
|
|
|
// call to setExpect otherwise the expect will miss a string
|
|
|
|
// that is already in the buffer.
|
|
|
|
scriptindex++;
|
|
|
|
setExpect(scriptArgument);
|
|
|
|
loopnest--;
|
|
|
|
loopend = true;
|
|
|
|
}
|
|
|
|
messg->setText(bm);
|
|
|
|
emit debugMessage(bm);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// this is a subroutine for the "Answer" script option
|
|
|
|
|
|
|
|
if(vmain == 150) {
|
|
|
|
if(!expecting) {
|
|
|
|
writeline(gpppdata.modemAnswerStr());
|
|
|
|
setExpect(gpppdata.modemAnswerResp());
|
|
|
|
|
|
|
|
vmain = 2;
|
|
|
|
scriptindex++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(vmain == 30) {
|
|
|
|
if (termwindow->isVisible())
|
|
|
|
return;
|
|
|
|
if (termwindow->pressedContinue())
|
|
|
|
vmain = 10;
|
|
|
|
else
|
|
|
|
cancelbutton();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(vmain == 10) {
|
|
|
|
if(!expecting) {
|
|
|
|
|
|
|
|
int result;
|
|
|
|
|
|
|
|
timeout_timer->stop();
|
|
|
|
if_timeout_timer->stop(); // better be sure.
|
|
|
|
|
|
|
|
// stop reading of data
|
|
|
|
Modem::modem->stop();
|
|
|
|
|
|
|
|
if(gpppdata.authMethod() == AUTH_TERMINAL) {
|
|
|
|
if (termwindow) {
|
|
|
|
delete termwindow;
|
|
|
|
termwindow = 0L;
|
|
|
|
show();
|
|
|
|
} else {
|
|
|
|
termwindow = new LoginTerm(0L, 0L);
|
|
|
|
hide();
|
|
|
|
termwindow->show();
|
|
|
|
vmain = 30;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close the tty. This prevents the TQTimer::singleShot() in
|
|
|
|
// Modem::readtty() from re-enabling the socket notifier.
|
|
|
|
// The port is still held open by the helper process.
|
|
|
|
Modem::modem->closetty();
|
|
|
|
|
|
|
|
killTimer( main_timer_ID );
|
|
|
|
|
|
|
|
if_timeout_timer->start(gpppdata.pppdTimeout()*1000);
|
|
|
|
kdDebug(5002) << "started if timeout timer with " << gpppdata.pppdTimeout()*1000 << endl;
|
|
|
|
|
|
|
|
// find out PPP interface and notify the stats module
|
|
|
|
stats->setUnit(pppInterfaceNumber());
|
|
|
|
|
|
|
|
kapp->flushX();
|
|
|
|
semaphore = true;
|
|
|
|
result = execppp();
|
|
|
|
|
|
|
|
emit debugMessage(i18n("Starting pppd..."));
|
|
|
|
kdDebug(5002) << "execppp() returned with return-code " << result << endl;
|
|
|
|
|
|
|
|
if(result) {
|
|
|
|
if(!gpppdata.autoDNS())
|
|
|
|
adddns();
|
|
|
|
|
|
|
|
// O.K we are done here, let's change over to the if_waiting loop
|
|
|
|
// where we wait for the ppp if (interface) to come up.
|
|
|
|
|
|
|
|
emit if_waiting_signal();
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// starting pppd wasn't successful. Error messages were
|
|
|
|
// handled by execppp();
|
|
|
|
if_timeout_timer->stop();
|
|
|
|
|
|
|
|
hide();
|
|
|
|
messg->setText("");
|
|
|
|
p_kppp->quit_b->setFocus();
|
|
|
|
p_kppp->show();
|
|
|
|
kapp->processEvents();
|
|
|
|
Modem::modem->hangup();
|
|
|
|
emit stopAccounting();
|
|
|
|
p_kppp->con_win->stopClock();
|
|
|
|
Modem::modem->closetty();
|
|
|
|
Modem::modem->unlockdevice();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// this is a "wait until cancel" entry
|
|
|
|
|
|
|
|
if(vmain == 20) {
|
|
|
|
gpppdata.setWaitCallback(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::set_con_speed_string() {
|
|
|
|
// Here we are trying to determine the speed at which we are connected.
|
|
|
|
// Usually the modem responds after connect with something like
|
|
|
|
// CONNECT 115200, so all we need to do is find the number after CONNECT
|
|
|
|
// or whatever the modemConnectResp() is.
|
|
|
|
p_kppp->con_speed = Modem::modem->parseModemSpeed(myreadbuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::readChar(unsigned char c) {
|
|
|
|
if(semaphore)
|
|
|
|
return;
|
|
|
|
|
|
|
|
readbuffer += c;
|
|
|
|
myreadbuffer += c;
|
|
|
|
|
|
|
|
// While in scanning mode store each char to the scan buffer
|
|
|
|
// for use in the prompt command
|
|
|
|
if( scanning )
|
|
|
|
scanbuffer += c;
|
|
|
|
|
|
|
|
// add to debug window
|
|
|
|
emit debugPutChar(c);
|
|
|
|
|
|
|
|
checkBuffers();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::checkBuffers() {
|
|
|
|
// Let's check if we are finished with scanning:
|
|
|
|
// The scanstring have to be in the buffer and the latest character
|
|
|
|
// was a carriage return or an linefeed (depending on modem setup)
|
|
|
|
if( scanning && scanbuffer.contains(scanstr) &&
|
|
|
|
( scanbuffer.right(1) == "\n" || scanbuffer.right(1) == "\r") ) {
|
|
|
|
scanning = false;
|
|
|
|
|
|
|
|
int vstart = scanbuffer.find( scanstr ) + scanstr.length();
|
|
|
|
scanvar = scanbuffer.mid( vstart, scanbuffer.length() - vstart);
|
|
|
|
scanvar = scanvar.stripWhiteSpace();
|
|
|
|
|
|
|
|
// Show the Variabel content in the debug window
|
|
|
|
TQString sv = i18n("Scan Var: %1").arg(scanvar);
|
|
|
|
emit debugMessage(sv);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(expecting) {
|
|
|
|
if(readbuffer.contains(expectstr)) {
|
|
|
|
expecting = false;
|
|
|
|
// keep everything after the expected string
|
|
|
|
readbuffer.remove(0, readbuffer.find(expectstr) + expectstr.length());
|
|
|
|
|
|
|
|
TQString ts = i18n("Found: %1").arg(expectstr);
|
|
|
|
emit debugMessage(ts);
|
|
|
|
|
|
|
|
if (loopend) {
|
|
|
|
loopend=false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (loopend && readbuffer.contains(loopstr[loopnest])) {
|
|
|
|
expecting = false;
|
|
|
|
readbuffer = "";
|
|
|
|
TQString ts = i18n("Looping: %1").arg(loopstr[loopnest]);
|
|
|
|
emit debugMessage(ts);
|
|
|
|
scriptindex = loopstartindex[loopnest];
|
|
|
|
loopend = false;
|
|
|
|
loopnest++;
|
|
|
|
}
|
|
|
|
// notify event loop if expected string was found
|
|
|
|
if(!expecting)
|
|
|
|
timerEvent((TQTimerEvent *) 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::pause() {
|
|
|
|
pausing = false;
|
|
|
|
pausetimer->stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::cancelbutton() {
|
|
|
|
gpppdata.setWaitCallback(false);
|
|
|
|
Modem::modem->stop();
|
|
|
|
killTimer(main_timer_ID);
|
|
|
|
timeout_timer->stop();
|
|
|
|
if_timer->stop();
|
|
|
|
if_timeout_timer->stop();
|
|
|
|
|
|
|
|
if (termwindow) {
|
|
|
|
delete termwindow;
|
|
|
|
termwindow = 0L;
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
|
|
|
messg->setText(i18n("One moment please..."));
|
|
|
|
|
|
|
|
// just to be sure
|
|
|
|
Requester::rq->removeSecret(AUTH_PAP);
|
|
|
|
Requester::rq->removeSecret(AUTH_CHAP);
|
|
|
|
removedns();
|
|
|
|
|
|
|
|
kapp->processEvents();
|
|
|
|
|
|
|
|
Requester::rq->killPPPDaemon();
|
|
|
|
Modem::modem->hangup();
|
|
|
|
|
|
|
|
hide();
|
|
|
|
messg->setText("");
|
|
|
|
p_kppp->quit_b->setFocus();
|
|
|
|
p_kppp->show();
|
|
|
|
emit stopAccounting(); // just to be sure
|
|
|
|
p_kppp->con_win->stopClock();
|
|
|
|
Modem::modem->closetty();
|
|
|
|
Modem::modem->unlockdevice();
|
|
|
|
|
|
|
|
//abort prompt window...
|
|
|
|
if (prompt->isVisible()) {
|
|
|
|
prompt->hide();
|
|
|
|
}
|
|
|
|
prompt->setConsumed();
|
|
|
|
|
|
|
|
if(p_kppp->quitOnDisconnect())
|
|
|
|
kapp->exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::script_timed_out() {
|
|
|
|
if(vmain == 20) { // we are in the 'wait for the user to cancel' state
|
|
|
|
timeout_timer->stop();
|
|
|
|
emit stopAccounting();
|
|
|
|
p_kppp->con_win->stopClock();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prompt->isVisible())
|
|
|
|
prompt->hide();
|
|
|
|
|
|
|
|
prompt->setConsumed();
|
|
|
|
messg->setText(i18n("Script timed out."));
|
|
|
|
Modem::modem->hangup();
|
|
|
|
emit stopAccounting();
|
|
|
|
p_kppp->con_win->stopClock();
|
|
|
|
|
|
|
|
vmain = 0; // let's try again.
|
|
|
|
substate = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::setScan(const TQString &n) {
|
|
|
|
scanning = true;
|
|
|
|
scanstr = n;
|
|
|
|
scanbuffer = "";
|
|
|
|
|
|
|
|
TQString ts = i18n("Scanning: %1").arg(n);
|
|
|
|
emit debugMessage(ts);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::setExpect(const TQString &n) {
|
|
|
|
expecting = true;
|
|
|
|
expectstr = n;
|
|
|
|
|
|
|
|
TQString ts = i18n("Expecting: %1").arg(n);
|
|
|
|
ts.replace(TQRegExp("\n"), "<LF>");
|
|
|
|
emit debugMessage(ts);
|
|
|
|
|
|
|
|
// check if the expected string is in the read buffer already.
|
|
|
|
checkBuffers();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::if_waiting_timed_out() {
|
|
|
|
if_timer->stop();
|
|
|
|
if_timeout_timer->stop();
|
|
|
|
kdDebug(5002) << "if_waiting_timed_out()" << endl;
|
|
|
|
|
|
|
|
gpppdata.setpppdError(E_IF_TIMEOUT);
|
|
|
|
|
|
|
|
// let's kill the stuck pppd
|
|
|
|
Requester::rq->killPPPDaemon();
|
|
|
|
|
|
|
|
emit stopAccounting();
|
|
|
|
p_kppp->con_win->stopClock();
|
|
|
|
|
|
|
|
|
|
|
|
// killing ppp will generate a SIGCHLD which will be caught in pppdie()
|
|
|
|
// in main.cpp what happens next will depend on the boolean
|
|
|
|
// reconnect_on_disconnect which is set in ConnectWidget::init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectWidget::pppdDied()
|
|
|
|
{
|
|
|
|
if_timer->stop();
|
|
|
|
if_timeout_timer->stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectWidget::if_waiting_slot() {
|
|
|
|
messg->setText(i18n("Logging on to network..."));
|
|
|
|
|
|
|
|
if(!stats->ifIsUp()) {
|
|
|
|
|
|
|
|
if(gpppdata.pppdError() != 0) {
|
|
|
|
// we are here if pppd died immediately after starting it.
|
|
|
|
pppdDied();
|
|
|
|
// error message handled in main.cpp: sigPPPDDied()
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if_timer->start(100, TRUE); // single shot
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// O.K the ppp interface is up and running
|
|
|
|
// give it a few time to come up completly (0.2 seconds)
|
|
|
|
if_timeout_timer->stop();
|
|
|
|
if_timer->stop();
|
|
|
|
usleep(200000);
|
|
|
|
|
|
|
|
if(gpppdata.autoDNS())
|
|
|
|
addpeerdns();
|
|
|
|
|
|
|
|
// Close the debugging window. If we are connected, we
|
|
|
|
// are not really interested in debug output
|
|
|
|
emit closeDebugWindow();
|
|
|
|
p_kppp->statdlg->take_stats(); // start taking ppp statistics
|
|
|
|
auto_hostname();
|
|
|
|
|
|
|
|
// signal other applications that we are connected now
|
|
|
|
kapp->dcopClient()->emitDCOPSignal("KpppIface", "connected()", TQByteArray());
|
|
|
|
|
|
|
|
if(!gpppdata.command_on_connect().isEmpty()) {
|
|
|
|
messg->setText(i18n("Running startup command..."));
|
|
|
|
|
|
|
|
// make sure that we don't get any async errors
|
|
|
|
kapp->flushX();
|
|
|
|
execute_command(gpppdata.command_on_connect());
|
|
|
|
messg->setText(i18n("Done"));
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove the authentication file
|
|
|
|
Requester::rq->removeSecret(AUTH_PAP);
|
|
|
|
Requester::rq->removeSecret(AUTH_CHAP);
|
|
|
|
|
|
|
|
emit debugMessage(i18n("Done"));
|
|
|
|
set_con_speed_string();
|
|
|
|
|
|
|
|
p_kppp->con_win->setConnectionSpeed(p_kppp->con_speed);
|
|
|
|
hide();
|
|
|
|
messg->setText("");
|
|
|
|
|
|
|
|
// prepare the con_win so as to have the right size for
|
|
|
|
// accounting / non-accounting mode
|
|
|
|
if(p_kppp->acct != 0)
|
|
|
|
p_kppp->con_win->accounting(p_kppp->acct->running());
|
|
|
|
else
|
|
|
|
p_kppp->con_win->accounting(false);
|
|
|
|
|
|
|
|
if (gpppdata.get_dock_into_panel()) {
|
|
|
|
DockWidget::dock_widget->show();
|
|
|
|
DockWidget::dock_widget->take_stats();
|
|
|
|
hide();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
p_kppp->con_win->show();
|
|
|
|
|
|
|
|
if(gpppdata.get_iconify_on_connect()) {
|
|
|
|
p_kppp->con_win->showMinimized();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Modem::modem->closetty();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool ConnectWidget::execppp() {
|
|
|
|
TQString command;
|
|
|
|
|
|
|
|
command = "pppd";
|
|
|
|
|
|
|
|
// as of version 2.3.6 pppd falls back to the real user rights when
|
|
|
|
// opening a device given in a command line. To avoid permission conflicts
|
|
|
|
// we'll simply leave this argument away. pppd will then use the default tty
|
|
|
|
// which is the serial port we connected stdin/stdout to in opener.cpp.
|
|
|
|
// command += " ";
|
|
|
|
// command += gpppdata.modemDevice();
|
|
|
|
|
|
|
|
command += " " + gpppdata.speed();
|
|
|
|
|
|
|
|
command += " -detach";
|
|
|
|
command += " call kppp-options";
|
|
|
|
|
|
|
|
if(gpppdata.ipaddr() != "0.0.0.0" ||
|
|
|
|
gpppdata.gateway() != "0.0.0.0") {
|
|
|
|
if(gpppdata.ipaddr() != "0.0.0.0") {
|
|
|
|
command += " ";
|
|
|
|
command += gpppdata.ipaddr();
|
|
|
|
command += ":";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
command += " ";
|
|
|
|
command += ":";
|
|
|
|
}
|
|
|
|
|
|
|
|
if(gpppdata.gateway() != "0.0.0.0")
|
|
|
|
command += gpppdata.gateway();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(gpppdata.subnetmask() != "0.0.0.0")
|
|
|
|
command += " netmask " + gpppdata.subnetmask();
|
|
|
|
|
|
|
|
// the english/i18n mix below is ugly but we want to keep working
|
|
|
|
// after someone changed the code to use i18n'ed config values
|
|
|
|
TQString flowCtrl = gpppdata.flowcontrol();
|
|
|
|
if(flowCtrl != "None" && flowCtrl != i18n("None")) {
|
|
|
|
if(flowCtrl == "CRTSCTS" || flowCtrl == "Hardware [CRTSCTS]" ||
|
|
|
|
flowCtrl == i18n("Hardware [CRTSCTS]"))
|
|
|
|
command += " crtscts";
|
|
|
|
else
|
|
|
|
command += " xonxoff";
|
|
|
|
}
|
|
|
|
|
|
|
|
if(gpppdata.defaultroute())
|
|
|
|
command += " defaultroute";
|
|
|
|
|
|
|
|
if(gpppdata.autoDNS())
|
|
|
|
command += " usepeerdns";
|
|
|
|
|
|
|
|
TQStringList &arglist = gpppdata.pppdArgument();
|
|
|
|
for ( TQStringList::Iterator it = arglist.begin();
|
|
|
|
it != arglist.end();
|
|
|
|
++it )
|
|
|
|
{
|
|
|
|
command += " " + *it;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Callback settings
|
|
|
|
if(gpppdata.callbackType() && !gpppdata.waitCallback()) {
|
|
|
|
if(!gpppdata.pppdVersionMin(2, 4, 2)) {
|
|
|
|
command += " +callback";
|
|
|
|
if(gpppdata.callbackType() == CBTYPE_USER)
|
|
|
|
command += " callback " + gpppdata.callbackPhone();
|
|
|
|
} else {
|
|
|
|
command += " callback ";
|
|
|
|
command += gpppdata.callbackType() == CBTYPE_ADMIN ?
|
|
|
|
TQString("0") : gpppdata.callbackPhone();
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
gpppdata.setWaitCallback(false);
|
|
|
|
|
|
|
|
// PAP settings
|
|
|
|
if(gpppdata.authMethod() == AUTH_PAP) {
|
|
|
|
command += " -chap user ";
|
|
|
|
command = command + "\"" + gpppdata.storedUsername() + "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHAP settings
|
|
|
|
if(gpppdata.authMethod() == AUTH_CHAP) {
|
|
|
|
command += " -pap user ";
|
|
|
|
command = command + "\"" + gpppdata.storedUsername() + "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
// PAP/CHAP settings
|
|
|
|
if(gpppdata.authMethod() == AUTH_PAPCHAP) {
|
|
|
|
command += " user ";
|
|
|
|
command = command + "\"" + gpppdata.storedUsername() + "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
// check for debug
|
|
|
|
if(gpppdata.getPPPDebug())
|
|
|
|
command += " debug";
|
|
|
|
|
|
|
|
if (command.length() > MAX_CMDLEN) {
|
|
|
|
KMessageBox::error(this, i18n(
|
|
|
|
"pppd command + command-line arguments exceed "
|
|
|
|
"2024 characters in length."
|
|
|
|
));
|
|
|
|
|
|
|
|
return false; // nonsensically long command which would bust my buffer buf.
|
|
|
|
}
|
|
|
|
|
|
|
|
kapp->flushX();
|
|
|
|
|
|
|
|
return Requester::rq->execPPPDaemon(command);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::closeEvent( TQCloseEvent *e ) {
|
|
|
|
e->ignore();
|
|
|
|
emit cancelbutton();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ConnectWidget::setMsg(const TQString &msg) {
|
|
|
|
messg->setText(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectWidget::writeline(const TQString &s) {
|
|
|
|
Modem::modem->writeLine(s.local8Bit());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the hostname and domain from DNS Server
|
|
|
|
void auto_hostname() {
|
|
|
|
struct in_addr local_ip;
|
|
|
|
struct hostent *hostname_entry;
|
|
|
|
TQString new_hostname;
|
|
|
|
int dot;
|
|
|
|
char tmp_str[100]; // buffer overflow safe
|
|
|
|
|
|
|
|
gethostname(tmp_str, sizeof(tmp_str));
|
|
|
|
tmp_str[sizeof(tmp_str)-1]=0; // panic
|
|
|
|
old_hostname=tmp_str; // copy to TQString
|
|
|
|
|
|
|
|
if (!p_kppp->stats->local_ip_address.isEmpty() && gpppdata.autoname()) {
|
|
|
|
local_ip.s_addr=inet_addr(p_kppp->stats->local_ip_address.ascii());
|
|
|
|
hostname_entry=gethostbyaddr((const char *)&local_ip,sizeof(in_addr),AF_INET);
|
|
|
|
|
|
|
|
if (hostname_entry != 0L) {
|
|
|
|
new_hostname=hostname_entry->h_name;
|
|
|
|
dot=new_hostname.find('.');
|
|
|
|
new_hostname=new_hostname.remove(dot,new_hostname.length()-dot);
|
|
|
|
Requester::rq->setHostname(new_hostname);
|
|
|
|
modified_hostname = TRUE;
|
|
|
|
|
|
|
|
new_hostname=hostname_entry->h_name;
|
|
|
|
new_hostname.remove(0,dot+1);
|
|
|
|
|
|
|
|
add_domain(new_hostname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Replace the DNS domain entry in the /etc/resolv.conf file and
|
|
|
|
// disable the nameserver entries if option is enabled
|
|
|
|
void add_domain(const TQString &domain) {
|
|
|
|
|
|
|
|
int fd;
|
|
|
|
char c;
|
|
|
|
TQString resolv[MAX_RESOLVCONF_LINES];
|
|
|
|
|
|
|
|
if (domain.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if((fd = Requester::rq->openResolv(O_RDONLY)) >= 0) {
|
|
|
|
|
|
|
|
int i=0;
|
|
|
|
while((read(fd, &c, 1) == 1) && (i < MAX_RESOLVCONF_LINES)) {
|
|
|
|
if(c == '\n') {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
resolv[i] += c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
if ((c != '\n') && (i < MAX_RESOLVCONF_LINES)) i++;
|
|
|
|
|
|
|
|
if((fd = Requester::rq->openResolv(O_WRONLY|O_TRUNC)) >= 0) {
|
|
|
|
TQCString tmp = "domain " + domain.local8Bit() +
|
|
|
|
" \t\t#kppp temp entry\n";
|
|
|
|
write(fd, tmp.data(), tmp.length());
|
|
|
|
|
|
|
|
for(int j=0; j < i; j++) {
|
|
|
|
if((resolv[j].contains("domain") ||
|
|
|
|
( resolv[j].contains("nameserver")
|
|
|
|
&& !resolv[j].contains("#kppp temp entry")
|
|
|
|
&& gpppdata.exDNSDisabled()))
|
|
|
|
&& !resolv[j].contains("#entry disabled by kppp")) {
|
|
|
|
TQCString tmp = "# " + resolv[j].local8Bit() +
|
|
|
|
" \t#entry disabled by kppp\n";
|
|
|
|
write(fd, tmp, tmp.length());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
TQCString tmp = resolv[j].local8Bit() + "\n";
|
|
|
|
write(fd, tmp, tmp.length());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// adds the DNS entries in the /etc/resolv.conf file
|
|
|
|
void adddns()
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
if ((fd = Requester::rq->openResolv(O_WRONLY|O_APPEND)) >= 0) {
|
|
|
|
TQStringList &dnslist = gpppdata.dns();
|
|
|
|
for ( TQStringList::Iterator it = dnslist.begin();
|
|
|
|
it != dnslist.end();
|
|
|
|
++it )
|
|
|
|
{
|
|
|
|
TQCString dns = "nameserver " + (*it).local8Bit() +
|
|
|
|
" \t#kppp temp entry\n";
|
|
|
|
write(fd, dns.data(), dns.length());
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
add_domain(gpppdata.domain());
|
|
|
|
}
|
|
|
|
|
|
|
|
void addpeerdns() {
|
|
|
|
int fd, fd2;
|
|
|
|
TQString p = "/var/run/ppp/resolv.conf";
|
|
|
|
|
|
|
|
if (!TQFile::exists(p))
|
|
|
|
p = "/etc/ppp/resolv.conf";
|
|
|
|
|
|
|
|
if((fd = Requester::rq->openResolv(O_WRONLY|O_APPEND)) >= 0) {
|
|
|
|
if((fd2 = open(p.latin1(), O_RDONLY)) >= 0) {
|
|
|
|
char c;
|
|
|
|
int i = 0;
|
|
|
|
while(i++ < 100 && read(fd2, &c, 1) == 1) {
|
|
|
|
if(c == '\n')
|
|
|
|
write(fd, "\t#kppp temp entry\n", 18);
|
|
|
|
else
|
|
|
|
write(fd, &c, 1);
|
|
|
|
}
|
|
|
|
close(fd2);
|
|
|
|
} else
|
|
|
|
fprintf(stderr, "failed to read from %s\n", p.latin1());
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
add_domain(gpppdata.domain());
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove the dns entries from the /etc/resolv.conf file
|
|
|
|
void removedns() {
|
|
|
|
|
|
|
|
int fd;
|
|
|
|
char c;
|
|
|
|
TQString resolv[MAX_RESOLVCONF_LINES];
|
|
|
|
|
|
|
|
if((fd = Requester::rq->openResolv(O_RDONLY)) >= 0) {
|
|
|
|
|
|
|
|
int i=0;
|
|
|
|
while(read(fd, &c, 1) == 1 && i < MAX_RESOLVCONF_LINES) {
|
|
|
|
if(c == '\n') {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
resolv[i] += c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
if((fd = Requester::rq->openResolv(O_WRONLY|O_TRUNC)) >= 0) {
|
|
|
|
for(int j=0; j < i; j++) {
|
|
|
|
if(resolv[j].contains("#kppp temp entry")) continue;
|
|
|
|
if(resolv[j].contains("#entry disabled by kppp")) {
|
|
|
|
TQCString tmp = resolv[j].local8Bit();
|
|
|
|
write(fd, tmp.data()+2, tmp.length() - 27);
|
|
|
|
write(fd, "\n", 1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
TQCString tmp = resolv[j].local8Bit() + "\n";
|
|
|
|
write(fd, tmp, tmp.length());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( modified_hostname ) {
|
|
|
|
Requester::rq->setHostname(old_hostname);
|
|
|
|
modified_hostname = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "connect.moc"
|