summaryrefslogtreecommitdiff
path: root/noncore/settings/networksettings/ppp/connect.cpp
Unidiff
Diffstat (limited to 'noncore/settings/networksettings/ppp/connect.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/networksettings/ppp/connect.cpp1438
1 files changed, 1438 insertions, 0 deletions
diff --git a/noncore/settings/networksettings/ppp/connect.cpp b/noncore/settings/networksettings/ppp/connect.cpp
new file mode 100644
index 0000000..b7e229e
--- a/dev/null
+++ b/noncore/settings/networksettings/ppp/connect.cpp
@@ -0,0 +1,1438 @@
1/*
2 * kPPP: A pppd front end for the KDE project
3 *
4 *
5 * Copyright (C) 1997 Bernd Johannes Wuebben
6 * wuebben@math.cornell.edu
7 * Copyright (C) 1998-2001 Harri Porten <porten@kde.org>
8 *
9 * based on EzPPP:
10 * Copyright (C) 1997 Jay Painter
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with this program; if not, write to the Free
24 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27//#include <config.h>
28
29#include <qlayout.h>
30#include <qregexp.h>
31
32#include <qapplication.h>
33//#include <kdebug.h>
34//#include <klocale.h>
35#define i18n QObject::tr
36#include <qmessagebox.h>
37#include <qpushbutton.h>
38
39#include <unistd.h>
40#include <stdlib.h>
41#include <string.h>
42#include <fcntl.h>
43#include <netdb.h>
44#include <sys/types.h>
45#include <sys/socket.h>
46#include <arpa/inet.h>
47#include <netinet/in.h>
48#include <sys/ioctl.h>
49#include <assert.h>
50
51#ifdef _XPG4_2
52 #define __xnet_connectconnect
53#endif
54
55#include <errno.h>
56
57#ifdef HAVE_SYS_PARAM_H
58#include <sys/param.h>
59#endif
60
61#ifdef __linux__
62#include "runtests.h"
63#endif
64
65#include "auth.h"
66#include "connect.h"
67//#include "docking.h"
68//#include "main.h"
69#include "modem.h"
70#include "kpppconfig.h"
71#include "pppdata.h"
72#include "kpppwidget.h"
73//#include "requester.h"
74//#include "utils.h"
75#define execute_command system
76
77extern KPPPWidget *p_kppp;
78
79QString old_hostname;
80bool modified_hostname;
81
82
83ConnectWidget::ConnectWidget(QWidget *parent, const char *name)
84 : QWidget(parent, name),
85 // initialize some important variables
86 myreadbuffer(""),
87 main_timer_ID(0),
88 vmain(0),
89 substate(-1),
90 scriptindex(0),
91 loopnest(0),
92 loopend(false),
93 semaphore(false),
94 expecting(false),
95 readbuffer(""),
96 scanvar(""),
97 scanning(false),
98 pausing(false),
99// termwindow(0),
100// stats(st),
101 dialnumber(0)
102{
103 modified_hostname = false;
104
105 QVBoxLayout *tl = new QVBoxLayout(this, 8, 10);
106 QString tit = i18n("Connecting to: ");
107 setCaption(tit);
108
109 QHBoxLayout *l0 = new QHBoxLayout(10);
110 tl->addLayout(l0);
111 l0->addSpacing(10);
112 messg = new QLabel(this, "messg");
113 messg->setFrameStyle(QFrame::Panel|QFrame::Sunken);
114 messg->setAlignment(AlignCenter);
115 messg->setText(i18n("Unable to create modem lock file."));
116 messg->setMinimumHeight(messg->sizeHint().height() + 5);
117 int messw = (messg->sizeHint().width() * 12) / 10;
118 messw = QMAX(messw,280);
119 messg->setMinimumWidth(messw);
120 messg->setText(i18n("Looking for modem..."));
121 l0->addSpacing(10);
122 l0->addWidget(messg);
123 l0->addSpacing(10);
124
125 QHBoxLayout *l1 = new QHBoxLayout(10);
126 tl->addLayout(l1);
127 l1->addStretch(1);
128
129 debug = new QPushButton(i18n("Log"), this);
130 debug->setToggleButton(true);
131 connect(debug, SIGNAL(clicked()), SIGNAL(toggleDebugWindow()));
132
133 cancel = new QPushButton(i18n("Cancel"), this);
134 cancel->setFocus();
135 connect(cancel, SIGNAL(clicked()), SLOT(cancelbutton()));
136
137 int maxw = QMAX(cancel->sizeHint().width(),
138 debug->sizeHint().width());
139 maxw = QMAX(maxw,65);
140 debug->setFixedWidth(maxw);
141 cancel->setFixedWidth(maxw);
142 l1->addWidget(debug);
143 l1->addWidget(cancel);
144
145 setFixedSize(sizeHint());
146
147 pausetimer = new QTimer(this);
148 connect(pausetimer, SIGNAL(timeout()), SLOT(pause()));
149
150 qApp->processEvents();
151
152 timeout_timer = new QTimer(this);
153 connect(timeout_timer, SIGNAL(timeout()), SLOT(script_timed_out()));
154
155 inittimer = new QTimer(this);
156 connect(inittimer, SIGNAL(timeout()), SLOT(init()));
157
158 if_timeout_timer = new QTimer(this);
159 connect(if_timeout_timer, SIGNAL(timeout()), SLOT(if_waiting_timed_out()));
160
161 connect(this,SIGNAL(if_waiting_signal()),this,SLOT(if_waiting_slot()));
162
163 prompt = new PWEntry( this, "pw" );
164 if_timer = new QTimer(this);
165 connect(if_timer,SIGNAL(timeout()), SLOT(if_waiting_slot()));
166}
167
168
169ConnectWidget::~ConnectWidget() {
170}
171
172
173void ConnectWidget::preinit() {
174 // this is all just to keep the GUI nice and snappy ....
175 // you have to see to believe ...
176 messg->setText(i18n("Looking for modem..."));
177 inittimer->start(100);
178}
179
180
181void ConnectWidget::init() {
182 gpppdata.setpppdError(0);
183 inittimer->stop();
184 vmain = 0;
185 substate = -1;
186 expecting = false;
187 pausing = false;
188 scriptindex = 0;
189 myreadbuffer = "";
190 scanning = false;
191 scanvar = "";
192 firstrunID = true;
193 firstrunPW = true;
194// stats->totalbytes = 0;
195 dialnumber = 0;
196
197 p_kppp->con_speed = "";
198
199// p_kppp->setQuitOnDisconnect (p_kppp->quitOnDisconnect() || gpppdata.quit_on_disconnect());
200
201 comlist = &gpppdata.scriptType();
202 arglist = &gpppdata.script();
203
204 QString tit = i18n("Connecting to: %1").arg(gpppdata.accname());
205 setCaption(tit);
206
207 qApp->processEvents();
208
209 // run the "before-connect" command
210 if (!gpppdata.command_before_connect().isEmpty()) {
211 messg->setText(i18n("Running pre-startup command..."));
212 emit debugMessage(i18n("Running pre-startup command..."));
213
214 qApp->processEvents();
215 QApplication::flushX();
216 pid_t id = execute_command(gpppdata.command_before_connect());
217// int i, status;
218
219// do {
220// qApp->processEvents();
221// i = waitpid(id, &status, WNOHANG);
222// usleep(100000);
223// } while (i == 0 && errno == 0);
224 }
225
226 int lock = Modem::modem->lockdevice();
227
228 if (lock == 1) {
229 messg->setText(i18n("Modem device is locked."));
230 vmain = 20; // wait until cancel is pressed
231 return;
232 }
233
234 if (lock == -1) {
235 messg->setText(i18n("Unable to create modem lock file."));
236 vmain = 20; // wait until cancel is pressed
237 return;
238 }
239
240 if(Modem::modem->opentty()) {
241 messg->setText(Modem::modem->modemMessage());
242 qApp->processEvents();
243 if(Modem::modem->hangup()) {
244
245 qApp->processEvents();
246
247 semaphore = false;
248
249 Modem::modem->stop();
250 Modem::modem->notify(this, SLOT(readChar(unsigned char)));
251
252 // if we are stuck anywhere we will time out
253 timeout_timer->start(gpppdata.modemTimeout()*1000);
254
255 // this timer will run the script etc.
256 main_timer_ID = startTimer(10);
257
258 return;
259 }
260 }
261
262 // initialization failed
263 messg->setText(Modem::modem->modemMessage());
264 vmain = 20; // wait until cancel is pressed
265 Modem::modem->unlockdevice();
266}
267
268
269void ConnectWidget::timerEvent(QTimerEvent *) {
270 if (semaphore || pausing)
271 return;
272
273 if(vmain == 0) {
274#ifdef DEBUG_WO_DIALING
275 vmain = 10;
276 return;
277#endif
278
279 assert(PPPData::NumInitStrings > 0);
280 // first init string ?
281 if(substate == -1) {
282 messg->setText(i18n("Initializing modem..."));
283 emit debugMessage(i18n("Initializing modem..."));
284 substate = 0;
285 }
286
287 QString initStr = gpppdata.modemInitStr(substate);
288 if (!initStr.isEmpty()) {
289 // send a carriage return and then wait a bit so that the modem will
290 // let us issue commands.
291 if(gpppdata.modemPreInitDelay() > 0) {
292 usleep(gpppdata.modemPreInitDelay() * 5000);
293 writeline("");
294 usleep(gpppdata.modemPreInitDelay() * 5000);
295 }
296 setExpect(gpppdata.modemInitResp());
297 writeline(initStr);
298 usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 sec
299 }
300
301 substate++;
302
303 /*
304 * FIXME after 3.0: Make it possible to disable ATS11 since it
305 * seems to be incompatible with some ISDN adapters (e.g. DataBox
306 * Speed Dragon). Even better would be to detect this when doing
307 * a "Modem Query"
308 */
309 if (MODEM_TONEDURATION != gpppdata.modemToneDuration())
310 vmain = 5;
311 else
312 vmain = 3;
313
314 return;
315 }
316
317 if (vmain == 5) {
318 if(!expecting) {
319 QString sToneDuration = "ATS11=" + QString::number(gpppdata.modemToneDuration());
320 QString msg = i18n("Setting ") + sToneDuration;
321 messg->setText(msg);
322 emit debugMessage(msg);
323 setExpect(gpppdata.modemInitResp());
324 writeline(sToneDuration);
325 }
326 vmain = 3;
327 return;
328 }
329
330 if(vmain == 3) {
331 if(!expecting) {
332 // done with all init strings ?
333 if(substate < PPPData::NumInitStrings) {
334 vmain = 0;
335 return;
336 }
337 substate = -1;
338 // skip setting the volume if command is empty
339 if(gpppdata.volumeInitString().isEmpty()) {
340 vmain = 4;
341 return;
342 }
343 messg->setText(i18n("Setting speaker volume..."));
344 emit debugMessage(i18n("Setting speaker volume..."));
345
346 setExpect(gpppdata.modemInitResp());
347 QString vol("AT");
348 vol += gpppdata.volumeInitString();
349 writeline(vol);
350 usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 sec
351 vmain = 4;
352 return;
353 }
354 }
355
356 if(vmain == 4) {
357 if(!expecting) {
358 if(!gpppdata.waitForDialTone()) {
359 QString msg = i18n("Turning off dial tone waiting...");
360 messg->setText(msg);
361 emit debugMessage(msg);
362 setExpect(gpppdata.modemInitResp());
363 writeline(gpppdata.modemNoDialToneDetectionStr());
364 }
365 vmain = 1;
366 return;
367 }
368 }
369
370 // dial the number and wait to connect
371 if(vmain == 1) {
372 if(!expecting) {
373
374 timeout_timer->stop();
375 timeout_timer->start(gpppdata.modemTimeout()*1000);
376
377 QStringList &plist = gpppdata.phonenumbers();
378 QString bmarg= gpppdata.dialPrefix();
379 bmarg += *plist.at(dialnumber);
380 QString bm = i18n("Dialing %1").arg(bmarg);
381 messg->setText(bm);
382 emit debugMessage(bm);
383
384 QString pn = gpppdata.modemDialStr();
385 pn += gpppdata.dialPrefix();
386 pn += *plist.at(dialnumber);
387 if(++dialnumber >= plist.count())
388 dialnumber = 0;
389 writeline(pn);
390
391 setExpect(gpppdata.modemConnectResp());
392 vmain = 100;
393 return;
394 }
395 }
396
397 // wait for connect, but redial if BUSY or wait for user cancel
398 // if NO CARRIER or NO DIALTONE
399 if(vmain == 100) {
400 if(!expecting) {
401 myreadbuffer = gpppdata.modemConnectResp();
402 setExpect("\n");
403 vmain = 101;
404 return;
405 }
406
407 if(readbuffer.contains(gpppdata.modemBusyResp())) {
408 timeout_timer->stop();
409 timeout_timer->start(gpppdata.modemTimeout()*1000);
410
411 messg->setText(i18n("Line busy. Hanging up..."));
412 emit debugPutChar('\n');
413 Modem::modem->hangup();
414
415 if(gpppdata.busyWait() > 0) {
416 QString bm = i18n("Line busy. Waiting: %1 seconds").arg(gpppdata.busyWait());
417 messg->setText(bm);
418 emit debugMessage(bm);
419
420 pausing = true;
421
422 pausetimer->start(gpppdata.busyWait()*1000, true);
423 timeout_timer->stop();
424 }
425
426 Modem::modem->setDataMode(false);
427 vmain = 0;
428 substate = -1;
429 return;
430 }
431
432 if(readbuffer.contains(gpppdata.modemNoDialtoneResp())) {
433 timeout_timer->stop();
434
435 messg->setText(i18n("No Dialtone"));
436 vmain = 20;
437 Modem::modem->unlockdevice();
438 return;
439 }
440
441 if(readbuffer.contains(gpppdata.modemNoCarrierResp())) {
442 timeout_timer->stop();
443
444 messg->setText(i18n("No Carrier"));
445 vmain = 20;
446 Modem::modem->unlockdevice();
447 return;
448 }
449 }
450
451 // wait for newline after CONNECT response (so we get the speed)
452 if(vmain == 101) {
453 if(!expecting) {
454 Modem::modem->setDataMode(true); // modem will no longer respond to AT commands
455
456 emit startAccounting();
457// p_kppp->con_win->startClock();
458
459 vmain = 2;
460 scriptTimeout=gpppdata.modemTimeout()*1000;
461 return;
462 }
463 }
464
465 // execute the script
466 if(vmain == 2) {
467 if(!expecting && !pausing && !scanning) {
468
469 timeout_timer->stop();
470 timeout_timer->start(scriptTimeout);
471
472 if((unsigned) scriptindex < comlist->count()) {
473 scriptCommand = *(comlist->at(scriptindex));
474 scriptArgument = *(arglist->at(scriptindex));
475 } else {
476 qDebug( "End of script" );
477 vmain = 10;
478 return;
479 }
480
481 if (scriptCommand == "Scan") {
482 QString bm = i18n("Scanning %1").arg(scriptArgument);
483 messg->setText(bm);
484 emit debugMessage(bm);
485
486 setScan(scriptArgument);
487 scriptindex++;
488 return;
489 }
490
491 if (scriptCommand == "Save") {
492 QString bm = i18n("Saving %1").arg(scriptArgument);
493 messg->setText(bm);
494 emit debugMessage(bm);
495
496 if (scriptArgument.lower() == "password") {
497 gpppdata.setPassword(scanvar);
498 p_kppp->setPW_Edit(scanvar);
499 if(gpppdata.storePassword())
500 gpppdata.setStoredPassword(scanvar);
501 firstrunPW = true;
502 }
503
504 scriptindex++;
505 return;
506 }
507
508
509 if (scriptCommand == "Send" || scriptCommand == "SendNoEcho") {
510 QString bm = i18n("Sending %1");
511
512 // replace %USERNAME% and %PASSWORD%
513 QString arg = scriptArgument;
514 QRegExp re1("%USERNAME%");
515 QRegExp re2("%PASSWORD%");
516 arg = arg.replace(re1, gpppdata.storedUsername());
517 arg = arg.replace(re2, gpppdata.storedPassword());
518
519 if (scriptCommand == "Send")
520 bm = bm.arg(scriptArgument);
521 else {
522 for(uint i = 0; i < scriptArgument.length(); i++)
523 bm = bm.arg("*");
524 }
525
526 messg->setText(bm);
527 emit debugMessage(bm);
528
529 writeline(scriptArgument);
530 scriptindex++;
531 return;
532 }
533
534 if (scriptCommand == "Expect") {
535 QString bm = i18n("Expecting %1").arg(scriptArgument);
536 messg->setText(bm);
537 emit debugMessage(bm);
538
539 // The incrementing of the scriptindex MUST be before the
540 // call to setExpect otherwise the expect will miss a string that is
541 // already in the buffer.
542 scriptindex++;
543 setExpect(scriptArgument);
544 return;
545 }
546
547
548 if (scriptCommand == "Pause") {
549 QString bm = i18n("Pause %1 seconds").arg(scriptArgument);
550 messg->setText(bm);
551 emit debugMessage(bm);
552
553 pausing = true;
554
555 pausetimer->start(scriptArgument.toInt()*1000, true);
556 timeout_timer->stop();
557
558 scriptindex++;
559 return;
560 }
561
562 if (scriptCommand == "Timeout") {
563
564 timeout_timer->stop();
565
566 QString bm = i18n("Timeout %1 seconds").arg(scriptArgument);
567 messg->setText(bm);
568 emit debugMessage(bm);
569
570 scriptTimeout=scriptArgument.toInt()*1000;
571 timeout_timer->start(scriptTimeout);
572
573 scriptindex++;
574 return;
575 }
576
577 if (scriptCommand == "Hangup") {
578 messg->setText(i18n("Hangup"));
579 emit debugMessage(i18n("Hangup"));
580
581 writeline(gpppdata.modemHangupStr());
582 setExpect(gpppdata.modemHangupResp());
583
584 scriptindex++;
585 return;
586 }
587
588 if (scriptCommand == "Answer") {
589
590 timeout_timer->stop();
591
592 messg->setText(i18n("Answer"));
593 emit debugMessage(i18n("Answer"));
594
595 setExpect(gpppdata.modemRingResp());
596 vmain = 150;
597 return;
598 }
599
600 if (scriptCommand == "ID") {
601 QString bm = i18n("ID %1").arg(scriptArgument);
602 messg->setText(bm);
603 emit debugMessage(bm);
604
605 QString idstring = gpppdata.storedUsername();
606
607 if(!idstring.isEmpty() && firstrunID) {
608 // the user entered an Id on the main kppp dialog
609 writeline(idstring);
610 firstrunID = false;
611 scriptindex++;
612 }
613 else {
614 // the user didn't enter and Id on the main kppp dialog
615 // let's query for an ID
616 /* if not around yet, then post window... */
617 if (prompt->Consumed()) {
618 if (!(prompt->isVisible())) {
619 prompt->setPrompt(scriptArgument);
620 prompt->setEchoModeNormal();
621 prompt->show();
622 }
623 } else {
624 /* if prompt withdrawn ... then, */
625 if(!(prompt->isVisible())) {
626 writeline(prompt->text());
627 prompt->setConsumed();
628 scriptindex++;
629 return;
630 }
631 /* replace timeout value */
632 }
633 }
634 }
635
636 if (scriptCommand == "Password") {
637 QString bm = i18n("Password %1").arg(scriptArgument);
638 messg->setText(bm);
639 emit debugMessage(bm);
640
641 QString pwstring = gpppdata.password();
642
643 if(!pwstring.isEmpty() && firstrunPW) {
644 // the user entered a password on the main kppp dialog
645 writeline(pwstring);
646 firstrunPW = false;
647 scriptindex++;
648 }
649 else {
650 // the user didn't enter a password on the main kppp dialog
651 // let's query for a password
652 /* if not around yet, then post window... */
653 if (prompt->Consumed()) {
654 if (!(prompt->isVisible())) {
655 prompt->setPrompt(scriptArgument);
656 prompt->setEchoModePassword();
657 prompt->show();
658 }
659 } else {
660 /* if prompt withdrawn ... then, */
661 if(!(prompt->isVisible())) {
662 p_kppp->setPW_Edit(prompt->text());
663 writeline(prompt->text());
664 prompt->setConsumed();
665 scriptindex++;
666 return;
667 }
668 /* replace timeout value */
669 }
670 }
671 }
672
673 if (scriptCommand == "Prompt") {
674 QString bm = i18n("Prompting %1");
675
676 // if the scriptindex (aka the prompt text) includes a ## marker
677 // this marker should get substituted with the contents of our stored
678 // variable (from the subsequent scan).
679
680 QString ts = scriptArgument;
681 int vstart = ts.find( "##" );
682 if( vstart != -1 ) {
683 ts.remove( vstart, 2 );
684 ts.insert( vstart, scanvar );
685 }
686
687 bm = bm.arg(ts);
688 messg->setText(bm);
689 emit debugMessage(bm);
690
691 /* if not around yet, then post window... */
692 if (prompt->Consumed()) {
693 if (!(prompt->isVisible())) {
694 prompt->setPrompt( ts );
695 prompt->setEchoModeNormal();
696 prompt->show();
697 }
698 } else {
699 /* if prompt withdrawn ... then, */
700 if (!(prompt->isVisible())) {
701 writeline(prompt->text());
702 prompt->setConsumed();
703 scriptindex++;
704 return;
705 }
706 /* replace timeout value */
707 }
708 }
709
710 if (scriptCommand == "PWPrompt") {
711 QString bm = i18n("PW Prompt %1").arg(scriptArgument);
712 messg->setText(bm);
713 emit debugMessage(bm);
714
715 /* if not around yet, then post window... */
716 if (prompt->Consumed()) {
717 if (!(prompt->isVisible())) {
718 prompt->setPrompt(scriptArgument);
719 prompt->setEchoModePassword();
720 prompt->show();
721 }
722 } else {
723 /* if prompt withdrawn ... then, */
724 if (!(prompt->isVisible())) {
725 writeline(prompt->text());
726 prompt->setConsumed();
727 scriptindex++;
728 return;
729 }
730 /* replace timeout value */
731 }
732 }
733
734 if (scriptCommand == "LoopStart") {
735
736 QString bm = i18n("Loop Start %1").arg(scriptArgument);
737
738 // The incrementing of the scriptindex MUST be before the
739 // call to setExpect otherwise the expect will miss a string that is
740 // already in the buffer.
741 scriptindex++;
742
743 if ( loopnest > (MAXLOOPNEST-2) ) {
744 bm += i18n("ERROR: Nested too deep, ignored.");
745 vmain=20;
746 cancelbutton();
747 QMessageBox::critical(0, "error", i18n("Loops nested too deeply!"));
748 } else {
749 setExpect(scriptArgument);
750 loopstartindex[loopnest] = scriptindex;
751 loopstr[loopnest] = scriptArgument;
752 loopend = false;
753 loopnest++;
754 }
755 messg->setText(bm);
756 emit debugMessage(bm);
757
758 }
759
760 if (scriptCommand == "LoopEnd") {
761 QString bm = i18n("Loop End %1").arg(scriptArgument);
762 if ( loopnest <= 0 ) {
763 bm = i18n("LoopEnd without matching Start! Line: %1").arg(bm);
764 vmain=20;
765 cancelbutton();
766 QMessageBox::critical(0, "error", bm);
767 return;
768 } else {
769 // NB! The incrementing of the scriptindex MUST be before the
770 // call to setExpect otherwise the expect will miss a string
771 // that is already in the buffer.
772 scriptindex++;
773 setExpect(scriptArgument);
774 loopnest--;
775 loopend = true;
776 }
777 messg->setText(bm);
778 emit debugMessage(bm);
779
780 }
781 }
782 }
783
784 // this is a subroutine for the "Answer" script option
785
786 if(vmain == 150) {
787 if(!expecting) {
788 writeline(gpppdata.modemAnswerStr());
789 setExpect(gpppdata.modemAnswerResp());
790
791 vmain = 2;
792 scriptindex++;
793 return;
794 }
795 }
796
797 if(vmain == 30) {
798// if (termwindow->isVisible())
799// return;
800// if (termwindow->pressedContinue())
801// vmain = 10;
802// else
803 cancelbutton();
804 }
805
806 if(vmain == 10) {
807 if(!expecting) {
808
809 int result;
810
811 timeout_timer->stop();
812 if_timeout_timer->stop(); // better be sure.
813
814 // stop reading of data
815 Modem::modem->stop();
816
817 if(gpppdata.authMethod() == AUTH_TERMINAL) {
818 // if (termwindow) {
819 // delete termwindow;
820 // termwindow = 0L;
821 // this->show();
822 // } else {
823 // termwindow = new LoginTerm(0L, 0L);
824 // hide();
825 // termwindow->show();
826 // vmain = 30;
827 // return;
828 // }
829 }
830
831 // Close the tty. This prevents the QTimer::singleShot() in
832 // Modem::readtty() from re-enabling the socket notifier.
833 // The port is still held open by the helper process.
834 Modem::modem->closetty();
835
836 killTimer( main_timer_ID );
837
838 if_timeout_timer->start(gpppdata.pppdTimeout()*1000);
839 qDebug( "started if timeout timer with %i", gpppdata.pppdTimeout()*1000);
840
841 // find out PPP interface and notify the stats module
842// stats->setUnit(pppInterfaceNumber());
843
844 qApp->flushX();
845 semaphore = true;
846 result = execppp();
847
848 emit debugMessage(i18n("Starting pppd..."));
849 qDebug("execppp() returned with return-code %i", result );
850
851 if(result) {
852 if(!gpppdata.autoDNS())
853 adddns();
854
855 // O.K we are done here, let's change over to the if_waiting loop
856 // where we wait for the ppp if (interface) to come up.
857
858 emit if_waiting_signal();
859 } else {
860
861 // starting pppd wasn't successful. Error messages were
862 // handled by execppp();
863 if_timeout_timer->stop();
864 this->hide();
865 messg->setText("");
866 p_kppp->quit_b->setFocus();
867 p_kppp->show();
868 qApp->processEvents();
869 Modem::modem->hangup();
870 emit stopAccounting();
871 //p_kppp->con_win->stopClock();
872 Modem::modem->closetty();
873 Modem::modem->unlockdevice();
874
875 }
876
877 return;
878 }
879 }
880
881 // this is a "wait until cancel" entry
882
883 if(vmain == 20) {
884 }
885}
886
887
888void ConnectWidget::set_con_speed_string() {
889 // Here we are trying to determine the speed at which we are connected.
890 // Usually the modem responds after connect with something like
891 // CONNECT 115200, so all we need to do is find the number after CONNECT
892 // or whatever the modemConnectResp() is.
893 p_kppp->con_speed = Modem::modem->parseModemSpeed(myreadbuffer);
894}
895
896
897
898void ConnectWidget::readChar(unsigned char c) {
899 if(semaphore)
900 return;
901
902 readbuffer += c;
903 myreadbuffer += c;
904
905 // While in scanning mode store each char to the scan buffer
906 // for use in the prompt command
907 if( scanning )
908 scanbuffer += c;
909
910 // add to debug window
911 emit debugPutChar(c);
912
913 checkBuffers();
914}
915
916
917void ConnectWidget::checkBuffers() {
918 // Let's check if we are finished with scanning:
919 // The scanstring have to be in the buffer and the latest character
920 // was a carriage return or an linefeed (depending on modem setup)
921 if( scanning && scanbuffer.contains(scanstr) &&
922 ( scanbuffer.right(1) == "\n" || scanbuffer.right(1) == "\r") ) {
923 scanning = false;
924
925 int vstart = scanbuffer.find( scanstr ) + scanstr.length();
926 scanvar = scanbuffer.mid( vstart, scanbuffer.length() - vstart);
927 scanvar = scanvar.stripWhiteSpace();
928
929 // Show the Variabel content in the debug window
930 QString sv = i18n("Scan Var: %1").arg(scanvar);
931 emit debugMessage(sv);
932 }
933
934 if(expecting) {
935 if(readbuffer.contains(expectstr)) {
936 expecting = false;
937 // keep everything after the expected string
938 readbuffer.remove(0, readbuffer.find(expectstr) + expectstr.length());
939
940 QString ts = i18n("Found: %1").arg(expectstr);
941 emit debugMessage(ts);
942
943 if (loopend) {
944 loopend=false;
945 }
946 }
947
948 if (loopend && readbuffer.contains(loopstr[loopnest])) {
949 expecting = false;
950 readbuffer = "";
951 QString ts = i18n("Looping: %1").arg(loopstr[loopnest]);
952 emit debugMessage(ts);
953 scriptindex = loopstartindex[loopnest];
954 loopend = false;
955 loopnest++;
956 }
957 // notify event loop if expected string was found
958 if(!expecting)
959 timerEvent((QTimerEvent *) 0);
960 }
961}
962
963
964
965void ConnectWidget::pause() {
966 pausing = false;
967 pausetimer->stop();
968}
969
970
971void ConnectWidget::cancelbutton() {
972 Modem::modem->stop();
973 killTimer(main_timer_ID);
974 timeout_timer->stop();
975 if_timer->stop();
976 if_timeout_timer->stop();
977
978// if (termwindow) {
979// delete termwindow;
980// termwindow = 0L;
981// this->show();
982// }
983
984 messg->setText(i18n("One moment please..."));
985
986 // just to be sure
987 Modem::modem->removeSecret(AUTH_PAP);
988 Modem::modem->removeSecret(AUTH_CHAP);
989 removedns();
990
991 qApp->processEvents();
992
993 Modem::modem->killPPPDaemon();
994 Modem::modem->hangup();
995
996 this->hide();
997 messg->setText("");
998 p_kppp->quit_b->setFocus();
999 p_kppp->show();
1000 emit stopAccounting();// just to be sure
1001// p_kppp->con_win->stopClock();
1002 Modem::modem->closetty();
1003 Modem::modem->unlockdevice();
1004
1005 //abort prompt window...
1006 if (prompt->isVisible()) {
1007 prompt->hide();
1008 }
1009 prompt->setConsumed();
1010
1011// if(p_kppp->quitOnDisconnect())
1012// qApp->exit(0);
1013}
1014
1015
1016void ConnectWidget::script_timed_out() {
1017 if(vmain == 20) { // we are in the 'wait for the user to cancel' state
1018 timeout_timer->stop();
1019 emit stopAccounting();
1020// p_kppp->con_win->stopClock();
1021 return;
1022 }
1023
1024 if (prompt->isVisible())
1025 prompt->hide();
1026
1027 prompt->setConsumed();
1028 messg->setText(i18n("Script timed out!"));
1029 Modem::modem->hangup();
1030 emit stopAccounting();
1031// p_kppp->con_win->stopClock();
1032
1033 vmain = 0; // let's try again.
1034 substate = -1;
1035}
1036
1037
1038void ConnectWidget::setScan(const QString &n) {
1039 scanning = true;
1040 scanstr = n;
1041 scanbuffer = "";
1042
1043 QString ts = i18n("Scanning: %1").arg(n);
1044 emit debugMessage(ts);
1045}
1046
1047
1048void ConnectWidget::setExpect(const QString &n) {
1049 expecting = true;
1050 expectstr = n;
1051
1052 QString ts = i18n("Expecting: %1").arg(n);
1053 ts.replace(QRegExp("\n"), "<LF>");
1054 emit debugMessage(ts);
1055
1056 // check if the expected string is in the read buffer already.
1057 checkBuffers();
1058}
1059
1060
1061void ConnectWidget::if_waiting_timed_out() {
1062 if_timer->stop();
1063 if_timeout_timer->stop();
1064 qDebug("if_waiting_timed_out()");
1065
1066 gpppdata.setpppdError(E_IF_TIMEOUT);
1067
1068 // let's kill the stuck pppd
1069 Modem::modem->killPPPDaemon();
1070
1071 emit stopAccounting();
1072// p_kppp->con_win->stopClock();
1073
1074
1075 // killing ppp will generate a SIGCHLD which will be caught in pppdie()
1076 // in main.cpp what happens next will depend on the boolean
1077 // reconnect_on_disconnect which is set in ConnectWidget::init();
1078}
1079
1080void ConnectWidget::pppdDied()
1081{
1082 if_timer->stop();
1083 if_timeout_timer->stop();
1084}
1085
1086void ConnectWidget::if_waiting_slot() {
1087 messg->setText(i18n("Logging on to network..."));
1088
1089// if(!stats->ifIsUp()) {
1090
1091// if(gpppdata.pppdError() != 0) {
1092// // we are here if pppd died immediately after starting it.
1093// pppdDied();
1094// // error message handled in main.cpp: sigPPPDDied()
1095// return;
1096// }
1097
1098// if_timer->start(100, TRUE); // single shot
1099// return;
1100// }
1101
1102 // O.K the ppp interface is up and running
1103 // give it a few time to come up completly (0.2 seconds)
1104 if_timeout_timer->stop();
1105 if_timer->stop();
1106 usleep(200000);
1107
1108 if(gpppdata.autoDNS())
1109 addpeerdns();
1110
1111 // Close the debugging window. If we are connected, we
1112 // are not really interested in debug output
1113 emit closeDebugWindow();
1114// p_kppp->statdlg->take_stats(); // start taking ppp statistics
1115 auto_hostname();
1116
1117 if(!gpppdata.command_on_connect().isEmpty()) {
1118 messg->setText(i18n("Running startup command..."));
1119
1120 // make sure that we don't get any async errors
1121 qApp->flushX();
1122 execute_command(gpppdata.command_on_connect());
1123 messg->setText(i18n("Done"));
1124 }
1125
1126 // remove the authentication file
1127 Modem::modem->removeSecret(AUTH_PAP);
1128 Modem::modem->removeSecret(AUTH_CHAP);
1129
1130 emit debugMessage(i18n("Done"));
1131 set_con_speed_string();
1132
1133// p_kppp->con_win->setConnectionSpeed(p_kppp->con_speed);
1134 this->hide();
1135 messg->setText("");
1136
1137 // prepare the con_win so as to have the right size for
1138 // accounting / non-accounting mode
1139// if(p_kppp->acct != 0)
1140// p_kppp->con_win->accounting(p_kppp->acct->running());
1141// else
1142// p_kppp->con_win->accounting(false);
1143
1144 if (gpppdata.get_dock_into_panel()) {
1145// DockWidget::dock_widget->show();
1146// DockWidget::dock_widget->take_stats();
1147// this->hide();
1148 }
1149 else {
1150// p_kppp->con_win->show();
1151
1152 if(gpppdata.get_iconify_on_connect()) {
1153 // p_kppp->con_win->showMinimized();
1154 }
1155 }
1156
1157 Modem::modem->closetty();
1158}
1159
1160
1161bool ConnectWidget::execppp() {
1162 QString command;
1163
1164 command = "pppd";
1165
1166 // as of version 2.3.6 pppd falls back to the real user rights when
1167 // opening a device given in a command line. To avoid permission conflicts
1168 // we'll simply leave this argument away. pppd will then use the default tty
1169 // which is the serial port we connected stdin/stdout to in opener.cpp.
1170 // command += " ";
1171 // command += gpppdata.modemDevice();
1172
1173 command += " " + gpppdata.speed();
1174
1175 command += " -detach";
1176
1177 if(gpppdata.ipaddr() != "0.0.0.0" ||
1178 gpppdata.gateway() != "0.0.0.0") {
1179 if(gpppdata.ipaddr() != "0.0.0.0") {
1180 command += " ";
1181 command += gpppdata.ipaddr();
1182 command += ":";
1183 }
1184 else {
1185 command += " ";
1186 command += ":";
1187 }
1188
1189 if(gpppdata.gateway() != "0.0.0.0")
1190 command += gpppdata.gateway();
1191 }
1192
1193 if(gpppdata.subnetmask() != "0.0.0.0")
1194 command += " netmask " + gpppdata.subnetmask();
1195
1196 if(gpppdata.flowcontrol() != "None") {
1197 if(gpppdata.flowcontrol() == "CRTSCTS")
1198 command += " crtscts";
1199 else
1200 command += " xonxoff";
1201 }
1202
1203 if(gpppdata.defaultroute())
1204 command += " defaultroute";
1205
1206 if(gpppdata.autoDNS())
1207 command += " usepeerdns";
1208
1209 QStringList &arglist = gpppdata.pppdArgument();
1210 for ( QStringList::Iterator it = arglist.begin();
1211 it != arglist.end();
1212 ++it )
1213 {
1214 command += " " + *it;
1215 }
1216
1217 // PAP settings
1218 if(gpppdata.authMethod() == AUTH_PAP) {
1219 command += " -chap user ";
1220 command = command + "\"" + gpppdata.storedUsername() + "\"";
1221 }
1222
1223 // CHAP settings
1224 if(gpppdata.authMethod() == AUTH_CHAP) {
1225 command += " -pap user ";
1226 command = command + "\"" + gpppdata.storedUsername() + "\"";
1227 }
1228
1229 // PAP/CHAP settings
1230 if(gpppdata.authMethod() == AUTH_PAPCHAP) {
1231 command += " user ";
1232 command = command + "\"" + gpppdata.storedUsername() + "\"";
1233 }
1234
1235 // check for debug
1236 if(gpppdata.getPPPDebug())
1237 command += " debug";
1238
1239 if (command.length() > MAX_CMDLEN) {
1240 QMessageBox::critical(this, "error", i18n(
1241 "pppd command + command-line arguments exceed "
1242 "2024 characters in length."
1243 ));
1244
1245 return false; // nonsensically long command which would bust my buffer buf.
1246 }
1247
1248 qApp->flushX();
1249
1250 return Modem::modem->execPPPDaemon(command);
1251}
1252
1253
1254void ConnectWidget::closeEvent( QCloseEvent *e ) {
1255 e->ignore();
1256 emit cancelbutton();
1257}
1258
1259
1260void ConnectWidget::setMsg(const QString &msg) {
1261 messg->setText(msg);
1262}
1263
1264void ConnectWidget::writeline(const QString &s) {
1265 Modem::modem->writeLine(s.local8Bit());
1266}
1267
1268// Set the hostname and domain from DNS Server
1269void auto_hostname() {
1270 struct in_addr local_ip;
1271 struct hostent *hostname_entry;
1272 QString new_hostname;
1273 int dot;
1274 char tmp_str[100]; // buffer overflow safe
1275
1276 gethostname(tmp_str, sizeof(tmp_str));
1277 tmp_str[sizeof(tmp_str)-1]=0; // panic
1278 old_hostname=tmp_str; // copy to QString
1279
1280 // if (!p_kppp->stats->local_ip_address.isEmpty() && gpppdata.autoname()) {
1281 if ( gpppdata.autoname()) {
1282// local_ip.s_addr=inet_addr(p_kppp->stats->local_ip_address.ascii());
1283 hostname_entry=gethostbyaddr((const char *)&local_ip,sizeof(in_addr),AF_INET);
1284
1285 if (hostname_entry != 0L) {
1286 new_hostname=hostname_entry->h_name;
1287 dot=new_hostname.find('.');
1288 new_hostname=new_hostname.remove(dot,new_hostname.length()-dot);
1289 Modem::modem->setHostname(new_hostname);
1290 modified_hostname = TRUE;
1291
1292 new_hostname=hostname_entry->h_name;
1293 new_hostname.remove(0,dot+1);
1294
1295 add_domain(new_hostname);
1296 }
1297 }
1298
1299}
1300
1301// Replace the DNS domain entry in the /etc/resolv.conf file and
1302// disable the nameserver entries if option is enabled
1303void add_domain(const QString &domain) {
1304
1305 int fd;
1306 char c;
1307 QString resolv[MAX_RESOLVCONF_LINES];
1308
1309 if (domain.isEmpty())
1310 return;
1311
1312 if((fd = Modem::modem->openResolv(O_RDONLY)) >= 0) {
1313
1314 int i=0;
1315 while((read(fd, &c, 1) == 1) && (i < MAX_RESOLVCONF_LINES)) {
1316 if(c == '\n') {
1317 i++;
1318 }
1319 else {
1320 resolv[i] += c;
1321 }
1322 }
1323 close(fd);
1324 if ((c != '\n') && (i < MAX_RESOLVCONF_LINES)) i++;
1325
1326 if((fd = Modem::modem->openResolv(O_WRONLY|O_TRUNC)) >= 0) {
1327 QCString tmp = "domain " + domain.local8Bit() +
1328 " \t\t#kppp temp entry\n";
1329 write(fd, tmp.data(), tmp.length());
1330
1331 for(int j=0; j < i; j++) {
1332 if((resolv[j].contains("domain") ||
1333 ( resolv[j].contains("nameserver")
1334 && !resolv[j].contains("#kppp temp entry")
1335 && gpppdata.exDNSDisabled()))
1336 && !resolv[j].contains("#entry disabled by kppp")) {
1337 QCString tmp = "# " + resolv[j].local8Bit() +
1338 " \t#entry disabled by kppp\n";
1339 write(fd, tmp, tmp.length());
1340 }
1341 else {
1342 QCString tmp = resolv[j].local8Bit() + "\n";
1343 write(fd, tmp, tmp.length());
1344 }
1345 }
1346 }
1347 close(fd);
1348 }
1349}
1350
1351
1352// adds the DNS entries in the /etc/resolv.conf file
1353void adddns()
1354{
1355 int fd;
1356
1357 if ((fd = Modem::modem->openResolv(O_WRONLY|O_APPEND)) >= 0) {
1358 QStringList &dnslist = gpppdata.dns();
1359 for ( QStringList::Iterator it = dnslist.begin();
1360 it != dnslist.end();
1361 ++it )
1362 {
1363 QCString dns = "nameserver " + (*it).local8Bit() +
1364 " \t#kppp temp entry\n";
1365 write(fd, dns.data(), dns.length());
1366 }
1367 close(fd);
1368 }
1369 add_domain(gpppdata.domain());
1370}
1371
1372void addpeerdns() {
1373 int fd, fd2;
1374
1375 if((fd = Modem::modem->openResolv(O_WRONLY|O_APPEND)) >= 0) {
1376 if((fd2 = open("/etc/ppp/resolv.conf", O_RDONLY)) >= 0) {
1377 char c;
1378 int i = 0;
1379 while(i++ < 100 && read(fd2, &c, 1) == 1) {
1380 if(c == '\n')
1381 write(fd, "\t#kppp temp entry\n", 18);
1382 else
1383 write(fd, &c, 1);
1384 }
1385 close(fd2);
1386 } else
1387 fprintf(stderr, "failed to read from /etc/ppp/resolv.conf\n");
1388 close(fd);
1389 }
1390 add_domain(gpppdata.domain());
1391}
1392
1393// remove the dns entries from the /etc/resolv.conf file
1394void removedns() {
1395
1396 int fd;
1397 char c;
1398 QString resolv[MAX_RESOLVCONF_LINES];
1399
1400 if((fd = Modem::modem->openResolv(O_RDONLY)) >= 0) {
1401
1402 int i=0;
1403 while(read(fd, &c, 1) == 1 && i < MAX_RESOLVCONF_LINES) {
1404 if(c == '\n') {
1405 i++;
1406 }
1407 else {
1408 resolv[i] += c;
1409 }
1410 }
1411 close(fd);
1412
1413 if((fd = Modem::modem->openResolv(O_WRONLY|O_TRUNC)) >= 0) {
1414 for(int j=0; j < i; j++) {
1415 if(resolv[j].contains("#kppp temp entry")) continue;
1416 if(resolv[j].contains("#entry disabled by kppp")) {
1417 QCString tmp = resolv[j].local8Bit();
1418 write(fd, tmp.data()+2, tmp.length() - 27);
1419 write(fd, "\n", 1);
1420 }
1421 else {
1422 QCString tmp = resolv[j].local8Bit() + "\n";
1423 write(fd, tmp, tmp.length());
1424 }
1425 }
1426 }
1427 close(fd);
1428
1429 }
1430
1431 if ( modified_hostname ) {
1432 Modem::modem->setHostname(old_hostname);
1433 modified_hostname = FALSE;
1434 }
1435
1436}
1437
1438