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