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.cpp48
1 files changed, 24 insertions, 24 deletions
diff --git a/noncore/settings/networksettings/ppp/modem.cpp b/noncore/settings/networksettings/ppp/modem.cpp
index 3dbc8c3..f3f2639 100644
--- a/noncore/settings/networksettings/ppp/modem.cpp
+++ b/noncore/settings/networksettings/ppp/modem.cpp
@@ -1,1080 +1,1080 @@
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#define qError qDebug 54#define qError qDebug
55 55
56 56
57#define MY_ASSERT(x) if (!(x)) { \ 57#define MY_ASSERT(x) if (!(x)) { \
58 qFatal( "ASSERT: \"%s\" in %s (%d)\n",#x,__FILE__,__LINE__); \ 58 ofatal << "ASSERT: \"" << #x << "\" in " << __FILE__ << " (" << __LINE__ << ")\n" << oendl; \
59 exit(1); } 59 exit(1); }
60 60
61 61
62static sigjmp_buf jmp_buffer; 62static sigjmp_buf jmp_buffer;
63 63
64//Modem *Modem::modem = 0; 64//Modem *Modem::modem = 0;
65 65
66 66
67const char* pppdPath() { 67const char* pppdPath() {
68 // wasting a few bytes 68 // wasting a few bytes
69 static char buffer[sizeof(PPPDSEARCHPATH)+sizeof(PPPDNAME)]; 69 static char buffer[sizeof(PPPDSEARCHPATH)+sizeof(PPPDNAME)];
70 static char *pppdPath = 0L; 70 static char *pppdPath = 0L;
71 char *p; 71 char *p;
72 72
73 if(pppdPath == 0L) { 73 if(pppdPath == 0L) {
74 const char *c = PPPDSEARCHPATH; 74 const char *c = PPPDSEARCHPATH;
75 while(*c != '\0') { 75 while(*c != '\0') {
76 while(*c == ':') 76 while(*c == ':')
77 c++; 77 c++;
78 p = buffer; 78 p = buffer;
79 while(*c != '\0' && *c != ':') 79 while(*c != '\0' && *c != ':')
80 *p++ = *c++; 80 *p++ = *c++;
81 *p = '\0'; 81 *p = '\0';
82 strcat(p, "/"); 82 strcat(p, "/");
83 strcat(p, PPPDNAME); 83 strcat(p, PPPDNAME);
84 if(access(buffer, F_OK) == 0) 84 if(access(buffer, F_OK) == 0)
85 return (pppdPath = buffer); 85 return (pppdPath = buffer);
86 } 86 }
87 } 87 }
88 88
89 return pppdPath; 89 return pppdPath;
90} 90}
91 91
92 92
93Modem::Modem( PPPData* pd ) 93Modem::Modem( PPPData* pd )
94{ 94{
95 _pppdata = pd; 95 _pppdata = pd;
96 modemfd = -1; 96 modemfd = -1;
97 _pppdExitStatus = -1; 97 _pppdExitStatus = -1;
98 pppdPid = -1; 98 pppdPid = -1;
99 sn = m_modemDebug = 0L; 99 sn = m_modemDebug = 0L;
100 data_mode = false; 100 data_mode = false;
101 modem_is_locked = false; 101 modem_is_locked = false;
102 lockfile[0] = '\0'; 102 lockfile[0] = '\0';
103 device = "/dev/modem"; 103 device = "/dev/modem";
104} 104}
105 105
106 106
107Modem::~Modem() 107Modem::~Modem()
108{ 108{
109} 109}
110 110
111 111
112speed_t Modem::modemspeed() { 112speed_t Modem::modemspeed() {
113 // 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
114 // 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
115 // other systems may not have them 115 // other systems may not have them
116 int i = _pppdata->speed().toInt()/100; 116 int i = _pppdata->speed().toInt()/100;
117 117
118 switch(i) { 118 switch(i) {
119 case 24: 119 case 24:
120 return B2400; 120 return B2400;
121 break; 121 break;
122 case 96: 122 case 96:
123 return B9600; 123 return B9600;
124 break; 124 break;
125 case 192: 125 case 192:
126 return B19200; 126 return B19200;
127 break; 127 break;
128 case 384: 128 case 384:
129 return B38400; 129 return B38400;
130 break; 130 break;
131#ifdef B57600 131#ifdef B57600
132 case 576: 132 case 576:
133 return B57600; 133 return B57600;
134 break; 134 break;
135#endif 135#endif
136 136
137#ifdef B115200 137#ifdef B115200
138 case 1152: 138 case 1152:
139 return B115200; 139 return B115200;
140 break; 140 break;
141#endif 141#endif
142 142
143#ifdef B230400 143#ifdef B230400
144 case 2304: 144 case 2304:
145 return B230400; 145 return B230400;
146 break; 146 break;
147#endif 147#endif
148 148
149#ifdef B460800 149#ifdef B460800
150 case 4608: 150 case 4608:
151 return B460800; 151 return B460800;
152 break; 152 break;
153#endif 153#endif
154 154
155 default: 155 default:
156 return B38400; 156 return B38400;
157 break; 157 break;
158 } 158 }
159} 159}
160 160
161bool Modem::opentty() { 161bool Modem::opentty() {
162 // int flags; 162 // int flags;
163 163
164//begin if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) { 164//begin if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) {
165 close(modemfd); 165 close(modemfd);
166 device = _pppdata->modemDevice(); 166 device = _pppdata->modemDevice();
167 if ((modemfd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) == -1) { 167 if ((modemfd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) == -1) {
168 qDebug("error opening modem device !"); 168 odebug << "error opening modem device !" << oendl;
169 errmsg = QObject::tr("Unable to open modem."); 169 errmsg = QObject::tr("Unable to open modem.");
170 return false; 170 return false;
171 } 171 }
172//bend if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) { 172//bend if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) {
173//} 173//}
174 174
175#if 0 175#if 0
176 if(_pppdata->UseCDLine()) { 176 if(_pppdata->UseCDLine()) {
177 if(ioctl(modemfd, TIOCMGET, &flags) == -1) { 177 if(ioctl(modemfd, TIOCMGET, &flags) == -1) {
178 errmsg = QObject::tr("Unable to detect state of CD line."); 178 errmsg = QObject::tr("Unable to detect state of CD line.");
179 ::close(modemfd); 179 ::close(modemfd);
180 modemfd = -1; 180 modemfd = -1;
181 return false; 181 return false;
182 } 182 }
183 if ((flags&TIOCM_CD) == 0) { 183 if ((flags&TIOCM_CD) == 0) {
184 errmsg = QObject::tr("The modem is not ready."); 184 errmsg = QObject::tr("The modem is not ready.");
185 ::close(modemfd); 185 ::close(modemfd);
186 modemfd = -1; 186 modemfd = -1;
187 return false; 187 return false;
188 } 188 }
189 } 189 }
190#endif 190#endif
191 191
192 tcdrain (modemfd); 192 tcdrain (modemfd);
193 tcflush (modemfd, TCIOFLUSH); 193 tcflush (modemfd, TCIOFLUSH);
194 194
195 if(tcgetattr(modemfd, &tty) < 0){ 195 if(tcgetattr(modemfd, &tty) < 0){
196 // this helps in some cases 196 // this helps in some cases
197 tcsendbreak(modemfd, 0); 197 tcsendbreak(modemfd, 0);
198 sleep(1); 198 sleep(1);
199 if(tcgetattr(modemfd, &tty) < 0){ 199 if(tcgetattr(modemfd, &tty) < 0){
200 errmsg = QObject::tr("The modem is busy."); 200 errmsg = QObject::tr("The modem is busy.");
201 ::close(modemfd); 201 ::close(modemfd);
202 modemfd = -1; 202 modemfd = -1;
203 return false; 203 return false;
204 } 204 }
205 } 205 }
206 206
207 memset(&initial_tty,'\0',sizeof(initial_tty)); 207 memset(&initial_tty,'\0',sizeof(initial_tty));
208 208
209 initial_tty = tty; 209 initial_tty = tty;
210 210
211 tty.c_cc[VMIN] = 0; // nonblocking 211 tty.c_cc[VMIN] = 0; // nonblocking
212 tty.c_cc[VTIME] = 0; 212 tty.c_cc[VTIME] = 0;
213 tty.c_oflag = 0; 213 tty.c_oflag = 0;
214 tty.c_lflag = 0; 214 tty.c_lflag = 0;
215 215
216 tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB); 216 tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
217 tty.c_cflag |= CS8 | CREAD; 217 tty.c_cflag |= CS8 | CREAD;
218 tty.c_cflag |= CLOCAL; // ignore modem status lines 218 tty.c_cflag |= CLOCAL; // ignore modem status lines
219 tty.c_iflag = IGNBRK | IGNPAR /* | ISTRIP */ ; 219 tty.c_iflag = IGNBRK | IGNPAR /* | ISTRIP */ ;
220 tty.c_lflag &= ~ICANON; // non-canonical mode 220 tty.c_lflag &= ~ICANON; // non-canonical mode
221 tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE); 221 tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE);
222 222
223 223
224 if(_pppdata->flowcontrol() != "None") { 224 if(_pppdata->flowcontrol() != "None") {
225 if(_pppdata->flowcontrol() == "CRTSCTS") { 225 if(_pppdata->flowcontrol() == "CRTSCTS") {
226 tty.c_cflag |= CRTSCTS; 226 tty.c_cflag |= CRTSCTS;
227 } 227 }
228 else { 228 else {
229 tty.c_iflag |= IXON | IXOFF; 229 tty.c_iflag |= IXON | IXOFF;
230 tty.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ 230 tty.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
231 tty.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ 231 tty.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
232 } 232 }
233 } 233 }
234 else { 234 else {
235 tty.c_cflag &= ~CRTSCTS; 235 tty.c_cflag &= ~CRTSCTS;
236 tty.c_iflag &= ~(IXON | IXOFF); 236 tty.c_iflag &= ~(IXON | IXOFF);
237 } 237 }
238 238
239 cfsetospeed(&tty, modemspeed()); 239 cfsetospeed(&tty, modemspeed());
240 cfsetispeed(&tty, modemspeed()); 240 cfsetispeed(&tty, modemspeed());
241 241
242 tcdrain(modemfd); 242 tcdrain(modemfd);
243 243
244 if(tcsetattr(modemfd, TCSANOW, &tty) < 0){ 244 if(tcsetattr(modemfd, TCSANOW, &tty) < 0){
245 errmsg = QObject::tr("The modem is busy."); 245 errmsg = QObject::tr("The modem is busy.");
246 ::close(modemfd); 246 ::close(modemfd);
247 modemfd=-1; 247 modemfd=-1;
248 return false; 248 return false;
249 } 249 }
250 250
251 errmsg = QObject::tr("Modem Ready."); 251 errmsg = QObject::tr("Modem Ready.");
252 return true; 252 return true;
253} 253}
254 254
255 255
256bool Modem::closetty() { 256bool Modem::closetty() {
257 if(modemfd >=0 ) { 257 if(modemfd >=0 ) {
258 stop(); 258 stop();
259 /* discard data not read or transmitted */ 259 /* discard data not read or transmitted */
260 tcflush(modemfd, TCIOFLUSH); 260 tcflush(modemfd, TCIOFLUSH);
261 261
262 if(tcsetattr(modemfd, TCSANOW, &initial_tty) < 0){ 262 if(tcsetattr(modemfd, TCSANOW, &initial_tty) < 0){
263 errmsg = QObject::tr("Can't restore tty settings: tcsetattr()\n"); 263 errmsg = QObject::tr("Can't restore tty settings: tcsetattr()\n");
264 ::close(modemfd); 264 ::close(modemfd);
265 modemfd = -1; 265 modemfd = -1;
266 return false; 266 return false;
267 } 267 }
268 ::close(modemfd); 268 ::close(modemfd);
269 modemfd = -1; 269 modemfd = -1;
270 } 270 }
271 271
272 return true; 272 return true;
273} 273}
274 274
275 275
276void Modem::readtty(int) { 276void Modem::readtty(int) {
277 char buffer[200]; 277 char buffer[200];
278 unsigned char c; 278 unsigned char c;
279 int len; 279 int len;
280 280
281 // read data in chunks of up to 200 bytes 281 // read data in chunks of up to 200 bytes
282 if((len = ::read(modemfd, buffer, 200)) > 0) { 282 if((len = ::read(modemfd, buffer, 200)) > 0) {
283 // split buffer into single characters for further processing 283 // split buffer into single characters for further processing
284 for(int i = 0; i < len; i++) { 284 for(int i = 0; i < len; i++) {
285 c = buffer[i] & 0x7F; 285 c = buffer[i] & 0x7F;
286 emit charWaiting(c); 286 emit charWaiting(c);
287 } 287 }
288 } 288 }
289} 289}
290 290
291 291
292void Modem::notify(const QObject *receiver, const char *member) { 292void Modem::notify(const QObject *receiver, const char *member) {
293 connect(this, SIGNAL(charWaiting(unsigned char)), receiver, member); 293 connect(this, SIGNAL(charWaiting(unsigned char)), receiver, member);
294 startNotifier(); 294 startNotifier();
295} 295}
296 296
297 297
298void Modem::stop() { 298void Modem::stop() {
299 disconnect(SIGNAL(charWaiting(unsigned char))); 299 disconnect(SIGNAL(charWaiting(unsigned char)));
300 stopNotifier(); 300 stopNotifier();
301} 301}
302 302
303 303
304void Modem::startNotifier() { 304void Modem::startNotifier() {
305 if(modemfd >= 0) { 305 if(modemfd >= 0) {
306 if(sn == 0) { 306 if(sn == 0) {
307 sn = new QSocketNotifier(modemfd, QSocketNotifier::Read, this); 307 sn = new QSocketNotifier(modemfd, QSocketNotifier::Read, this);
308 connect(sn, SIGNAL(activated(int)), SLOT(readtty(int))); 308 connect(sn, SIGNAL(activated(int)), SLOT(readtty(int)));
309 qDebug("QSocketNotifier started!"); 309 odebug << "QSocketNotifier started!" << oendl;
310 } else { 310 } else {
311 qDebug("QSocketNotifier re-enabled!"); 311 odebug << "QSocketNotifier re-enabled!" << oendl;
312 sn->setEnabled(true); 312 sn->setEnabled(true);
313 } 313 }
314 } 314 }
315} 315}
316 316
317 317
318void Modem::stopNotifier() { 318void Modem::stopNotifier() {
319 if(sn != 0) { 319 if(sn != 0) {
320 sn->setEnabled(false); 320 sn->setEnabled(false);
321 disconnect(sn); 321 disconnect(sn);
322 delete sn; 322 delete sn;
323 sn = 0; 323 sn = 0;
324 qDebug( "QSocketNotifier stopped!" ); 324 odebug << "QSocketNotifier stopped!" << oendl;
325 } 325 }
326} 326}
327 327
328 328
329void Modem::flush() { 329void Modem::flush() {
330 char c; 330 char c;
331 while(read(modemfd, &c, 1) == 1); 331 while(read(modemfd, &c, 1) == 1);
332} 332}
333 333
334 334
335bool Modem::writeChar(unsigned char c) { 335bool Modem::writeChar(unsigned char c) {
336 int s; 336 int s;
337 do { 337 do {
338 s = write(modemfd, &c, 1); 338 s = write(modemfd, &c, 1);
339 if (s < 0) { 339 if (s < 0) {
340 qError( "write() in Modem::writeChar failed" ); 340 oerr << "write() in Modem::writeChar failed" << oendl;
341 return false; 341 return false;
342 } 342 }
343 } while(s == 0); 343 } while(s == 0);
344 344
345 return true; 345 return true;
346} 346}
347 347
348 348
349bool Modem::writeLine(const char *buf) { 349bool Modem::writeLine(const char *buf) {
350 int len = strlen(buf); 350 int len = strlen(buf);
351 char *b = new char[len+2]; 351 char *b = new char[len+2];
352 memcpy(b, buf, len); 352 memcpy(b, buf, len);
353 // different modems seem to need different line terminations 353 // different modems seem to need different line terminations
354 QString term = _pppdata->enter(); 354 QString term = _pppdata->enter();
355 if(term == "LF") 355 if(term == "LF")
356 b[len++]='\n'; 356 b[len++]='\n';
357 else if(term == "CR") 357 else if(term == "CR")
358 b[len++]='\r'; 358 b[len++]='\r';
359 else if(term == "CR/LF") { 359 else if(term == "CR/LF") {
360 b[len++]='\r'; 360 b[len++]='\r';
361 b[len++]='\n'; 361 b[len++]='\n';
362 } 362 }
363 int l = len; 363 int l = len;
364 while(l) { 364 while(l) {
365 int wr = write(modemfd, &b[len-l], l); 365 int wr = write(modemfd, &b[len-l], l);
366 if(wr < 0) { 366 if(wr < 0) {
367 // TODO do something meaningful with the error code (or ignore it 367 // TODO do something meaningful with the error code (or ignore it
368 qError( "write() in Modem::writeLine failed" ); 368 oerr << "write() in Modem::writeLine failed" << oendl;
369 delete[] b; 369 delete[] b;
370 return false; 370 return false;
371 } 371 }
372 l -= wr; 372 l -= wr;
373 } 373 }
374 delete[] b; 374 delete[] b;
375 return true; 375 return true;
376} 376}
377 377
378 378
379bool Modem::hangup() { 379bool Modem::hangup() {
380 // 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
381 // 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
382 // 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
383 // 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
384 // is most likely the reason. 384 // is most likely the reason.
385 struct termios temptty; 385 struct termios temptty;
386 386
387 if(modemfd >= 0) { 387 if(modemfd >= 0) {
388 388
389 // is this Escape & HangupStr stuff really necessary ? (Harri) 389 // is this Escape & HangupStr stuff really necessary ? (Harri)
390 390
391 if (data_mode) escape_to_command_mode(); 391 if (data_mode) escape_to_command_mode();
392 392
393 // Then hangup command 393 // Then hangup command
394 writeLine(_pppdata->modemHangupStr().local8Bit()); 394 writeLine(_pppdata->modemHangupStr().local8Bit());
395 395
396 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 sec 396 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 sec
397 397
398#ifndef DEBUG_WO_DIALING 398#ifndef DEBUG_WO_DIALING
399 if (sigsetjmp(jmp_buffer, 1) == 0) { 399 if (sigsetjmp(jmp_buffer, 1) == 0) {
400 // set alarm in case tcsendbreak() hangs 400 // set alarm in case tcsendbreak() hangs
401 signal(SIGALRM, alarm_handler); 401 signal(SIGALRM, alarm_handler);
402 alarm(2); 402 alarm(2);
403 403
404 tcsendbreak(modemfd, 0); 404 tcsendbreak(modemfd, 0);
405 405
406 alarm(0); 406 alarm(0);
407 signal(SIGALRM, SIG_IGN); 407 signal(SIGALRM, SIG_IGN);
408 } else { 408 } else {
409 // we reach this point if the alarm handler got called 409 // we reach this point if the alarm handler got called
410 closetty(); 410 closetty();
411 close(modemfd); 411 close(modemfd);
412 modemfd = -1; 412 modemfd = -1;
413 errmsg = QObject::tr("The modem does not respond."); 413 errmsg = QObject::tr("The modem does not respond.");
414 return false; 414 return false;
415 } 415 }
416 416
417#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.
418 tcgetattr(modemfd, &temptty); 418 tcgetattr(modemfd, &temptty);
419 cfsetospeed(&temptty, B0); 419 cfsetospeed(&temptty, B0);
420 cfsetispeed(&temptty, B0); 420 cfsetispeed(&temptty, B0);
421 tcsetattr(modemfd, TCSAFLUSH, &temptty); 421 tcsetattr(modemfd, TCSAFLUSH, &temptty);
422#else 422#else
423 int modemstat; 423 int modemstat;
424 ioctl(modemfd, TIOCMGET, &modemstat); 424 ioctl(modemfd, TIOCMGET, &modemstat);
425 modemstat &= ~TIOCM_DTR; 425 modemstat &= ~TIOCM_DTR;
426 ioctl(modemfd, TIOCMSET, &modemstat); 426 ioctl(modemfd, TIOCMSET, &modemstat);
427 ioctl(modemfd, TIOCMGET, &modemstat); 427 ioctl(modemfd, TIOCMGET, &modemstat);
428 modemstat |= TIOCM_DTR; 428 modemstat |= TIOCM_DTR;
429 ioctl(modemfd, TIOCMSET, &modemstat); 429 ioctl(modemfd, TIOCMSET, &modemstat);
430#endif 430#endif
431 431
432 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 secs 432 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 secs
433 433
434 cfsetospeed(&temptty, modemspeed()); 434 cfsetospeed(&temptty, modemspeed());
435 cfsetispeed(&temptty, modemspeed()); 435 cfsetispeed(&temptty, modemspeed());
436 tcsetattr(modemfd, TCSAFLUSH, &temptty); 436 tcsetattr(modemfd, TCSAFLUSH, &temptty);
437#endif 437#endif
438 return true; 438 return true;
439 } else 439 } else
440 return false; 440 return false;
441} 441}
442 442
443 443
444void Modem::escape_to_command_mode() { 444void Modem::escape_to_command_mode() {
445 // 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.
446 // 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.
447 // When a modem sends the host the CONNECT string, that signals 447 // When a modem sends the host the CONNECT string, that signals
448 // 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.)
449 // 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.
450 // 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.
451 // 451 //
452 tcflush(modemfd, TCIOFLUSH); 452 tcflush(modemfd, TCIOFLUSH);
453 453
454 // +3 because quiet time must be greater than guard time. 454 // +3 because quiet time must be greater than guard time.
455 usleep((_pppdata->modemEscapeGuardTime()+3)*20000); 455 usleep((_pppdata->modemEscapeGuardTime()+3)*20000);
456 QCString tmp = _pppdata->modemEscapeStr().local8Bit(); 456 QCString tmp = _pppdata->modemEscapeStr().local8Bit();
457 write(modemfd, tmp.data(), tmp.length()); 457 write(modemfd, tmp.data(), tmp.length());
458 tcflush(modemfd, TCIOFLUSH); 458 tcflush(modemfd, TCIOFLUSH);
459 usleep((_pppdata->modemEscapeGuardTime()+3)*20000); 459 usleep((_pppdata->modemEscapeGuardTime()+3)*20000);
460 460
461 data_mode = false; 461 data_mode = false;
462} 462}
463 463
464 464
465const QString Modem::modemMessage() { 465const QString Modem::modemMessage() {
466 return errmsg; 466 return errmsg;
467} 467}
468 468
469 469
470QString Modem::parseModemSpeed(const QString &s) { 470QString Modem::parseModemSpeed(const QString &s) {
471 // this is a small (and bad) parser for modem speeds 471 // this is a small (and bad) parser for modem speeds
472 int rx = -1; 472 int rx = -1;
473 int tx = -1; 473 int tx = -1;
474 int i; 474 int i;
475 QString result; 475 QString result;
476 476
477 qDebug( "Modem reported result string: %s", s.latin1()); 477 odebug << "Modem reported result string: " << s.latin1() << "" << oendl;
478 478
479 const int RXMAX = 7; 479 const int RXMAX = 7;
480 const int TXMAX = 2; 480 const int TXMAX = 2;
481 QRegExp rrx[RXMAX] = { 481 QRegExp rrx[RXMAX] = {
482 QRegExp("[0-9]+[:/ ]RX", false), 482 QRegExp("[0-9]+[:/ ]RX", false),
483 QRegExp("[0-9]+RX", false), 483 QRegExp("[0-9]+RX", false),
484 QRegExp("[/: -][0-9]+[/: ]", false), 484 QRegExp("[/: -][0-9]+[/: ]", false),
485 QRegExp("[/: -][0-9]+$", false), 485 QRegExp("[/: -][0-9]+$", false),
486 QRegExp("CARRIER [^0-9]*[0-9]+", false), 486 QRegExp("CARRIER [^0-9]*[0-9]+", false),
487 QRegExp("CONNECT [^0-9]*[0-9]+", false), 487 QRegExp("CONNECT [^0-9]*[0-9]+", false),
488 QRegExp("[0-9]+") // panic mode 488 QRegExp("[0-9]+") // panic mode
489 }; 489 };
490 490
491 QRegExp trx[TXMAX] = { 491 QRegExp trx[TXMAX] = {
492 QRegExp("[0-9]+[:/ ]TX", false), 492 QRegExp("[0-9]+[:/ ]TX", false),
493 QRegExp("[0-9]+TX", false) 493 QRegExp("[0-9]+TX", false)
494 }; 494 };
495 495
496 for(i = 0; i < RXMAX; i++) { 496 for(i = 0; i < RXMAX; i++) {
497 int len, idx, result; 497 int len, idx, result;
498 if((idx = rrx[i].match(s,0,&len)) > -1) { 498 if((idx = rrx[i].match(s,0,&len)) > -1) {
499// if((idx = rrx[i].search(s)) > -1) { 499// if((idx = rrx[i].search(s)) > -1) {
500 // len = rrx[i].matchedLength(); 500 // len = rrx[i].matchedLength();
501 501
502 // 502 //
503 // 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
504 // and len contains how long the match is. Extract the match. 504 // and len contains how long the match is. Extract the match.
505 // 505 //
506 QString sub = s.mid(idx, len); 506 QString sub = s.mid(idx, len);
507 507
508 // 508 //
509 // Now extract the digits only from the match, which will 509 // Now extract the digits only from the match, which will
510 // then be converted to an int. 510 // then be converted to an int.
511 // 511 //
512 if ((idx = rrx[RXMAX-1].match( sub,0,&len )) > -1) { 512 if ((idx = rrx[RXMAX-1].match( sub,0,&len )) > -1) {
513// if ((idx = rrx[RXMAX-1].search( sub )) > -1) { 513// if ((idx = rrx[RXMAX-1].search( sub )) > -1) {
514// len = rrx[RXMAX-1].matchedLength(); 514// len = rrx[RXMAX-1].matchedLength();
515 sub = sub.mid(idx, len); 515 sub = sub.mid(idx, len);
516 result = sub.toInt(); 516 result = sub.toInt();
517 if(result > 0) { 517 if(result > 0) {
518 rx = result; 518 rx = result;
519 break; 519 break;
520 } 520 }
521 } 521 }
522 } 522 }
523 } 523 }
524 524
525 for(i = 0; i < TXMAX; i++) { 525 for(i = 0; i < TXMAX; i++) {
526 int len, idx, result; 526 int len, idx, result;
527 if((idx = trx[i].match(s,0,&len)) > -1) { 527 if((idx = trx[i].match(s,0,&len)) > -1) {
528// if((idx = trx[i].search(s)) > -1) { 528// if((idx = trx[i].search(s)) > -1) {
529// len = trx[i].matchedLength(); 529// len = trx[i].matchedLength();
530 530
531 // 531 //
532 // 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
533 // and len contains how long the match is. Extract the match. 533 // and len contains how long the match is. Extract the match.
534 // 534 //
535 QString sub = s.mid(idx, len); 535 QString sub = s.mid(idx, len);
536 536
537 // 537 //
538 // Now extract the digits only from the match, which will then 538 // Now extract the digits only from the match, which will then
539 // be converted to an int. 539 // be converted to an int.
540 // 540 //
541 if((idx = rrx[RXMAX-1].match(sub,0,&len)) > -1) { 541 if((idx = rrx[RXMAX-1].match(sub,0,&len)) > -1) {
542// if((idx = rrx[RXMAX-1].search(sub)) > -1) { 542// if((idx = rrx[RXMAX-1].search(sub)) > -1) {
543// len = rrx[RXMAX-1].matchedLength(); 543// len = rrx[RXMAX-1].matchedLength();
544 sub = sub.mid(idx, len); 544 sub = sub.mid(idx, len);
545 result = sub.toInt(); 545 result = sub.toInt();
546 if(result > 0) { 546 if(result > 0) {
547 tx = result; 547 tx = result;
548 break; 548 break;
549 } 549 }
550 } 550 }
551 } 551 }
552 } 552 }
553 553
554 if(rx == -1 && tx == -1) 554 if(rx == -1 && tx == -1)
555 result = QObject::tr("Unknown speed"); 555 result = QObject::tr("Unknown speed");
556 else if(tx == -1) 556 else if(tx == -1)
557 result.setNum(rx); 557 result.setNum(rx);
558 else if(rx == -1) // should not happen 558 else if(rx == -1) // should not happen
559 result.setNum(tx); 559 result.setNum(tx);
560 else 560 else
561 result.sprintf("%d/%d", rx, tx); 561 result.sprintf("%d/%d", rx, tx);
562 562
563 qDebug( "The parsed result is: %s", result.latin1()); 563 odebug << "The parsed result is: " << result.latin1() << "" << oendl;
564 564
565 return result; 565 return result;
566} 566}
567 567
568 568
569// 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
570// a lock file can't be created ( permission problem ) 570// a lock file can't be created ( permission problem )
571int Modem::lockdevice() { 571int Modem::lockdevice() {
572 int fd; 572 int fd;
573 char newlock[80]=""; // safe 573 char newlock[80]=""; // safe
574 574
575 if(!_pppdata->modemLockFile()) { 575 if(!_pppdata->modemLockFile()) {
576 qDebug("The user doesn't want a lockfile."); 576 odebug << "The user doesn't want a lockfile." << oendl;
577 return 0; 577 return 0;
578 } 578 }
579 579
580 if (modem_is_locked) 580 if (modem_is_locked)
581 return 1; 581 return 1;
582 582
583 QString lockfile = LOCK_DIR"/LCK.."; 583 QString lockfile = LOCK_DIR"/LCK..";
584 lockfile += _pppdata->modemDevice().mid(5); // append everything after /dev/ 584 lockfile += _pppdata->modemDevice().mid(5); // append everything after /dev/
585 585
586 if(access(QFile::encodeName(lockfile), F_OK) == 0) { 586 if(access(QFile::encodeName(lockfile), F_OK) == 0) {
587// if ((fd = Requester::rq-> 587// if ((fd = Requester::rq->
588if ((fd = openLockfile(QFile::encodeName(lockfile), O_RDONLY)) >= 0) { 588if ((fd = openLockfile(QFile::encodeName(lockfile), O_RDONLY)) >= 0) {
589 // 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
590 // file has more than 32 bytes, skip the rest 590 // file has more than 32 bytes, skip the rest
591 char oldlock[33]; // safe 591 char oldlock[33]; // safe
592 int sz = read(fd, &oldlock, 32); 592 int sz = read(fd, &oldlock, 32);
593 close (fd); 593 close (fd);
594 if (sz <= 0) 594 if (sz <= 0)
595 return 1; 595 return 1;
596 oldlock[sz] = '\0'; 596 oldlock[sz] = '\0';
597 597
598 qDebug( "Device is locked by: %s", oldlock); 598 odebug << "Device is locked by: " << oldlock << "" << oendl;
599 599
600 int oldpid; 600 int oldpid;
601 int match = sscanf(oldlock, "%d", &oldpid); 601 int match = sscanf(oldlock, "%d", &oldpid);
602 602
603 // found a pid in lockfile ? 603 // found a pid in lockfile ?
604 if (match < 1 || oldpid <= 0) 604 if (match < 1 || oldpid <= 0)
605 return 1; 605 return 1;
606 606
607 // check if process exists 607 // check if process exists
608 if (kill((pid_t)oldpid, 0) == 0 || errno != ESRCH) 608 if (kill((pid_t)oldpid, 0) == 0 || errno != ESRCH)
609 return 1; 609 return 1;
610 610
611 qDebug( "lockfile is stale" ); 611 odebug << "lockfile is stale" << oendl;
612 } 612 }
613 } 613 }
614 614
615 fd = openLockfile(_pppdata->modemDevice(),O_WRONLY|O_TRUNC|O_CREAT); 615 fd = openLockfile(_pppdata->modemDevice(),O_WRONLY|O_TRUNC|O_CREAT);
616 if(fd >= 0) { 616 if(fd >= 0) {
617 sprintf(newlock,"%010d\n", getpid()); 617 sprintf(newlock,"%010d\n", getpid());
618 qDebug("Locking Device: %s", newlock); 618 odebug << "Locking Device: " << newlock << "" << oendl;
619 619
620 write(fd, newlock, strlen(newlock)); 620 write(fd, newlock, strlen(newlock));
621 close(fd); 621 close(fd);
622 modem_is_locked=true; 622 modem_is_locked=true;
623 623
624 return 0; 624 return 0;
625 } 625 }
626 626
627 return -1; 627 return -1;
628 628
629} 629}
630 630
631 631
632// UnLock modem device 632// UnLock modem device
633void Modem::unlockdevice() { 633void Modem::unlockdevice() {
634 if (modem_is_locked) { 634 if (modem_is_locked) {
635 qDebug( "UnLocking Modem Device" ); 635 odebug << "UnLocking Modem Device" << oendl;
636 close(modemfd); 636 close(modemfd);
637 modemfd = -1; 637 modemfd = -1;
638 unlink(lockfile); 638 unlink(lockfile);
639 lockfile[0] = '\0'; 639 lockfile[0] = '\0';
640 modem_is_locked=false; 640 modem_is_locked=false;
641 } 641 }
642} 642}
643 643
644int Modem::openLockfile( QString lockfile, int flags) 644int Modem::openLockfile( QString lockfile, int flags)
645{ 645{
646 int fd; 646 int fd;
647 int mode; 647 int mode;
648 flags = O_RDONLY; 648 flags = O_RDONLY;
649 if(flags == O_WRONLY|O_TRUNC|O_CREAT) 649 if(flags == O_WRONLY|O_TRUNC|O_CREAT)
650 mode = 0644; 650 mode = 0644;
651 else 651 else
652 mode = 0; 652 mode = 0;
653 653
654 lockfile = LOCK_DIR; 654 lockfile = LOCK_DIR;
655 lockfile += "/LCK.."; 655 lockfile += "/LCK..";
656 lockfile += device.right( device.length() - device.findRev("/") -1 ); 656 lockfile += device.right( device.length() - device.findRev("/") -1 );
657 qDebug("lockfile >%s<",lockfile.latin1()); 657 odebug << "lockfile >" << lockfile.latin1() << "<" << oendl;
658 // TODO: 658 // TODO:
659 // struct stat st; 659 // struct stat st;
660 // if(stat(lockfile.data(), &st) == -1) { 660 // if(stat(lockfile.data(), &st) == -1) {
661 // if(errno == EBADF) 661 // if(errno == EBADF)
662 // return -1; 662 // return -1;
663 // } else { 663 // } else {
664 // // make sure that this is a regular file 664 // // make sure that this is a regular file
665 // if(!S_ISREG(st.st_mode)) 665 // if(!S_ISREG(st.st_mode))
666 // return -1; 666 // return -1;
667 // } 667 // }
668 if ((fd = open(lockfile, flags, mode)) == -1) { 668 if ((fd = open(lockfile, flags, mode)) == -1) {
669 qDebug("error opening lockfile!"); 669 odebug << "error opening lockfile!" << oendl;
670 lockfile = QString::null; 670 lockfile = QString::null;
671 fd = open(DEVNULL, O_RDONLY); 671 fd = open(DEVNULL, O_RDONLY);
672 } else 672 } else
673 fchown(fd, 0, 0); 673 fchown(fd, 0, 0);
674 return fd; 674 return fd;
675} 675}
676 676
677 677
678 678
679void alarm_handler(int) { 679void alarm_handler(int) {
680 // fprintf(stderr, "alarm_handler(): Received SIGALRM\n"); 680 // fprintf(stderr, "alarm_handler(): Received SIGALRM\n");
681 681
682 // jump 682 // jump
683 siglongjmp(jmp_buffer, 1); 683 siglongjmp(jmp_buffer, 1);
684} 684}
685 685
686 686
687const char* Modem::authFile(Auth method, int version) { 687const char* Modem::authFile(Auth method, int version) {
688 switch(method|version) { 688 switch(method|version) {
689 case PAP|Original: 689 case PAP|Original:
690 return PAP_AUTH_FILE; 690 return PAP_AUTH_FILE;
691 break; 691 break;
692 case PAP|New: 692 case PAP|New:
693 return PAP_AUTH_FILE".new"; 693 return PAP_AUTH_FILE".new";
694 break; 694 break;
695 case PAP|Old: 695 case PAP|Old:
696 return PAP_AUTH_FILE".old"; 696 return PAP_AUTH_FILE".old";
697 break; 697 break;
698 case CHAP|Original: 698 case CHAP|Original:
699 return CHAP_AUTH_FILE; 699 return CHAP_AUTH_FILE;
700 break; 700 break;
701 case CHAP|New: 701 case CHAP|New:
702 return CHAP_AUTH_FILE".new"; 702 return CHAP_AUTH_FILE".new";
703 break; 703 break;
704 case CHAP|Old: 704 case CHAP|Old:
705 return CHAP_AUTH_FILE".old"; 705 return CHAP_AUTH_FILE".old";
706 break; 706 break;
707 default: 707 default:
708 return 0L; 708 return 0L;
709 } 709 }
710} 710}
711 711
712 712
713bool Modem::createAuthFile(Auth method, const char *username, const char *password) { 713bool Modem::createAuthFile(Auth method, const char *username, const char *password) {
714 const char *authfile, *oldName, *newName; 714 const char *authfile, *oldName, *newName;
715 char line[100]; 715 char line[100];
716 char regexp[2*MaxStrLen+30]; 716 char regexp[2*MaxStrLen+30];
717 regex_t preg; 717 regex_t preg;
718 718
719 if(!(authfile = authFile(method))) 719 if(!(authfile = authFile(method)))
720 return false; 720 return false;
721 721
722 if(!(newName = authFile(method, New))) 722 if(!(newName = authFile(method, New)))
723 return false; 723 return false;
724 724
725 // look for username, "username" or 'username' 725 // look for username, "username" or 'username'
726 // if you modify this RE you have to adapt regexp's size above 726 // if you modify this RE you have to adapt regexp's size above
727 snprintf(regexp, sizeof(regexp), "^[ \t]*%s[ \t]\\|^[ \t]*[\"\']%s[\"\']", 727 snprintf(regexp, sizeof(regexp), "^[ \t]*%s[ \t]\\|^[ \t]*[\"\']%s[\"\']",
728 username,username); 728 username,username);
729 MY_ASSERT(regcomp(&preg, regexp, 0) == 0); 729 MY_ASSERT(regcomp(&preg, regexp, 0) == 0);
730 730
731 // copy to new file pap- or chap-secrets 731 // copy to new file pap- or chap-secrets
732 int old_umask = umask(0077); 732 int old_umask = umask(0077);
733 FILE *fout = fopen(newName, "w"); 733 FILE *fout = fopen(newName, "w");
734 if(fout) { 734 if(fout) {
735 // copy old file 735 // copy old file
736 FILE *fin = fopen(authfile, "r"); 736 FILE *fin = fopen(authfile, "r");
737 if(fin) { 737 if(fin) {
738 while(fgets(line, sizeof(line), fin)) { 738 while(fgets(line, sizeof(line), fin)) {
739 if(regexec(&preg, line, 0, 0L, 0) == 0) 739 if(regexec(&preg, line, 0, 0L, 0) == 0)
740 continue; 740 continue;
741 fputs(line, fout); 741 fputs(line, fout);
742 } 742 }
743 fclose(fin); 743 fclose(fin);
744 } 744 }
745 745
746 // append user/pass pair 746 // append user/pass pair
747 fprintf(fout, "\"%s\"\t*\t\"%s\"\n", username, password); 747 fprintf(fout, "\"%s\"\t*\t\"%s\"\n", username, password);
748 fclose(fout); 748 fclose(fout);
749 } 749 }
750 750
751 // restore umask 751 // restore umask
752 umask(old_umask); 752 umask(old_umask);
753 753
754 // free memory allocated by regcomp 754 // free memory allocated by regcomp
755 regfree(&preg); 755 regfree(&preg);
756 756
757 if(!(oldName = authFile(method, Old))) 757 if(!(oldName = authFile(method, Old)))
758 return false; 758 return false;
759 759
760 // delete old file if any 760 // delete old file if any
761 unlink(oldName); 761 unlink(oldName);
762 762
763 rename(authfile, oldName); 763 rename(authfile, oldName);
764 rename(newName, authfile); 764 rename(newName, authfile);
765 765
766 return true; 766 return true;
767} 767}
768 768
769 769
770bool Modem::removeAuthFile(Auth method) { 770bool Modem::removeAuthFile(Auth method) {
771 const char *authfile, *oldName; 771 const char *authfile, *oldName;
772 772
773 if(!(authfile = authFile(method))) 773 if(!(authfile = authFile(method)))
774 return false; 774 return false;
775 if(!(oldName = authFile(method, Old))) 775 if(!(oldName = authFile(method, Old)))
776 return false; 776 return false;
777 777
778 if(access(oldName, F_OK) == 0) { 778 if(access(oldName, F_OK) == 0) {
779 unlink(authfile); 779 unlink(authfile);
780 return (rename(oldName, authfile) == 0); 780 return (rename(oldName, authfile) == 0);
781 } else 781 } else
782 return false; 782 return false;
783} 783}
784 784
785 785
786bool Modem::setSecret(int method, const char* name, const char* password) 786bool Modem::setSecret(int method, const char* name, const char* password)
787{ 787{
788 788
789 Auth auth; 789 Auth auth;
790 if(method == AUTH_PAPCHAP) 790 if(method == AUTH_PAPCHAP)
791 return setSecret(AUTH_PAP, name, password) && 791 return setSecret(AUTH_PAP, name, password) &&
792 setSecret(AUTH_CHAP, name, password); 792 setSecret(AUTH_CHAP, name, password);
793 793
794 switch(method) { 794 switch(method) {
795 case AUTH_PAP: 795 case AUTH_PAP:
796 auth = Modem::PAP; 796 auth = Modem::PAP;
797 break; 797 break;
798 case AUTH_CHAP: 798 case AUTH_CHAP:
799 auth = Modem::CHAP; 799 auth = Modem::CHAP;
800 break; 800 break;
801 default: 801 default:
802 return false; 802 return false;
803 } 803 }
804 804
805 return createAuthFile(auth, name, password); 805 return createAuthFile(auth, name, password);
806 806
807} 807}
808 808
809bool Modem::removeSecret(int method) 809bool Modem::removeSecret(int method)
810{ 810{
811 Auth auth; 811 Auth auth;
812 812
813 switch(method) { 813 switch(method) {
814 case AUTH_PAP: 814 case AUTH_PAP:
815 auth = Modem::PAP; 815 auth = Modem::PAP;
816 break; 816 break;
817 case AUTH_CHAP: 817 case AUTH_CHAP:
818 auth = Modem::CHAP; 818 auth = Modem::CHAP;
819 break; 819 break;
820 default: 820 default:
821 return false; 821 return false;
822 } 822 }
823 return removeAuthFile( auth ); 823 return removeAuthFile( auth );
824} 824}
825 825
826int checkForInterface() 826int checkForInterface()
827{ 827{
828// 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
829// 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
830// code should compile. 830// code should compile.
831#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__)
832 int s, ok; 832 int s, ok;
833 struct ifreq ifr; 833 struct ifreq ifr;
834 // extern char *no_ppp_msg; 834 // extern char *no_ppp_msg;
835 835
836 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 836 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
837 return 1; /* can't tell */ 837 return 1; /* can't tell */
838 838
839 strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); 839 strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
840 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; 840 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
841 close(s); 841 close(s);
842 842
843 if (ok == -1) { 843 if (ok == -1) {
844// 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
845// KLDs, the old LKM interface couldn't handle loading devices 845// KLDs, the old LKM interface couldn't handle loading devices
846// dynamically, and thus can't load ppp support on the fly 846// dynamically, and thus can't load ppp support on the fly
847#ifdef __FreeBSD__ 847#ifdef __FreeBSD__
848 // 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.
849 if (kldload("if_ppp") == -1) { 849 if (kldload("if_ppp") == -1) {
850 return -1; 850 return -1;
851 } 851 }
852 return 0; 852 return 0;
853#else 853#else
854 return -1; 854 return -1;
855#endif 855#endif
856 } 856 }
857 return 0; 857 return 0;
858#else 858#else
859// 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
860 struct stat buf; 860 struct stat buf;
861 861
862 memset(&buf, 0, sizeof(buf)); 862 memset(&buf, 0, sizeof(buf));
863 return stat("/dev/ppp", &buf); 863 return stat("/dev/ppp", &buf);
864#endif 864#endif
865} 865}
866 866
867bool Modem::execpppd(const char *arguments) { 867bool Modem::execpppd(const char *arguments) {
868 char buf[MAX_CMDLEN]; 868 char buf[MAX_CMDLEN];
869 char *args[MaxArgs]; 869 char *args[MaxArgs];
870 pid_t pgrpid; 870 pid_t pgrpid;
871 871
872 if(modemfd<0) 872 if(modemfd<0)
873 return false; 873 return false;
874 874
875 _pppdExitStatus = -1; 875 _pppdExitStatus = -1;
876 876
877 (void)::pipe( m_pppdLOG ); 877 (void)::pipe( m_pppdLOG );
878 878
879 switch(pppdPid = fork()) 879 switch(pppdPid = fork())
880 { 880 {
881 case -1: 881 case -1:
882 fprintf(stderr,"In parent: fork() failed\n"); 882 fprintf(stderr,"In parent: fork() failed\n");
883 ::close( m_pppdLOG[0] ); 883 ::close( m_pppdLOG[0] );
884 ::close( m_pppdLOG[1] ); 884 ::close( m_pppdLOG[1] );
885 return false; 885 return false;
886 break; 886 break;
887 887
888 case 0: 888 case 0:
889 // 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
890 // 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
891 strlcpy(buf, arguments); 891 strlcpy(buf, arguments);
892 parseargs(buf, args); 892 parseargs(buf, args);
893 // become a session leader and let /dev/ttySx 893 // become a session leader and let /dev/ttySx
894 // be the controlling terminal. 894 // be the controlling terminal.
895 pgrpid = setsid(); 895 pgrpid = setsid();
896#ifdef TIOCSCTTY 896#ifdef TIOCSCTTY
897 if(ioctl(modemfd, TIOCSCTTY, 0)<0) 897 if(ioctl(modemfd, TIOCSCTTY, 0)<0)
898 fprintf(stderr, "ioctl() failed.\n"); 898 fprintf(stderr, "ioctl() failed.\n");
899#elif defined (TIOCSPGRP) 899#elif defined (TIOCSPGRP)
900 if(ioctl(modemfd, TIOCSPGRP, &pgrpid)<0) 900 if(ioctl(modemfd, TIOCSPGRP, &pgrpid)<0)
901 fprintf(stderr, "ioctl() failed.\n"); 901 fprintf(stderr, "ioctl() failed.\n");
902#endif 902#endif
903 if(tcsetpgrp(modemfd, pgrpid)<0) 903 if(tcsetpgrp(modemfd, pgrpid)<0)
904 fprintf(stderr, "tcsetpgrp() failed.\n"); 904 fprintf(stderr, "tcsetpgrp() failed.\n");
905 905
906 ::close( m_pppdLOG[0] ); 906 ::close( m_pppdLOG[0] );
907 ::setenv( "LANG", "C", 1 ); // overwrite 907 ::setenv( "LANG", "C", 1 ); // overwrite
908 dup2(m_pppdLOG[1], 11 ); // for logfd 11 908 dup2(m_pppdLOG[1], 11 ); // for logfd 11
909 dup2(modemfd, 0); 909 dup2(modemfd, 0);
910 dup2(modemfd, 1); 910 dup2(modemfd, 1);
911 911
912 912
913 switch (checkForInterface()) { 913 switch (checkForInterface()) {
914 case 1: 914 case 1:
915 fprintf(stderr, "Cannot determine if kernel supports ppp.\n"); 915 fprintf(stderr, "Cannot determine if kernel supports ppp.\n");
916 break; 916 break;
917 case -1: 917 case -1:
918 fprintf(stderr, "Kernel does not support ppp, oops.\n"); 918 fprintf(stderr, "Kernel does not support ppp, oops.\n");
919 break; 919 break;
920 case 0: 920 case 0:
921 fprintf(stderr, "Kernel supports ppp alright.\n"); 921 fprintf(stderr, "Kernel supports ppp alright.\n");
922 break; 922 break;
923 } 923 }
924 924
925 execve(pppdPath(), args, 0L); 925 execve(pppdPath(), args, 0L);
926 _exit(0); 926 _exit(0);
927 break; 927 break;
928 928
929 default: 929 default:
930 qDebug("In parent: pppd pid %d\n",pppdPid); 930 odebug << "In parent: pppd pid " << pppdPid << "\n" << oendl;
931 close(modemfd); 931 close(modemfd);
932 932
933 ::close( m_pppdLOG[1] ); 933 ::close( m_pppdLOG[1] );
934 // set it to nonblocking io 934 // set it to nonblocking io
935 int flag = ::fcntl( m_pppdLOG[0], F_GETFL ); 935 int flag = ::fcntl( m_pppdLOG[0], F_GETFL );
936 936
937 if ( !(flag & O_NONBLOCK) ) { 937 if ( !(flag & O_NONBLOCK) ) {
938 qDebug("Setting nonblocking io"); 938 odebug << "Setting nonblocking io" << oendl;
939 flag |= O_NONBLOCK; 939 flag |= O_NONBLOCK;
940 ::fcntl(m_pppdLOG[0], F_SETFL, flag ); 940 ::fcntl(m_pppdLOG[0], F_SETFL, flag );
941 } 941 }
942 942
943 delete m_modemDebug; 943 delete m_modemDebug;
944 m_modemDebug = new QSocketNotifier(m_pppdLOG[0], QSocketNotifier::Read, this ); 944 m_modemDebug = new QSocketNotifier(m_pppdLOG[0], QSocketNotifier::Read, this );
945 connect(m_modemDebug, SIGNAL(activated(int) ), 945 connect(m_modemDebug, SIGNAL(activated(int) ),
946 this, SLOT(slotModemDebug(int) ) ); 946 this, SLOT(slotModemDebug(int) ) );
947 947
948 modemfd = -1; 948 modemfd = -1;
949 m_pppdDev = QString::fromLatin1("ppp0"); 949 m_pppdDev = QString::fromLatin1("ppp0");
950 return true; 950 return true;
951 break; 951 break;
952 } 952 }
953} 953}
954 954
955 955
956bool Modem::killpppd() { 956bool Modem::killpppd() {
957 qDebug("In killpppd and pid is %d", pppdPid ); 957 odebug << "In killpppd and pid is " << pppdPid << "" << oendl;
958 if(pppdPid > 0) { 958 if(pppdPid > 0) {
959 delete m_modemDebug; 959 delete m_modemDebug;
960 m_modemDebug = 0; 960 m_modemDebug = 0;
961 qDebug("In killpppd(): Sending SIGTERM to %d\n", pppdPid); 961 odebug << "In killpppd(): Sending SIGTERM to " << pppdPid << "\n" << oendl;
962 if(kill(pppdPid, SIGTERM) < 0) { 962 if(kill(pppdPid, SIGTERM) < 0) {
963 qDebug("Error terminating %d. Sending SIGKILL\n", pppdPid); 963 odebug << "Error terminating " << pppdPid << ". Sending SIGKILL\n" << oendl;
964 if(kill(pppdPid, SIGKILL) < 0) { 964 if(kill(pppdPid, SIGKILL) < 0) {
965 qDebug("Error killing %d\n", pppdPid); 965 odebug << "Error killing " << pppdPid << "\n" << oendl;
966 return false; 966 return false;
967 } 967 }
968 } 968 }
969 } 969 }
970 return true; 970 return true;
971} 971}
972 972
973 973
974void Modem::parseargs(char* buf, char** args) { 974void Modem::parseargs(char* buf, char** args) {
975 int nargs = 0; 975 int nargs = 0;
976 int quotes; 976 int quotes;
977 977
978 while(nargs < MaxArgs-1 && *buf != '\0') { 978 while(nargs < MaxArgs-1 && *buf != '\0') {
979 979
980 quotes = 0; 980 quotes = 0;
981 981
982 // Strip whitespace. Use nulls, so that the previous argument is 982 // Strip whitespace. Use nulls, so that the previous argument is
983 // terminated automatically. 983 // terminated automatically.
984 984
985 while ((*buf == ' ' ) || (*buf == '\t' ) || (*buf == '\n' ) ) 985 while ((*buf == ' ' ) || (*buf == '\t' ) || (*buf == '\n' ) )
986 *buf++ = '\0'; 986 *buf++ = '\0';
987 987
988 // detect begin of quoted argument 988 // detect begin of quoted argument
989 if (*buf == '"' || *buf == '\'') { 989 if (*buf == '"' || *buf == '\'') {
990 quotes = *buf; 990 quotes = *buf;
991 *buf++ = '\0'; 991 *buf++ = '\0';
992 } 992 }
993 993
994 // save the argument 994 // save the argument
995 if(*buf != '\0') { 995 if(*buf != '\0') {
996 *args++ = buf; 996 *args++ = buf;
997 nargs++; 997 nargs++;
998 } 998 }
999 999
1000 if (!quotes) 1000 if (!quotes)
1001 while ((*buf != '\0') && (*buf != '\n') && 1001 while ((*buf != '\0') && (*buf != '\n') &&
1002 (*buf != '\t') && (*buf != ' ')) 1002 (*buf != '\t') && (*buf != ' '))
1003 buf++; 1003 buf++;
1004 else { 1004 else {
1005 while ((*buf != '\0') && (*buf != quotes)) 1005 while ((*buf != '\0') && (*buf != quotes))
1006 buf++; 1006 buf++;
1007 *buf++ = '\0'; 1007 *buf++ = '\0';
1008 } 1008 }
1009 } 1009 }
1010 1010
1011 *args = 0L; 1011 *args = 0L;
1012} 1012}
1013 1013
1014bool Modem::execPPPDaemon(const QString & arguments) 1014bool Modem::execPPPDaemon(const QString & arguments)
1015{ 1015{
1016 if(execpppd(arguments)) { 1016 if(execpppd(arguments)) {
1017 _pppdata->setpppdRunning(true); 1017 _pppdata->setpppdRunning(true);
1018 return true; 1018 return true;
1019 } else 1019 } else
1020 return false; 1020 return false;
1021} 1021}
1022 1022
1023void Modem::killPPPDaemon() 1023void Modem::killPPPDaemon()
1024{ 1024{
1025 _pppdata->setpppdRunning(false); 1025 _pppdata->setpppdRunning(false);
1026 killpppd(); 1026 killpppd();
1027} 1027}
1028 1028
1029int Modem::pppdExitStatus() 1029int Modem::pppdExitStatus()
1030{ 1030{
1031 return _pppdExitStatus; 1031 return _pppdExitStatus;
1032} 1032}
1033 1033
1034int Modem::openResolv(int flags) 1034int Modem::openResolv(int flags)
1035{ 1035{
1036 int fd; 1036 int fd;
1037 if ((fd = open(_PATH_RESCONF, flags)) == -1) { 1037 if ((fd = open(_PATH_RESCONF, flags)) == -1) {
1038 qDebug("error opening resolv.conf!"); 1038 odebug << "error opening resolv.conf!" << oendl;
1039 fd = open(DEVNULL, O_RDONLY); 1039 fd = open(DEVNULL, O_RDONLY);
1040 } 1040 }
1041 return fd; 1041 return fd;
1042} 1042}
1043 1043
1044bool Modem::setHostname(const QString & name) 1044bool Modem::setHostname(const QString & name)
1045{ 1045{
1046 return sethostname(name, name.length()) == 0; 1046 return sethostname(name, name.length()) == 0;
1047} 1047}
1048 1048
1049QString Modem::pppDevice()const { 1049QString Modem::pppDevice()const {
1050 return m_pppdDev; 1050 return m_pppdDev;
1051} 1051}
1052void Modem::setPPPDevice( const QString& dev ) { 1052void Modem::setPPPDevice( const QString& dev ) {
1053 m_pppdDev = dev; 1053 m_pppdDev = dev;
1054} 1054}
1055pid_t Modem::pppPID()const { 1055pid_t Modem::pppPID()const {
1056 return pppdPid; 1056 return pppdPid;
1057} 1057}
1058void Modem::setPPPDPid( pid_t pid ) { 1058void Modem::setPPPDPid( pid_t pid ) {
1059 qDebug("Modem setting pid"); 1059 odebug << "Modem setting pid" << oendl;
1060 _pppdExitStatus = -1; 1060 _pppdExitStatus = -1;
1061 pppdPid = pid; 1061 pppdPid = pid;
1062 modemfd = -1; 1062 modemfd = -1;
1063} 1063}
1064void Modem::slotModemDebug(int fd) { 1064void Modem::slotModemDebug(int fd) {
1065 char buf[2049]; 1065 char buf[2049];
1066 int len; 1066 int len;
1067 1067
1068 // read in pppd data look for Using interface 1068 // read in pppd data look for Using interface
1069 // then read the interface 1069 // then read the interface
1070 // we limit to 10 device now 0-9 1070 // we limit to 10 device now 0-9
1071 if((len = ::read(fd, buf, 2048)) > 0) { 1071 if((len = ::read(fd, buf, 2048)) > 0) {
1072 buf[len+1] = '\0'; 1072 buf[len+1] = '\0';
1073 char *found; 1073 char *found;
1074 if ( (found = ::strstr(buf, "Using interface ") ) ) { 1074 if ( (found = ::strstr(buf, "Using interface ") ) ) {
1075 found += 16; 1075 found += 16;
1076 m_pppdDev = QString::fromLatin1(found, 5 ); 1076 m_pppdDev = QString::fromLatin1(found, 5 );
1077 m_pppdDev = m_pppdDev.simplifyWhiteSpace(); 1077 m_pppdDev = m_pppdDev.simplifyWhiteSpace();
1078 } 1078 }
1079 } 1079 }
1080} 1080}