summaryrefslogtreecommitdiff
path: root/noncore/settings/networksettings/ppp/modem.cpp
Unidiff
Diffstat (limited to 'noncore/settings/networksettings/ppp/modem.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/networksettings/ppp/modem.cpp85
1 files changed, 71 insertions, 14 deletions
diff --git a/noncore/settings/networksettings/ppp/modem.cpp b/noncore/settings/networksettings/ppp/modem.cpp
index d23fee4..3dbc8c3 100644
--- a/noncore/settings/networksettings/ppp/modem.cpp
+++ b/noncore/settings/networksettings/ppp/modem.cpp
@@ -1,654 +1,651 @@
1/* 1/*
2 * kPPP: A pppd Front End for the KDE project 2 * kPPP: A pppd Front End for the KDE project
3 * 3 *
4 * $Id$ 4 * $Id$
5 * 5 *
6 * Copyright (C) 1997 Bernd Johannes Wuebben 6 * Copyright (C) 1997 Bernd Johannes Wuebben
7 * wuebben@math.cornell.edu 7 * wuebben@math.cornell.edu
8 * 8 *
9 * This file was added by Harri Porten <porten@tu-harburg.de> 9 * This file was added by Harri Porten <porten@tu-harburg.de>
10 * 10 *
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public 13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either 14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version. 15 * version 2 of the License, or (at your option) any later version.
16 * 16 *
17 * This program is distributed in the hope that it will be useful, 17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details. 20 * Library General Public License for more details.
21 * 21 *
22 * You should have received a copy of the GNU Library General Public 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 23 * License along with this program; if not, write to the Free
24 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */ 25 */
26 26
27#include <errno.h> 27#include <errno.h>
28#include <stdlib.h> 28#include <stdlib.h>
29#include <unistd.h> 29#include <unistd.h>
30#include <fcntl.h> 30#include <fcntl.h>
31#include <signal.h> 31#include <signal.h>
32#include <sys/ioctl.h> 32#include <sys/ioctl.h>
33#include <sys/types.h> 33#include <sys/types.h>
34#include <sys/stat.h> 34#include <sys/stat.h>
35#include <setjmp.h> 35#include <setjmp.h>
36#include <regex.h> 36#include <regex.h>
37#include <qregexp.h> 37#include <qregexp.h>
38#include <assert.h> 38#include <assert.h>
39#include <string.h> 39#include <string.h>
40 40
41#ifdef HAVE_RESOLV_H 41#ifdef HAVE_RESOLV_H
42# include <arpa/nameser.h> 42# include <arpa/nameser.h>
43# include <resolv.h> 43# include <resolv.h>
44#endif 44#endif
45 45
46#ifndef _PATH_RESCONF 46#ifndef _PATH_RESCONF
47#define _PATH_RESCONF "/etc/resolv.conf" 47#define _PATH_RESCONF "/etc/resolv.conf"
48#endif 48#endif
49 49
50#define strlcpy strcpy 50#define strlcpy strcpy
51#include "auth.h" 51#include "auth.h"
52#include "modem.h" 52#include "modem.h"
53#include "pppdata.h" 53#include "pppdata.h"
54//#include <klocale.h>
55#define i18n QObject::tr
56#define qError qDebug 54#define qError qDebug
57//#include <kdebug.h> 55
58//#include <config.h>
59 56
60#define MY_ASSERT(x) if (!(x)) { \ 57#define MY_ASSERT(x) if (!(x)) { \
61 qFatal( "ASSERT: \"%s\" in %s (%d)\n",#x,__FILE__,__LINE__); \ 58 qFatal( "ASSERT: \"%s\" in %s (%d)\n",#x,__FILE__,__LINE__); \
62 exit(1); } 59 exit(1); }
63 60
64 61
65static sigjmp_buf jmp_buffer; 62static sigjmp_buf jmp_buffer;
66 63
67//Modem *Modem::modem = 0; 64//Modem *Modem::modem = 0;
68 65
69 66
70const char* pppdPath() { 67const char* pppdPath() {
71 // wasting a few bytes 68 // wasting a few bytes
72 static char buffer[sizeof(PPPDSEARCHPATH)+sizeof(PPPDNAME)]; 69 static char buffer[sizeof(PPPDSEARCHPATH)+sizeof(PPPDNAME)];
73 static char *pppdPath = 0L; 70 static char *pppdPath = 0L;
74 char *p; 71 char *p;
75 72
76 if(pppdPath == 0L) { 73 if(pppdPath == 0L) {
77 const char *c = PPPDSEARCHPATH; 74 const char *c = PPPDSEARCHPATH;
78 while(*c != '\0') { 75 while(*c != '\0') {
79 while(*c == ':') 76 while(*c == ':')
80 c++; 77 c++;
81 p = buffer; 78 p = buffer;
82 while(*c != '\0' && *c != ':') 79 while(*c != '\0' && *c != ':')
83 *p++ = *c++; 80 *p++ = *c++;
84 *p = '\0'; 81 *p = '\0';
85 strcat(p, "/"); 82 strcat(p, "/");
86 strcat(p, PPPDNAME); 83 strcat(p, PPPDNAME);
87 if(access(buffer, F_OK) == 0) 84 if(access(buffer, F_OK) == 0)
88 return (pppdPath = buffer); 85 return (pppdPath = buffer);
89 } 86 }
90 } 87 }
91 88
92 return pppdPath; 89 return pppdPath;
93} 90}
94 91
95 92
96Modem::Modem( PPPData* pd ) 93Modem::Modem( PPPData* pd )
97{ 94{
98 _pppdata = pd; 95 _pppdata = pd;
99 modemfd = -1; 96 modemfd = -1;
100 _pppdExitStatus = -1; 97 _pppdExitStatus = -1;
101 pppdPid = -1; 98 pppdPid = -1;
102 sn = 0L; 99 sn = m_modemDebug = 0L;
103 data_mode = false; 100 data_mode = false;
104 modem_is_locked = false; 101 modem_is_locked = false;
105 lockfile[0] = '\0'; 102 lockfile[0] = '\0';
106 device = "/dev/modem"; 103 device = "/dev/modem";
107} 104}
108 105
109 106
110Modem::~Modem() 107Modem::~Modem()
111{ 108{
112} 109}
113 110
114 111
115speed_t Modem::modemspeed() { 112speed_t Modem::modemspeed() {
116 // convert the string modem speed int the gpppdata object to a t_speed type 113 // convert the string modem speed int the gpppdata object to a t_speed type
117 // to set the modem. The constants here should all be ifdef'd because 114 // to set the modem. The constants here should all be ifdef'd because
118 // other systems may not have them 115 // other systems may not have them
119 int i = _pppdata->speed().toInt()/100; 116 int i = _pppdata->speed().toInt()/100;
120 117
121 switch(i) { 118 switch(i) {
122 case 24: 119 case 24:
123 return B2400; 120 return B2400;
124 break; 121 break;
125 case 96: 122 case 96:
126 return B9600; 123 return B9600;
127 break; 124 break;
128 case 192: 125 case 192:
129 return B19200; 126 return B19200;
130 break; 127 break;
131 case 384: 128 case 384:
132 return B38400; 129 return B38400;
133 break; 130 break;
134#ifdef B57600 131#ifdef B57600
135 case 576: 132 case 576:
136 return B57600; 133 return B57600;
137 break; 134 break;
138#endif 135#endif
139 136
140#ifdef B115200 137#ifdef B115200
141 case 1152: 138 case 1152:
142 return B115200; 139 return B115200;
143 break; 140 break;
144#endif 141#endif
145 142
146#ifdef B230400 143#ifdef B230400
147 case 2304: 144 case 2304:
148 return B230400; 145 return B230400;
149 break; 146 break;
150#endif 147#endif
151 148
152#ifdef B460800 149#ifdef B460800
153 case 4608: 150 case 4608:
154 return B460800; 151 return B460800;
155 break; 152 break;
156#endif 153#endif
157 154
158 default: 155 default:
159 return B38400; 156 return B38400;
160 break; 157 break;
161 } 158 }
162} 159}
163 160
164bool Modem::opentty() { 161bool Modem::opentty() {
165 // int flags; 162 // int flags;
166 163
167//begin if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) { 164//begin if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) {
168 close(modemfd); 165 close(modemfd);
169 device = _pppdata->modemDevice(); 166 device = _pppdata->modemDevice();
170 if ((modemfd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) == -1) { 167 if ((modemfd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) == -1) {
171 qDebug("error opening modem device !"); 168 qDebug("error opening modem device !");
172 errmsg = i18n("Unable to open modem."); 169 errmsg = QObject::tr("Unable to open modem.");
173 return false; 170 return false;
174 } 171 }
175//bend if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) { 172//bend if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) {
176//} 173//}
177 174
178#if 0 175#if 0
179 if(_pppdata->UseCDLine()) { 176 if(_pppdata->UseCDLine()) {
180 if(ioctl(modemfd, TIOCMGET, &flags) == -1) { 177 if(ioctl(modemfd, TIOCMGET, &flags) == -1) {
181 errmsg = i18n("Unable to detect state of CD line."); 178 errmsg = QObject::tr("Unable to detect state of CD line.");
182 ::close(modemfd); 179 ::close(modemfd);
183 modemfd = -1; 180 modemfd = -1;
184 return false; 181 return false;
185 } 182 }
186 if ((flags&TIOCM_CD) == 0) { 183 if ((flags&TIOCM_CD) == 0) {
187 errmsg = i18n("The modem is not ready."); 184 errmsg = QObject::tr("The modem is not ready.");
188 ::close(modemfd); 185 ::close(modemfd);
189 modemfd = -1; 186 modemfd = -1;
190 return false; 187 return false;
191 } 188 }
192 } 189 }
193#endif 190#endif
194 191
195 tcdrain (modemfd); 192 tcdrain (modemfd);
196 tcflush (modemfd, TCIOFLUSH); 193 tcflush (modemfd, TCIOFLUSH);
197 194
198 if(tcgetattr(modemfd, &tty) < 0){ 195 if(tcgetattr(modemfd, &tty) < 0){
199 // this helps in some cases 196 // this helps in some cases
200 tcsendbreak(modemfd, 0); 197 tcsendbreak(modemfd, 0);
201 sleep(1); 198 sleep(1);
202 if(tcgetattr(modemfd, &tty) < 0){ 199 if(tcgetattr(modemfd, &tty) < 0){
203 errmsg = i18n("The modem is busy."); 200 errmsg = QObject::tr("The modem is busy.");
204 ::close(modemfd); 201 ::close(modemfd);
205 modemfd = -1; 202 modemfd = -1;
206 return false; 203 return false;
207 } 204 }
208 } 205 }
209 206
210 memset(&initial_tty,'\0',sizeof(initial_tty)); 207 memset(&initial_tty,'\0',sizeof(initial_tty));
211 208
212 initial_tty = tty; 209 initial_tty = tty;
213 210
214 tty.c_cc[VMIN] = 0; // nonblocking 211 tty.c_cc[VMIN] = 0; // nonblocking
215 tty.c_cc[VTIME] = 0; 212 tty.c_cc[VTIME] = 0;
216 tty.c_oflag = 0; 213 tty.c_oflag = 0;
217 tty.c_lflag = 0; 214 tty.c_lflag = 0;
218 215
219 tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB); 216 tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
220 tty.c_cflag |= CS8 | CREAD; 217 tty.c_cflag |= CS8 | CREAD;
221 tty.c_cflag |= CLOCAL; // ignore modem status lines 218 tty.c_cflag |= CLOCAL; // ignore modem status lines
222 tty.c_iflag = IGNBRK | IGNPAR /* | ISTRIP */ ; 219 tty.c_iflag = IGNBRK | IGNPAR /* | ISTRIP */ ;
223 tty.c_lflag &= ~ICANON; // non-canonical mode 220 tty.c_lflag &= ~ICANON; // non-canonical mode
224 tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE); 221 tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE);
225 222
226 223
227 if(_pppdata->flowcontrol() != "None") { 224 if(_pppdata->flowcontrol() != "None") {
228 if(_pppdata->flowcontrol() == "CRTSCTS") { 225 if(_pppdata->flowcontrol() == "CRTSCTS") {
229 tty.c_cflag |= CRTSCTS; 226 tty.c_cflag |= CRTSCTS;
230 } 227 }
231 else { 228 else {
232 tty.c_iflag |= IXON | IXOFF; 229 tty.c_iflag |= IXON | IXOFF;
233 tty.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ 230 tty.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
234 tty.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ 231 tty.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
235 } 232 }
236 } 233 }
237 else { 234 else {
238 tty.c_cflag &= ~CRTSCTS; 235 tty.c_cflag &= ~CRTSCTS;
239 tty.c_iflag &= ~(IXON | IXOFF); 236 tty.c_iflag &= ~(IXON | IXOFF);
240 } 237 }
241 238
242 cfsetospeed(&tty, modemspeed()); 239 cfsetospeed(&tty, modemspeed());
243 cfsetispeed(&tty, modemspeed()); 240 cfsetispeed(&tty, modemspeed());
244 241
245 tcdrain(modemfd); 242 tcdrain(modemfd);
246 243
247 if(tcsetattr(modemfd, TCSANOW, &tty) < 0){ 244 if(tcsetattr(modemfd, TCSANOW, &tty) < 0){
248 errmsg = i18n("The modem is busy."); 245 errmsg = QObject::tr("The modem is busy.");
249 ::close(modemfd); 246 ::close(modemfd);
250 modemfd=-1; 247 modemfd=-1;
251 return false; 248 return false;
252 } 249 }
253 250
254 errmsg = i18n("Modem Ready."); 251 errmsg = QObject::tr("Modem Ready.");
255 return true; 252 return true;
256} 253}
257 254
258 255
259bool Modem::closetty() { 256bool Modem::closetty() {
260 if(modemfd >=0 ) { 257 if(modemfd >=0 ) {
261 stop(); 258 stop();
262 /* discard data not read or transmitted */ 259 /* discard data not read or transmitted */
263 tcflush(modemfd, TCIOFLUSH); 260 tcflush(modemfd, TCIOFLUSH);
264 261
265 if(tcsetattr(modemfd, TCSANOW, &initial_tty) < 0){ 262 if(tcsetattr(modemfd, TCSANOW, &initial_tty) < 0){
266 errmsg = i18n("Can't restore tty settings: tcsetattr()\n"); 263 errmsg = QObject::tr("Can't restore tty settings: tcsetattr()\n");
267 ::close(modemfd); 264 ::close(modemfd);
268 modemfd = -1; 265 modemfd = -1;
269 return false; 266 return false;
270 } 267 }
271 ::close(modemfd); 268 ::close(modemfd);
272 modemfd = -1; 269 modemfd = -1;
273 } 270 }
274 271
275 return true; 272 return true;
276} 273}
277 274
278 275
279void Modem::readtty(int) { 276void Modem::readtty(int) {
280 char buffer[200]; 277 char buffer[200];
281 unsigned char c; 278 unsigned char c;
282 int len; 279 int len;
283 280
284 // read data in chunks of up to 200 bytes 281 // read data in chunks of up to 200 bytes
285 if((len = ::read(modemfd, buffer, 200)) > 0) { 282 if((len = ::read(modemfd, buffer, 200)) > 0) {
286 // split buffer into single characters for further processing 283 // split buffer into single characters for further processing
287 for(int i = 0; i < len; i++) { 284 for(int i = 0; i < len; i++) {
288 c = buffer[i] & 0x7F; 285 c = buffer[i] & 0x7F;
289 emit charWaiting(c); 286 emit charWaiting(c);
290 } 287 }
291 } 288 }
292} 289}
293 290
294 291
295void Modem::notify(const QObject *receiver, const char *member) { 292void Modem::notify(const QObject *receiver, const char *member) {
296 connect(this, SIGNAL(charWaiting(unsigned char)), receiver, member); 293 connect(this, SIGNAL(charWaiting(unsigned char)), receiver, member);
297 startNotifier(); 294 startNotifier();
298} 295}
299 296
300 297
301void Modem::stop() { 298void Modem::stop() {
302 disconnect(SIGNAL(charWaiting(unsigned char))); 299 disconnect(SIGNAL(charWaiting(unsigned char)));
303 stopNotifier(); 300 stopNotifier();
304} 301}
305 302
306 303
307void Modem::startNotifier() { 304void Modem::startNotifier() {
308 if(modemfd >= 0) { 305 if(modemfd >= 0) {
309 if(sn == 0) { 306 if(sn == 0) {
310 sn = new QSocketNotifier(modemfd, QSocketNotifier::Read, this); 307 sn = new QSocketNotifier(modemfd, QSocketNotifier::Read, this);
311 connect(sn, SIGNAL(activated(int)), SLOT(readtty(int))); 308 connect(sn, SIGNAL(activated(int)), SLOT(readtty(int)));
312 qDebug("QSocketNotifier started!"); 309 qDebug("QSocketNotifier started!");
313 } else { 310 } else {
314 qDebug("QSocketNotifier re-enabled!"); 311 qDebug("QSocketNotifier re-enabled!");
315 sn->setEnabled(true); 312 sn->setEnabled(true);
316 } 313 }
317 } 314 }
318} 315}
319 316
320 317
321void Modem::stopNotifier() { 318void Modem::stopNotifier() {
322 if(sn != 0) { 319 if(sn != 0) {
323 sn->setEnabled(false); 320 sn->setEnabled(false);
324 disconnect(sn); 321 disconnect(sn);
325 delete sn; 322 delete sn;
326 sn = 0; 323 sn = 0;
327 qDebug( "QSocketNotifier stopped!" ); 324 qDebug( "QSocketNotifier stopped!" );
328 } 325 }
329} 326}
330 327
331 328
332void Modem::flush() { 329void Modem::flush() {
333 char c; 330 char c;
334 while(read(modemfd, &c, 1) == 1); 331 while(read(modemfd, &c, 1) == 1);
335} 332}
336 333
337 334
338bool Modem::writeChar(unsigned char c) { 335bool Modem::writeChar(unsigned char c) {
339 int s; 336 int s;
340 do { 337 do {
341 s = write(modemfd, &c, 1); 338 s = write(modemfd, &c, 1);
342 if (s < 0) { 339 if (s < 0) {
343 qError( "write() in Modem::writeChar failed" ); 340 qError( "write() in Modem::writeChar failed" );
344 return false; 341 return false;
345 } 342 }
346 } while(s == 0); 343 } while(s == 0);
347 344
348 return true; 345 return true;
349} 346}
350 347
351 348
352bool Modem::writeLine(const char *buf) { 349bool Modem::writeLine(const char *buf) {
353 int len = strlen(buf); 350 int len = strlen(buf);
354 char *b = new char[len+2]; 351 char *b = new char[len+2];
355 memcpy(b, buf, len); 352 memcpy(b, buf, len);
356 // different modems seem to need different line terminations 353 // different modems seem to need different line terminations
357 QString term = _pppdata->enter(); 354 QString term = _pppdata->enter();
358 if(term == "LF") 355 if(term == "LF")
359 b[len++]='\n'; 356 b[len++]='\n';
360 else if(term == "CR") 357 else if(term == "CR")
361 b[len++]='\r'; 358 b[len++]='\r';
362 else if(term == "CR/LF") { 359 else if(term == "CR/LF") {
363 b[len++]='\r'; 360 b[len++]='\r';
364 b[len++]='\n'; 361 b[len++]='\n';
365 } 362 }
366 int l = len; 363 int l = len;
367 while(l) { 364 while(l) {
368 int wr = write(modemfd, &b[len-l], l); 365 int wr = write(modemfd, &b[len-l], l);
369 if(wr < 0) { 366 if(wr < 0) {
370 // TODO do something meaningful with the error code (or ignore it 367 // TODO do something meaningful with the error code (or ignore it
371 qError( "write() in Modem::writeLine failed" ); 368 qError( "write() in Modem::writeLine failed" );
372 delete[] b; 369 delete[] b;
373 return false; 370 return false;
374 } 371 }
375 l -= wr; 372 l -= wr;
376 } 373 }
377 delete[] b; 374 delete[] b;
378 return true; 375 return true;
379} 376}
380 377
381 378
382bool Modem::hangup() { 379bool Modem::hangup() {
383 // this should really get the modem to hang up and go into command mode 380 // this should really get the modem to hang up and go into command mode
384 // If anyone sees a fault in the following please let me know, since 381 // If anyone sees a fault in the following please let me know, since
385 // this is probably the most imporant snippet of code in the whole of 382 // this is probably the most imporant snippet of code in the whole of
386 // kppp. If people complain about kppp being stuck, this piece of code 383 // kppp. If people complain about kppp being stuck, this piece of code
387 // is most likely the reason. 384 // is most likely the reason.
388 struct termios temptty; 385 struct termios temptty;
389 386
390 if(modemfd >= 0) { 387 if(modemfd >= 0) {
391 388
392 // is this Escape & HangupStr stuff really necessary ? (Harri) 389 // is this Escape & HangupStr stuff really necessary ? (Harri)
393 390
394 if (data_mode) escape_to_command_mode(); 391 if (data_mode) escape_to_command_mode();
395 392
396 // Then hangup command 393 // Then hangup command
397 writeLine(_pppdata->modemHangupStr().local8Bit()); 394 writeLine(_pppdata->modemHangupStr().local8Bit());
398 395
399 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 sec 396 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 sec
400 397
401#ifndef DEBUG_WO_DIALING 398#ifndef DEBUG_WO_DIALING
402 if (sigsetjmp(jmp_buffer, 1) == 0) { 399 if (sigsetjmp(jmp_buffer, 1) == 0) {
403 // set alarm in case tcsendbreak() hangs 400 // set alarm in case tcsendbreak() hangs
404 signal(SIGALRM, alarm_handler); 401 signal(SIGALRM, alarm_handler);
405 alarm(2); 402 alarm(2);
406 403
407 tcsendbreak(modemfd, 0); 404 tcsendbreak(modemfd, 0);
408 405
409 alarm(0); 406 alarm(0);
410 signal(SIGALRM, SIG_IGN); 407 signal(SIGALRM, SIG_IGN);
411 } else { 408 } else {
412 // we reach this point if the alarm handler got called 409 // we reach this point if the alarm handler got called
413 closetty(); 410 closetty();
414 close(modemfd); 411 close(modemfd);
415 modemfd = -1; 412 modemfd = -1;
416 errmsg = i18n("The modem does not respond."); 413 errmsg = QObject::tr("The modem does not respond.");
417 return false; 414 return false;
418 } 415 }
419 416
420#ifndef __svr4__ // drops DTR but doesn't set it afterwards again. not good for init. 417#ifndef __svr4__ // drops DTR but doesn't set it afterwards again. not good for init.
421 tcgetattr(modemfd, &temptty); 418 tcgetattr(modemfd, &temptty);
422 cfsetospeed(&temptty, B0); 419 cfsetospeed(&temptty, B0);
423 cfsetispeed(&temptty, B0); 420 cfsetispeed(&temptty, B0);
424 tcsetattr(modemfd, TCSAFLUSH, &temptty); 421 tcsetattr(modemfd, TCSAFLUSH, &temptty);
425#else 422#else
426 int modemstat; 423 int modemstat;
427 ioctl(modemfd, TIOCMGET, &modemstat); 424 ioctl(modemfd, TIOCMGET, &modemstat);
428 modemstat &= ~TIOCM_DTR; 425 modemstat &= ~TIOCM_DTR;
429 ioctl(modemfd, TIOCMSET, &modemstat); 426 ioctl(modemfd, TIOCMSET, &modemstat);
430 ioctl(modemfd, TIOCMGET, &modemstat); 427 ioctl(modemfd, TIOCMGET, &modemstat);
431 modemstat |= TIOCM_DTR; 428 modemstat |= TIOCM_DTR;
432 ioctl(modemfd, TIOCMSET, &modemstat); 429 ioctl(modemfd, TIOCMSET, &modemstat);
433#endif 430#endif
434 431
435 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 secs 432 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 secs
436 433
437 cfsetospeed(&temptty, modemspeed()); 434 cfsetospeed(&temptty, modemspeed());
438 cfsetispeed(&temptty, modemspeed()); 435 cfsetispeed(&temptty, modemspeed());
439 tcsetattr(modemfd, TCSAFLUSH, &temptty); 436 tcsetattr(modemfd, TCSAFLUSH, &temptty);
440#endif 437#endif
441 return true; 438 return true;
442 } else 439 } else
443 return false; 440 return false;
444} 441}
445 442
446 443
447void Modem::escape_to_command_mode() { 444void Modem::escape_to_command_mode() {
448 // Send Properly bracketed escape code to put the modem back into command state. 445 // Send Properly bracketed escape code to put the modem back into command state.
449 // A modem will accept AT commands only when it is in command state. 446 // A modem will accept AT commands only when it is in command state.
450 // When a modem sends the host the CONNECT string, that signals 447 // When a modem sends the host the CONNECT string, that signals
451 // that the modem is now in the connect state (no long accepts AT commands.) 448 // that the modem is now in the connect state (no long accepts AT commands.)
452 // Need to send properly timed escape sequence to put modem in command state. 449 // Need to send properly timed escape sequence to put modem in command state.
453 // Escape codes and guard times are controlled by S2 and S12 values. 450 // Escape codes and guard times are controlled by S2 and S12 values.
454 // 451 //
455 tcflush(modemfd, TCIOFLUSH); 452 tcflush(modemfd, TCIOFLUSH);
456 453
457 // +3 because quiet time must be greater than guard time. 454 // +3 because quiet time must be greater than guard time.
458 usleep((_pppdata->modemEscapeGuardTime()+3)*20000); 455 usleep((_pppdata->modemEscapeGuardTime()+3)*20000);
459 QCString tmp = _pppdata->modemEscapeStr().local8Bit(); 456 QCString tmp = _pppdata->modemEscapeStr().local8Bit();
460 write(modemfd, tmp.data(), tmp.length()); 457 write(modemfd, tmp.data(), tmp.length());
461 tcflush(modemfd, TCIOFLUSH); 458 tcflush(modemfd, TCIOFLUSH);
462 usleep((_pppdata->modemEscapeGuardTime()+3)*20000); 459 usleep((_pppdata->modemEscapeGuardTime()+3)*20000);
463 460
464 data_mode = false; 461 data_mode = false;
465} 462}
466 463
467 464
468const QString Modem::modemMessage() { 465const QString Modem::modemMessage() {
469 return errmsg; 466 return errmsg;
470} 467}
471 468
472 469
473QString Modem::parseModemSpeed(const QString &s) { 470QString Modem::parseModemSpeed(const QString &s) {
474 // this is a small (and bad) parser for modem speeds 471 // this is a small (and bad) parser for modem speeds
475 int rx = -1; 472 int rx = -1;
476 int tx = -1; 473 int tx = -1;
477 int i; 474 int i;
478 QString result; 475 QString result;
479 476
480 qDebug( "Modem reported result string: %s", s.latin1()); 477 qDebug( "Modem reported result string: %s", s.latin1());
481 478
482 const int RXMAX = 7; 479 const int RXMAX = 7;
483 const int TXMAX = 2; 480 const int TXMAX = 2;
484 QRegExp rrx[RXMAX] = { 481 QRegExp rrx[RXMAX] = {
485 QRegExp("[0-9]+[:/ ]RX", false), 482 QRegExp("[0-9]+[:/ ]RX", false),
486 QRegExp("[0-9]+RX", false), 483 QRegExp("[0-9]+RX", false),
487 QRegExp("[/: -][0-9]+[/: ]", false), 484 QRegExp("[/: -][0-9]+[/: ]", false),
488 QRegExp("[/: -][0-9]+$", false), 485 QRegExp("[/: -][0-9]+$", false),
489 QRegExp("CARRIER [^0-9]*[0-9]+", false), 486 QRegExp("CARRIER [^0-9]*[0-9]+", false),
490 QRegExp("CONNECT [^0-9]*[0-9]+", false), 487 QRegExp("CONNECT [^0-9]*[0-9]+", false),
491 QRegExp("[0-9]+") // panic mode 488 QRegExp("[0-9]+") // panic mode
492 }; 489 };
493 490
494 QRegExp trx[TXMAX] = { 491 QRegExp trx[TXMAX] = {
495 QRegExp("[0-9]+[:/ ]TX", false), 492 QRegExp("[0-9]+[:/ ]TX", false),
496 QRegExp("[0-9]+TX", false) 493 QRegExp("[0-9]+TX", false)
497 }; 494 };
498 495
499 for(i = 0; i < RXMAX; i++) { 496 for(i = 0; i < RXMAX; i++) {
500 int len, idx, result; 497 int len, idx, result;
501 if((idx = rrx[i].match(s,0,&len)) > -1) { 498 if((idx = rrx[i].match(s,0,&len)) > -1) {
502// if((idx = rrx[i].search(s)) > -1) { 499// if((idx = rrx[i].search(s)) > -1) {
503 // len = rrx[i].matchedLength(); 500 // len = rrx[i].matchedLength();
504 501
505 // 502 //
506 // rrx[i] has been matched, idx contains the start of the match 503 // rrx[i] has been matched, idx contains the start of the match
507 // and len contains how long the match is. Extract the match. 504 // and len contains how long the match is. Extract the match.
508 // 505 //
509 QString sub = s.mid(idx, len); 506 QString sub = s.mid(idx, len);
510 507
511 // 508 //
512 // Now extract the digits only from the match, which will 509 // Now extract the digits only from the match, which will
513 // then be converted to an int. 510 // then be converted to an int.
514 // 511 //
515 if ((idx = rrx[RXMAX-1].match( sub,0,&len )) > -1) { 512 if ((idx = rrx[RXMAX-1].match( sub,0,&len )) > -1) {
516// if ((idx = rrx[RXMAX-1].search( sub )) > -1) { 513// if ((idx = rrx[RXMAX-1].search( sub )) > -1) {
517// len = rrx[RXMAX-1].matchedLength(); 514// len = rrx[RXMAX-1].matchedLength();
518 sub = sub.mid(idx, len); 515 sub = sub.mid(idx, len);
519 result = sub.toInt(); 516 result = sub.toInt();
520 if(result > 0) { 517 if(result > 0) {
521 rx = result; 518 rx = result;
522 break; 519 break;
523 } 520 }
524 } 521 }
525 } 522 }
526 } 523 }
527 524
528 for(i = 0; i < TXMAX; i++) { 525 for(i = 0; i < TXMAX; i++) {
529 int len, idx, result; 526 int len, idx, result;
530 if((idx = trx[i].match(s,0,&len)) > -1) { 527 if((idx = trx[i].match(s,0,&len)) > -1) {
531// if((idx = trx[i].search(s)) > -1) { 528// if((idx = trx[i].search(s)) > -1) {
532// len = trx[i].matchedLength(); 529// len = trx[i].matchedLength();
533 530
534 // 531 //
535 // trx[i] has been matched, idx contains the start of the match 532 // trx[i] has been matched, idx contains the start of the match
536 // and len contains how long the match is. Extract the match. 533 // and len contains how long the match is. Extract the match.
537 // 534 //
538 QString sub = s.mid(idx, len); 535 QString sub = s.mid(idx, len);
539 536
540 // 537 //
541 // Now extract the digits only from the match, which will then 538 // Now extract the digits only from the match, which will then
542 // be converted to an int. 539 // be converted to an int.
543 // 540 //
544 if((idx = rrx[RXMAX-1].match(sub,0,&len)) > -1) { 541 if((idx = rrx[RXMAX-1].match(sub,0,&len)) > -1) {
545// if((idx = rrx[RXMAX-1].search(sub)) > -1) { 542// if((idx = rrx[RXMAX-1].search(sub)) > -1) {
546// len = rrx[RXMAX-1].matchedLength(); 543// len = rrx[RXMAX-1].matchedLength();
547 sub = sub.mid(idx, len); 544 sub = sub.mid(idx, len);
548 result = sub.toInt(); 545 result = sub.toInt();
549 if(result > 0) { 546 if(result > 0) {
550 tx = result; 547 tx = result;
551 break; 548 break;
552 } 549 }
553 } 550 }
554 } 551 }
555 } 552 }
556 553
557 if(rx == -1 && tx == -1) 554 if(rx == -1 && tx == -1)
558 result = i18n("Unknown speed"); 555 result = QObject::tr("Unknown speed");
559 else if(tx == -1) 556 else if(tx == -1)
560 result.setNum(rx); 557 result.setNum(rx);
561 else if(rx == -1) // should not happen 558 else if(rx == -1) // should not happen
562 result.setNum(tx); 559 result.setNum(tx);
563 else 560 else
564 result.sprintf("%d/%d", rx, tx); 561 result.sprintf("%d/%d", rx, tx);
565 562
566 qDebug( "The parsed result is: %s", result.latin1()); 563 qDebug( "The parsed result is: %s", result.latin1());
567 564
568 return result; 565 return result;
569} 566}
570 567
571 568
572// Lock modem device. Returns 0 on success 1 if the modem is locked and -1 if 569// Lock modem device. Returns 0 on success 1 if the modem is locked and -1 if
573// a lock file can't be created ( permission problem ) 570// a lock file can't be created ( permission problem )
574int Modem::lockdevice() { 571int Modem::lockdevice() {
575 int fd; 572 int fd;
576 char newlock[80]=""; // safe 573 char newlock[80]=""; // safe
577 574
578 if(!_pppdata->modemLockFile()) { 575 if(!_pppdata->modemLockFile()) {
579 qDebug("The user doesn't want a lockfile."); 576 qDebug("The user doesn't want a lockfile.");
580 return 0; 577 return 0;
581 } 578 }
582 579
583 if (modem_is_locked) 580 if (modem_is_locked)
584 return 1; 581 return 1;
585 582
586 QString lockfile = LOCK_DIR"/LCK.."; 583 QString lockfile = LOCK_DIR"/LCK..";
587 lockfile += _pppdata->modemDevice().mid(5); // append everything after /dev/ 584 lockfile += _pppdata->modemDevice().mid(5); // append everything after /dev/
588 585
589 if(access(QFile::encodeName(lockfile), F_OK) == 0) { 586 if(access(QFile::encodeName(lockfile), F_OK) == 0) {
590// if ((fd = Requester::rq-> 587// if ((fd = Requester::rq->
591if ((fd = openLockfile(QFile::encodeName(lockfile), O_RDONLY)) >= 0) { 588if ((fd = openLockfile(QFile::encodeName(lockfile), O_RDONLY)) >= 0) {
592 // Mario: it's not necessary to read more than lets say 32 bytes. If 589 // Mario: it's not necessary to read more than lets say 32 bytes. If
593 // file has more than 32 bytes, skip the rest 590 // file has more than 32 bytes, skip the rest
594 char oldlock[33]; // safe 591 char oldlock[33]; // safe
595 int sz = read(fd, &oldlock, 32); 592 int sz = read(fd, &oldlock, 32);
596 close (fd); 593 close (fd);
597 if (sz <= 0) 594 if (sz <= 0)
598 return 1; 595 return 1;
599 oldlock[sz] = '\0'; 596 oldlock[sz] = '\0';
600 597
601 qDebug( "Device is locked by: %s", oldlock); 598 qDebug( "Device is locked by: %s", oldlock);
602 599
603 int oldpid; 600 int oldpid;
604 int match = sscanf(oldlock, "%d", &oldpid); 601 int match = sscanf(oldlock, "%d", &oldpid);
605 602
606 // found a pid in lockfile ? 603 // found a pid in lockfile ?
607 if (match < 1 || oldpid <= 0) 604 if (match < 1 || oldpid <= 0)
608 return 1; 605 return 1;
609 606
610 // check if process exists 607 // check if process exists
611 if (kill((pid_t)oldpid, 0) == 0 || errno != ESRCH) 608 if (kill((pid_t)oldpid, 0) == 0 || errno != ESRCH)
612 return 1; 609 return 1;
613 610
614 qDebug( "lockfile is stale" ); 611 qDebug( "lockfile is stale" );
615 } 612 }
616 } 613 }
617 614
618 fd = openLockfile(_pppdata->modemDevice(),O_WRONLY|O_TRUNC|O_CREAT); 615 fd = openLockfile(_pppdata->modemDevice(),O_WRONLY|O_TRUNC|O_CREAT);
619 if(fd >= 0) { 616 if(fd >= 0) {
620 sprintf(newlock,"%010d\n", getpid()); 617 sprintf(newlock,"%010d\n", getpid());
621 qDebug("Locking Device: %s", newlock); 618 qDebug("Locking Device: %s", newlock);
622 619
623 write(fd, newlock, strlen(newlock)); 620 write(fd, newlock, strlen(newlock));
624 close(fd); 621 close(fd);
625 modem_is_locked=true; 622 modem_is_locked=true;
626 623
627 return 0; 624 return 0;
628 } 625 }
629 626
630 return -1; 627 return -1;
631 628
632} 629}
633 630
634 631
635// UnLock modem device 632// UnLock modem device
636void Modem::unlockdevice() { 633void Modem::unlockdevice() {
637 if (modem_is_locked) { 634 if (modem_is_locked) {
638 qDebug( "UnLocking Modem Device" ); 635 qDebug( "UnLocking Modem Device" );
639 close(modemfd); 636 close(modemfd);
640 modemfd = -1; 637 modemfd = -1;
641 unlink(lockfile); 638 unlink(lockfile);
642 lockfile[0] = '\0'; 639 lockfile[0] = '\0';
643 modem_is_locked=false; 640 modem_is_locked=false;
644 } 641 }
645} 642}
646 643
647int Modem::openLockfile( QString lockfile, int flags) 644int Modem::openLockfile( QString lockfile, int flags)
648{ 645{
649 int fd; 646 int fd;
650 int mode; 647 int mode;
651 flags = O_RDONLY; 648 flags = O_RDONLY;
652 if(flags == O_WRONLY|O_TRUNC|O_CREAT) 649 if(flags == O_WRONLY|O_TRUNC|O_CREAT)
653 mode = 0644; 650 mode = 0644;
654 else 651 else
@@ -784,240 +781,300 @@ bool Modem::removeAuthFile(Auth method) {
784 } else 781 } else
785 return false; 782 return false;
786} 783}
787 784
788 785
789bool Modem::setSecret(int method, const char* name, const char* password) 786bool Modem::setSecret(int method, const char* name, const char* password)
790{ 787{
791 788
792 Auth auth; 789 Auth auth;
793 if(method == AUTH_PAPCHAP) 790 if(method == AUTH_PAPCHAP)
794 return setSecret(AUTH_PAP, name, password) && 791 return setSecret(AUTH_PAP, name, password) &&
795 setSecret(AUTH_CHAP, name, password); 792 setSecret(AUTH_CHAP, name, password);
796 793
797 switch(method) { 794 switch(method) {
798 case AUTH_PAP: 795 case AUTH_PAP:
799 auth = Modem::PAP; 796 auth = Modem::PAP;
800 break; 797 break;
801 case AUTH_CHAP: 798 case AUTH_CHAP:
802 auth = Modem::CHAP; 799 auth = Modem::CHAP;
803 break; 800 break;
804 default: 801 default:
805 return false; 802 return false;
806 } 803 }
807 804
808 return createAuthFile(auth, name, password); 805 return createAuthFile(auth, name, password);
809 806
810} 807}
811 808
812bool Modem::removeSecret(int method) 809bool Modem::removeSecret(int method)
813{ 810{
814 Auth auth; 811 Auth auth;
815 812
816 switch(method) { 813 switch(method) {
817 case AUTH_PAP: 814 case AUTH_PAP:
818 auth = Modem::PAP; 815 auth = Modem::PAP;
819 break; 816 break;
820 case AUTH_CHAP: 817 case AUTH_CHAP:
821 auth = Modem::CHAP; 818 auth = Modem::CHAP;
822 break; 819 break;
823 default: 820 default:
824 return false; 821 return false;
825 } 822 }
826 return removeAuthFile( auth ); 823 return removeAuthFile( auth );
827} 824}
828 825
829int checkForInterface() 826int checkForInterface()
830{ 827{
831// I don't know if Linux needs more initialization to get the ioctl to 828// I don't know if Linux needs more initialization to get the ioctl to
832// work, pppd seems to hint it does. But BSD doesn't, and the following 829// work, pppd seems to hint it does. But BSD doesn't, and the following
833// code should compile. 830// code should compile.
834#if (defined(HAVE_NET_IF_PPP_H) || defined(HAVE_LINUX_IF_PPP_H)) && !defined(__svr4__) 831#if (defined(HAVE_NET_IF_PPP_H) || defined(HAVE_LINUX_IF_PPP_H)) && !defined(__svr4__)
835 int s, ok; 832 int s, ok;
836 struct ifreq ifr; 833 struct ifreq ifr;
837 // extern char *no_ppp_msg; 834 // extern char *no_ppp_msg;
838 835
839 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 836 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
840 return 1; /* can't tell */ 837 return 1; /* can't tell */
841 838
842 strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); 839 strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
843 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; 840 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
844 close(s); 841 close(s);
845 842
846 if (ok == -1) { 843 if (ok == -1) {
847// This is ifdef'd FreeBSD, because FreeBSD is the only BSD that supports 844// This is ifdef'd FreeBSD, because FreeBSD is the only BSD that supports
848// KLDs, the old LKM interface couldn't handle loading devices 845// KLDs, the old LKM interface couldn't handle loading devices
849// dynamically, and thus can't load ppp support on the fly 846// dynamically, and thus can't load ppp support on the fly
850#ifdef __FreeBSD__ 847#ifdef __FreeBSD__
851 // If we failed to load ppp support and don't have it already. 848 // If we failed to load ppp support and don't have it already.
852 if (kldload("if_ppp") == -1) { 849 if (kldload("if_ppp") == -1) {
853 return -1; 850 return -1;
854 } 851 }
855 return 0; 852 return 0;
856#else 853#else
857 return -1; 854 return -1;
858#endif 855#endif
859 } 856 }
860 return 0; 857 return 0;
861#else 858#else
862// We attempt to use the SunOS/SysVr4 method and stat /dev/ppp 859// We attempt to use the SunOS/SysVr4 method and stat /dev/ppp
863 struct stat buf; 860 struct stat buf;
864 861
865 memset(&buf, 0, sizeof(buf)); 862 memset(&buf, 0, sizeof(buf));
866 return stat("/dev/ppp", &buf); 863 return stat("/dev/ppp", &buf);
867#endif 864#endif
868} 865}
869 866
870bool Modem::execpppd(const char *arguments) { 867bool Modem::execpppd(const char *arguments) {
871 char buf[MAX_CMDLEN]; 868 char buf[MAX_CMDLEN];
872 char *args[MaxArgs]; 869 char *args[MaxArgs];
873 pid_t pgrpid; 870 pid_t pgrpid;
874 871
875 if(modemfd<0) 872 if(modemfd<0)
876 return false; 873 return false;
877 874
878 _pppdExitStatus = -1; 875 _pppdExitStatus = -1;
879 876
877 (void)::pipe( m_pppdLOG );
878
880 switch(pppdPid = fork()) 879 switch(pppdPid = fork())
881 { 880 {
882 case -1: 881 case -1:
883 fprintf(stderr,"In parent: fork() failed\n"); 882 fprintf(stderr,"In parent: fork() failed\n");
883 ::close( m_pppdLOG[0] );
884 ::close( m_pppdLOG[1] );
884 return false; 885 return false;
885 break; 886 break;
886 887
887 case 0: 888 case 0:
888 // let's parse the arguments the user supplied into UNIX suitable form 889 // let's parse the arguments the user supplied into UNIX suitable form
889 // that is a list of pointers each pointing to exactly one word 890 // that is a list of pointers each pointing to exactly one word
890 strlcpy(buf, arguments); 891 strlcpy(buf, arguments);
891 parseargs(buf, args); 892 parseargs(buf, args);
892 // become a session leader and let /dev/ttySx 893 // become a session leader and let /dev/ttySx
893 // be the controlling terminal. 894 // be the controlling terminal.
894 pgrpid = setsid(); 895 pgrpid = setsid();
895#ifdef TIOCSCTTY 896#ifdef TIOCSCTTY
896 if(ioctl(modemfd, TIOCSCTTY, 0)<0) 897 if(ioctl(modemfd, TIOCSCTTY, 0)<0)
897 fprintf(stderr, "ioctl() failed.\n"); 898 fprintf(stderr, "ioctl() failed.\n");
898#elif defined (TIOCSPGRP) 899#elif defined (TIOCSPGRP)
899 if(ioctl(modemfd, TIOCSPGRP, &pgrpid)<0) 900 if(ioctl(modemfd, TIOCSPGRP, &pgrpid)<0)
900 fprintf(stderr, "ioctl() failed.\n"); 901 fprintf(stderr, "ioctl() failed.\n");
901#endif 902#endif
902 if(tcsetpgrp(modemfd, pgrpid)<0) 903 if(tcsetpgrp(modemfd, pgrpid)<0)
903 fprintf(stderr, "tcsetpgrp() failed.\n"); 904 fprintf(stderr, "tcsetpgrp() failed.\n");
904 905
906 ::close( m_pppdLOG[0] );
907 ::setenv( "LANG", "C", 1 ); // overwrite
908 dup2(m_pppdLOG[1], 11 ); // for logfd 11
905 dup2(modemfd, 0); 909 dup2(modemfd, 0);
906 dup2(modemfd, 1); 910 dup2(modemfd, 1);
907 911
912
908 switch (checkForInterface()) { 913 switch (checkForInterface()) {
909 case 1: 914 case 1:
910 fprintf(stderr, "Cannot determine if kernel supports ppp.\n"); 915 fprintf(stderr, "Cannot determine if kernel supports ppp.\n");
911 break; 916 break;
912 case -1: 917 case -1:
913 fprintf(stderr, "Kernel does not support ppp, oops.\n"); 918 fprintf(stderr, "Kernel does not support ppp, oops.\n");
914 break; 919 break;
915 case 0: 920 case 0:
916 fprintf(stderr, "Kernel supports ppp alright.\n"); 921 fprintf(stderr, "Kernel supports ppp alright.\n");
917 break; 922 break;
918 } 923 }
919 924
920 execve(pppdPath(), args, 0L); 925 execve(pppdPath(), args, 0L);
921 _exit(0); 926 _exit(0);
922 break; 927 break;
923 928
924 default: 929 default:
925 qDebug("In parent: pppd pid %d\n",pppdPid); 930 qDebug("In parent: pppd pid %d\n",pppdPid);
926 close(modemfd); 931 close(modemfd);
932
933 ::close( m_pppdLOG[1] );
934 // set it to nonblocking io
935 int flag = ::fcntl( m_pppdLOG[0], F_GETFL );
936
937 if ( !(flag & O_NONBLOCK) ) {
938 qDebug("Setting nonblocking io");
939 flag |= O_NONBLOCK;
940 ::fcntl(m_pppdLOG[0], F_SETFL, flag );
941 }
942
943 delete m_modemDebug;
944 m_modemDebug = new QSocketNotifier(m_pppdLOG[0], QSocketNotifier::Read, this );
945 connect(m_modemDebug, SIGNAL(activated(int) ),
946 this, SLOT(slotModemDebug(int) ) );
947
927 modemfd = -1; 948 modemfd = -1;
949 m_pppdDev = QString::fromLatin1("ppp0");
928 return true; 950 return true;
929 break; 951 break;
930 } 952 }
931} 953}
932 954
933 955
934bool Modem::killpppd() { 956bool Modem::killpppd() {
957 qDebug("In killpppd and pid is %d", pppdPid );
935 if(pppdPid > 0) { 958 if(pppdPid > 0) {
959 delete m_modemDebug;
960 m_modemDebug = 0;
936 qDebug("In killpppd(): Sending SIGTERM to %d\n", pppdPid); 961 qDebug("In killpppd(): Sending SIGTERM to %d\n", pppdPid);
937 if(kill(pppdPid, SIGTERM) < 0) { 962 if(kill(pppdPid, SIGTERM) < 0) {
938 qDebug("Error terminating %d. Sending SIGKILL\n", pppdPid); 963 qDebug("Error terminating %d. Sending SIGKILL\n", pppdPid);
939 if(kill(pppdPid, SIGKILL) < 0) { 964 if(kill(pppdPid, SIGKILL) < 0) {
940 qDebug("Error killing %d\n", pppdPid); 965 qDebug("Error killing %d\n", pppdPid);
941 return false; 966 return false;
942 } 967 }
943 } 968 }
944 } 969 }
945 return true; 970 return true;
946} 971}
947 972
948 973
949void Modem::parseargs(char* buf, char** args) { 974void Modem::parseargs(char* buf, char** args) {
950 int nargs = 0; 975 int nargs = 0;
951 int quotes; 976 int quotes;
952 977
953 while(nargs < MaxArgs-1 && *buf != '\0') { 978 while(nargs < MaxArgs-1 && *buf != '\0') {
954 979
955 quotes = 0; 980 quotes = 0;
956 981
957 // Strip whitespace. Use nulls, so that the previous argument is 982 // Strip whitespace. Use nulls, so that the previous argument is
958 // terminated automatically. 983 // terminated automatically.
959 984
960 while ((*buf == ' ' ) || (*buf == '\t' ) || (*buf == '\n' ) ) 985 while ((*buf == ' ' ) || (*buf == '\t' ) || (*buf == '\n' ) )
961 *buf++ = '\0'; 986 *buf++ = '\0';
962 987
963 // detect begin of quoted argument 988 // detect begin of quoted argument
964 if (*buf == '"' || *buf == '\'') { 989 if (*buf == '"' || *buf == '\'') {
965 quotes = *buf; 990 quotes = *buf;
966 *buf++ = '\0'; 991 *buf++ = '\0';
967 } 992 }
968 993
969 // save the argument 994 // save the argument
970 if(*buf != '\0') { 995 if(*buf != '\0') {
971 *args++ = buf; 996 *args++ = buf;
972 nargs++; 997 nargs++;
973 } 998 }
974 999
975 if (!quotes) 1000 if (!quotes)
976 while ((*buf != '\0') && (*buf != '\n') && 1001 while ((*buf != '\0') && (*buf != '\n') &&
977 (*buf != '\t') && (*buf != ' ')) 1002 (*buf != '\t') && (*buf != ' '))
978 buf++; 1003 buf++;
979 else { 1004 else {
980 while ((*buf != '\0') && (*buf != quotes)) 1005 while ((*buf != '\0') && (*buf != quotes))
981 buf++; 1006 buf++;
982 *buf++ = '\0'; 1007 *buf++ = '\0';
983 } 1008 }
984 } 1009 }
985 1010
986 *args = 0L; 1011 *args = 0L;
987} 1012}
988 1013
989bool Modem::execPPPDaemon(const QString & arguments) 1014bool Modem::execPPPDaemon(const QString & arguments)
990{ 1015{
991 if(execpppd(arguments)) { 1016 if(execpppd(arguments)) {
992 _pppdata->setpppdRunning(true); 1017 _pppdata->setpppdRunning(true);
993 return true; 1018 return true;
994 } else 1019 } else
995 return false; 1020 return false;
996} 1021}
997 1022
998void Modem::killPPPDaemon() 1023void Modem::killPPPDaemon()
999{ 1024{
1000 _pppdata->setpppdRunning(false); 1025 _pppdata->setpppdRunning(false);
1001 killpppd(); 1026 killpppd();
1002} 1027}
1003 1028
1004int Modem::pppdExitStatus() 1029int Modem::pppdExitStatus()
1005{ 1030{
1006 return _pppdExitStatus; 1031 return _pppdExitStatus;
1007} 1032}
1008 1033
1009int Modem::openResolv(int flags) 1034int Modem::openResolv(int flags)
1010{ 1035{
1011 int fd; 1036 int fd;
1012 if ((fd = open(_PATH_RESCONF, flags)) == -1) { 1037 if ((fd = open(_PATH_RESCONF, flags)) == -1) {
1013 qDebug("error opening resolv.conf!"); 1038 qDebug("error opening resolv.conf!");
1014 fd = open(DEVNULL, O_RDONLY); 1039 fd = open(DEVNULL, O_RDONLY);
1015 } 1040 }
1016 return fd; 1041 return fd;
1017} 1042}
1018 1043
1019bool Modem::setHostname(const QString & name) 1044bool Modem::setHostname(const QString & name)
1020{ 1045{
1021 return sethostname(name, name.length()) == 0; 1046 return sethostname(name, name.length()) == 0;
1022} 1047}
1023 1048
1049QString Modem::pppDevice()const {
1050 return m_pppdDev;
1051}
1052void Modem::setPPPDevice( const QString& dev ) {
1053 m_pppdDev = dev;
1054}
1055pid_t Modem::pppPID()const {
1056 return pppdPid;
1057}
1058void Modem::setPPPDPid( pid_t pid ) {
1059 qDebug("Modem setting pid");
1060 _pppdExitStatus = -1;
1061 pppdPid = pid;
1062 modemfd = -1;
1063}
1064void Modem::slotModemDebug(int fd) {
1065 char buf[2049];
1066 int len;
1067
1068 // read in pppd data look for Using interface
1069 // then read the interface
1070 // we limit to 10 device now 0-9
1071 if((len = ::read(fd, buf, 2048)) > 0) {
1072 buf[len+1] = '\0';
1073 char *found;
1074 if ( (found = ::strstr(buf, "Using interface ") ) ) {
1075 found += 16;
1076 m_pppdDev = QString::fromLatin1(found, 5 );
1077 m_pppdDev = m_pppdDev.simplifyWhiteSpace();
1078 }
1079 }
1080}