summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/networksettings/ppp/modem.cpp2
1 files changed, 2 insertions, 0 deletions
diff --git a/noncore/settings/networksettings/ppp/modem.cpp b/noncore/settings/networksettings/ppp/modem.cpp
index 002c8e7..2da9b14 100644
--- a/noncore/settings/networksettings/ppp/modem.cpp
+++ b/noncore/settings/networksettings/ppp/modem.cpp
@@ -1,800 +1,802 @@
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>
34#include <sys/stat.h>
33#include <setjmp.h> 35#include <setjmp.h>
34#include <regex.h> 36#include <regex.h>
35#include <qregexp.h> 37#include <qregexp.h>
36#include <assert.h> 38#include <assert.h>
37#include <string.h> 39#include <string.h>
38 40
39#ifdef HAVE_RESOLV_H 41#ifdef HAVE_RESOLV_H
40# include <arpa/nameser.h> 42# include <arpa/nameser.h>
41# include <resolv.h> 43# include <resolv.h>
42#endif 44#endif
43 45
44#ifndef _PATH_RESCONF 46#ifndef _PATH_RESCONF
45#define _PATH_RESCONF "/etc/resolv.conf" 47#define _PATH_RESCONF "/etc/resolv.conf"
46#endif 48#endif
47 49
48#define strlcpy strcpy 50#define strlcpy strcpy
49#include "auth.h" 51#include "auth.h"
50#include "modem.h" 52#include "modem.h"
51#include "pppdata.h" 53#include "pppdata.h"
52//#include <klocale.h> 54//#include <klocale.h>
53#define i18n QObject::tr 55#define i18n QObject::tr
54#define qError qDebug 56#define qError qDebug
55//#include <kdebug.h> 57//#include <kdebug.h>
56//#include <config.h> 58//#include <config.h>
57 59
58#define MY_ASSERT(x) if (!(x)) { \ 60#define MY_ASSERT(x) if (!(x)) { \
59 qFatal( "ASSERT: \"%s\" in %s (%d)\n",#x,__FILE__,__LINE__); \ 61 qFatal( "ASSERT: \"%s\" in %s (%d)\n",#x,__FILE__,__LINE__); \
60 exit(1); } 62 exit(1); }
61 63
62 64
63static sigjmp_buf jmp_buffer; 65static sigjmp_buf jmp_buffer;
64 66
65//Modem *Modem::modem = 0; 67//Modem *Modem::modem = 0;
66 68
67 69
68const char* pppdPath() { 70const char* pppdPath() {
69 // wasting a few bytes 71 // wasting a few bytes
70 static char buffer[sizeof(PPPDSEARCHPATH)+sizeof(PPPDNAME)]; 72 static char buffer[sizeof(PPPDSEARCHPATH)+sizeof(PPPDNAME)];
71 static char *pppdPath = 0L; 73 static char *pppdPath = 0L;
72 char *p; 74 char *p;
73 75
74 if(pppdPath == 0L) { 76 if(pppdPath == 0L) {
75 const char *c = PPPDSEARCHPATH; 77 const char *c = PPPDSEARCHPATH;
76 while(*c != '\0') { 78 while(*c != '\0') {
77 while(*c == ':') 79 while(*c == ':')
78 c++; 80 c++;
79 p = buffer; 81 p = buffer;
80 while(*c != '\0' && *c != ':') 82 while(*c != '\0' && *c != ':')
81 *p++ = *c++; 83 *p++ = *c++;
82 *p = '\0'; 84 *p = '\0';
83 strcat(p, "/"); 85 strcat(p, "/");
84 strcat(p, PPPDNAME); 86 strcat(p, PPPDNAME);
85 if(access(buffer, F_OK) == 0) 87 if(access(buffer, F_OK) == 0)
86 return (pppdPath = buffer); 88 return (pppdPath = buffer);
87 } 89 }
88 } 90 }
89 91
90 return pppdPath; 92 return pppdPath;
91} 93}
92 94
93 95
94Modem::Modem( PPPData* pd ) 96Modem::Modem( PPPData* pd )
95{ 97{
96 _pppdata = pd; 98 _pppdata = pd;
97 modemfd = -1; 99 modemfd = -1;
98 _pppdExitStatus = -1; 100 _pppdExitStatus = -1;
99 pppdPid = -1; 101 pppdPid = -1;
100 sn = 0L; 102 sn = 0L;
101 data_mode = false; 103 data_mode = false;
102 modem_is_locked = false; 104 modem_is_locked = false;
103 lockfile[0] = '\0'; 105 lockfile[0] = '\0';
104 device = "/dev/modem"; 106 device = "/dev/modem";
105} 107}
106 108
107 109
108Modem::~Modem() 110Modem::~Modem()
109{ 111{
110} 112}
111 113
112 114
113speed_t Modem::modemspeed() { 115speed_t Modem::modemspeed() {
114 // 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
115 // 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
116 // other systems may not have them 118 // other systems may not have them
117 int i = _pppdata->speed().toInt()/100; 119 int i = _pppdata->speed().toInt()/100;
118 120
119 switch(i) { 121 switch(i) {
120 case 24: 122 case 24:
121 return B2400; 123 return B2400;
122 break; 124 break;
123 case 96: 125 case 96:
124 return B9600; 126 return B9600;
125 break; 127 break;
126 case 192: 128 case 192:
127 return B19200; 129 return B19200;
128 break; 130 break;
129 case 384: 131 case 384:
130 return B38400; 132 return B38400;
131 break; 133 break;
132#ifdef B57600 134#ifdef B57600
133 case 576: 135 case 576:
134 return B57600; 136 return B57600;
135 break; 137 break;
136#endif 138#endif
137 139
138#ifdef B115200 140#ifdef B115200
139 case 1152: 141 case 1152:
140 return B115200; 142 return B115200;
141 break; 143 break;
142#endif 144#endif
143 145
144#ifdef B230400 146#ifdef B230400
145 case 2304: 147 case 2304:
146 return B230400; 148 return B230400;
147 break; 149 break;
148#endif 150#endif
149 151
150#ifdef B460800 152#ifdef B460800
151 case 4608: 153 case 4608:
152 return B460800; 154 return B460800;
153 break; 155 break;
154#endif 156#endif
155 157
156 default: 158 default:
157 return B38400; 159 return B38400;
158 break; 160 break;
159 } 161 }
160} 162}
161 163
162bool Modem::opentty() { 164bool Modem::opentty() {
163 // int flags; 165 // int flags;
164 166
165//begin if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) { 167//begin if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) {
166 close(modemfd); 168 close(modemfd);
167 device = _pppdata->modemDevice(); 169 device = _pppdata->modemDevice();
168 if ((modemfd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) == -1) { 170 if ((modemfd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) == -1) {
169 qDebug("error opening modem device !"); 171 qDebug("error opening modem device !");
170 errmsg = i18n("Unable to open modem."); 172 errmsg = i18n("Unable to open modem.");
171 return false; 173 return false;
172 } 174 }
173//bend if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) { 175//bend if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) {
174//} 176//}
175 177
176#if 0 178#if 0
177 if(_pppdata->UseCDLine()) { 179 if(_pppdata->UseCDLine()) {
178 if(ioctl(modemfd, TIOCMGET, &flags) == -1) { 180 if(ioctl(modemfd, TIOCMGET, &flags) == -1) {
179 errmsg = i18n("Unable to detect state of CD line."); 181 errmsg = i18n("Unable to detect state of CD line.");
180 ::close(modemfd); 182 ::close(modemfd);
181 modemfd = -1; 183 modemfd = -1;
182 return false; 184 return false;
183 } 185 }
184 if ((flags&TIOCM_CD) == 0) { 186 if ((flags&TIOCM_CD) == 0) {
185 errmsg = i18n("The modem is not ready."); 187 errmsg = i18n("The modem is not ready.");
186 ::close(modemfd); 188 ::close(modemfd);
187 modemfd = -1; 189 modemfd = -1;
188 return false; 190 return false;
189 } 191 }
190 } 192 }
191#endif 193#endif
192 194
193 tcdrain (modemfd); 195 tcdrain (modemfd);
194 tcflush (modemfd, TCIOFLUSH); 196 tcflush (modemfd, TCIOFLUSH);
195 197
196 if(tcgetattr(modemfd, &tty) < 0){ 198 if(tcgetattr(modemfd, &tty) < 0){
197 // this helps in some cases 199 // this helps in some cases
198 tcsendbreak(modemfd, 0); 200 tcsendbreak(modemfd, 0);
199 sleep(1); 201 sleep(1);
200 if(tcgetattr(modemfd, &tty) < 0){ 202 if(tcgetattr(modemfd, &tty) < 0){
201 errmsg = i18n("The modem is busy."); 203 errmsg = i18n("The modem is busy.");
202 ::close(modemfd); 204 ::close(modemfd);
203 modemfd = -1; 205 modemfd = -1;
204 return false; 206 return false;
205 } 207 }
206 } 208 }
207 209
208 memset(&initial_tty,'\0',sizeof(initial_tty)); 210 memset(&initial_tty,'\0',sizeof(initial_tty));
209 211
210 initial_tty = tty; 212 initial_tty = tty;
211 213
212 tty.c_cc[VMIN] = 0; // nonblocking 214 tty.c_cc[VMIN] = 0; // nonblocking
213 tty.c_cc[VTIME] = 0; 215 tty.c_cc[VTIME] = 0;
214 tty.c_oflag = 0; 216 tty.c_oflag = 0;
215 tty.c_lflag = 0; 217 tty.c_lflag = 0;
216 218
217 tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB); 219 tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
218 tty.c_cflag |= CS8 | CREAD; 220 tty.c_cflag |= CS8 | CREAD;
219 tty.c_cflag |= CLOCAL; // ignore modem status lines 221 tty.c_cflag |= CLOCAL; // ignore modem status lines
220 tty.c_iflag = IGNBRK | IGNPAR /* | ISTRIP */ ; 222 tty.c_iflag = IGNBRK | IGNPAR /* | ISTRIP */ ;
221 tty.c_lflag &= ~ICANON; // non-canonical mode 223 tty.c_lflag &= ~ICANON; // non-canonical mode
222 tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE); 224 tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE);
223 225
224 226
225 if(_pppdata->flowcontrol() != "None") { 227 if(_pppdata->flowcontrol() != "None") {
226 if(_pppdata->flowcontrol() == "CRTSCTS") { 228 if(_pppdata->flowcontrol() == "CRTSCTS") {
227 tty.c_cflag |= CRTSCTS; 229 tty.c_cflag |= CRTSCTS;
228 } 230 }
229 else { 231 else {
230 tty.c_iflag |= IXON | IXOFF; 232 tty.c_iflag |= IXON | IXOFF;
231 tty.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ 233 tty.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
232 tty.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ 234 tty.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
233 } 235 }
234 } 236 }
235 else { 237 else {
236 tty.c_cflag &= ~CRTSCTS; 238 tty.c_cflag &= ~CRTSCTS;
237 tty.c_iflag &= ~(IXON | IXOFF); 239 tty.c_iflag &= ~(IXON | IXOFF);
238 } 240 }
239 241
240 cfsetospeed(&tty, modemspeed()); 242 cfsetospeed(&tty, modemspeed());
241 cfsetispeed(&tty, modemspeed()); 243 cfsetispeed(&tty, modemspeed());
242 244
243 tcdrain(modemfd); 245 tcdrain(modemfd);
244 246
245 if(tcsetattr(modemfd, TCSANOW, &tty) < 0){ 247 if(tcsetattr(modemfd, TCSANOW, &tty) < 0){
246 errmsg = i18n("The modem is busy."); 248 errmsg = i18n("The modem is busy.");
247 ::close(modemfd); 249 ::close(modemfd);
248 modemfd=-1; 250 modemfd=-1;
249 return false; 251 return false;
250 } 252 }
251 253
252 errmsg = i18n("Modem Ready."); 254 errmsg = i18n("Modem Ready.");
253 return true; 255 return true;
254} 256}
255 257
256 258
257bool Modem::closetty() { 259bool Modem::closetty() {
258 if(modemfd >=0 ) { 260 if(modemfd >=0 ) {
259 stop(); 261 stop();
260 /* discard data not read or transmitted */ 262 /* discard data not read or transmitted */
261 tcflush(modemfd, TCIOFLUSH); 263 tcflush(modemfd, TCIOFLUSH);
262 264
263 if(tcsetattr(modemfd, TCSANOW, &initial_tty) < 0){ 265 if(tcsetattr(modemfd, TCSANOW, &initial_tty) < 0){
264 errmsg = i18n("Can't restore tty settings: tcsetattr()\n"); 266 errmsg = i18n("Can't restore tty settings: tcsetattr()\n");
265 ::close(modemfd); 267 ::close(modemfd);
266 modemfd = -1; 268 modemfd = -1;
267 return false; 269 return false;
268 } 270 }
269 ::close(modemfd); 271 ::close(modemfd);
270 modemfd = -1; 272 modemfd = -1;
271 } 273 }
272 274
273 return true; 275 return true;
274} 276}
275 277
276 278
277void Modem::readtty(int) { 279void Modem::readtty(int) {
278 char buffer[200]; 280 char buffer[200];
279 unsigned char c; 281 unsigned char c;
280 int len; 282 int len;
281 283
282 // read data in chunks of up to 200 bytes 284 // read data in chunks of up to 200 bytes
283 if((len = ::read(modemfd, buffer, 200)) > 0) { 285 if((len = ::read(modemfd, buffer, 200)) > 0) {
284 // split buffer into single characters for further processing 286 // split buffer into single characters for further processing
285 for(int i = 0; i < len; i++) { 287 for(int i = 0; i < len; i++) {
286 c = buffer[i] & 0x7F; 288 c = buffer[i] & 0x7F;
287 emit charWaiting(c); 289 emit charWaiting(c);
288 } 290 }
289 } 291 }
290} 292}
291 293
292 294
293void Modem::notify(const QObject *receiver, const char *member) { 295void Modem::notify(const QObject *receiver, const char *member) {
294 connect(this, SIGNAL(charWaiting(unsigned char)), receiver, member); 296 connect(this, SIGNAL(charWaiting(unsigned char)), receiver, member);
295 startNotifier(); 297 startNotifier();
296} 298}
297 299
298 300
299void Modem::stop() { 301void Modem::stop() {
300 disconnect(SIGNAL(charWaiting(unsigned char))); 302 disconnect(SIGNAL(charWaiting(unsigned char)));
301 stopNotifier(); 303 stopNotifier();
302} 304}
303 305
304 306
305void Modem::startNotifier() { 307void Modem::startNotifier() {
306 if(modemfd >= 0) { 308 if(modemfd >= 0) {
307 if(sn == 0) { 309 if(sn == 0) {
308 sn = new QSocketNotifier(modemfd, QSocketNotifier::Read, this); 310 sn = new QSocketNotifier(modemfd, QSocketNotifier::Read, this);
309 connect(sn, SIGNAL(activated(int)), SLOT(readtty(int))); 311 connect(sn, SIGNAL(activated(int)), SLOT(readtty(int)));
310 qDebug("QSocketNotifier started!"); 312 qDebug("QSocketNotifier started!");
311 } else { 313 } else {
312 qDebug("QSocketNotifier re-enabled!"); 314 qDebug("QSocketNotifier re-enabled!");
313 sn->setEnabled(true); 315 sn->setEnabled(true);
314 } 316 }
315 } 317 }
316} 318}
317 319
318 320
319void Modem::stopNotifier() { 321void Modem::stopNotifier() {
320 if(sn != 0) { 322 if(sn != 0) {
321 sn->setEnabled(false); 323 sn->setEnabled(false);
322 disconnect(sn); 324 disconnect(sn);
323 delete sn; 325 delete sn;
324 sn = 0; 326 sn = 0;
325 qDebug( "QSocketNotifier stopped!" ); 327 qDebug( "QSocketNotifier stopped!" );
326 } 328 }
327} 329}
328 330
329 331
330void Modem::flush() { 332void Modem::flush() {
331 char c; 333 char c;
332 while(read(modemfd, &c, 1) == 1); 334 while(read(modemfd, &c, 1) == 1);
333} 335}
334 336
335 337
336bool Modem::writeChar(unsigned char c) { 338bool Modem::writeChar(unsigned char c) {
337 int s; 339 int s;
338 do { 340 do {
339 s = write(modemfd, &c, 1); 341 s = write(modemfd, &c, 1);
340 if (s < 0) { 342 if (s < 0) {
341 qError( "write() in Modem::writeChar failed" ); 343 qError( "write() in Modem::writeChar failed" );
342 return false; 344 return false;
343 } 345 }
344 } while(s == 0); 346 } while(s == 0);
345 347
346 return true; 348 return true;
347} 349}
348 350
349 351
350bool Modem::writeLine(const char *buf) { 352bool Modem::writeLine(const char *buf) {
351 int len = strlen(buf); 353 int len = strlen(buf);
352 char *b = new char[len+2]; 354 char *b = new char[len+2];
353 memcpy(b, buf, len); 355 memcpy(b, buf, len);
354 // different modems seem to need different line terminations 356 // different modems seem to need different line terminations
355 QString term = _pppdata->enter(); 357 QString term = _pppdata->enter();
356 if(term == "LF") 358 if(term == "LF")
357 b[len++]='\n'; 359 b[len++]='\n';
358 else if(term == "CR") 360 else if(term == "CR")
359 b[len++]='\r'; 361 b[len++]='\r';
360 else if(term == "CR/LF") { 362 else if(term == "CR/LF") {
361 b[len++]='\r'; 363 b[len++]='\r';
362 b[len++]='\n'; 364 b[len++]='\n';
363 } 365 }
364 int l = len; 366 int l = len;
365 while(l) { 367 while(l) {
366 int wr = write(modemfd, &b[len-l], l); 368 int wr = write(modemfd, &b[len-l], l);
367 if(wr < 0) { 369 if(wr < 0) {
368 // TODO do something meaningful with the error code (or ignore it 370 // TODO do something meaningful with the error code (or ignore it
369 qError( "write() in Modem::writeLine failed" ); 371 qError( "write() in Modem::writeLine failed" );
370 delete[] b; 372 delete[] b;
371 return false; 373 return false;
372 } 374 }
373 l -= wr; 375 l -= wr;
374 } 376 }
375 delete[] b; 377 delete[] b;
376 return true; 378 return true;
377} 379}
378 380
379 381
380bool Modem::hangup() { 382bool Modem::hangup() {
381 // 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
382 // 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
383 // 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
384 // 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
385 // is most likely the reason. 387 // is most likely the reason.
386 struct termios temptty; 388 struct termios temptty;
387 389
388 if(modemfd >= 0) { 390 if(modemfd >= 0) {
389 391
390 // is this Escape & HangupStr stuff really necessary ? (Harri) 392 // is this Escape & HangupStr stuff really necessary ? (Harri)
391 393
392 if (data_mode) escape_to_command_mode(); 394 if (data_mode) escape_to_command_mode();
393 395
394 // Then hangup command 396 // Then hangup command
395 writeLine(_pppdata->modemHangupStr().local8Bit()); 397 writeLine(_pppdata->modemHangupStr().local8Bit());
396 398
397 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 sec 399 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 sec
398 400
399#ifndef DEBUG_WO_DIALING 401#ifndef DEBUG_WO_DIALING
400 if (sigsetjmp(jmp_buffer, 1) == 0) { 402 if (sigsetjmp(jmp_buffer, 1) == 0) {
401 // set alarm in case tcsendbreak() hangs 403 // set alarm in case tcsendbreak() hangs
402 signal(SIGALRM, alarm_handler); 404 signal(SIGALRM, alarm_handler);
403 alarm(2); 405 alarm(2);
404 406
405 tcsendbreak(modemfd, 0); 407 tcsendbreak(modemfd, 0);
406 408
407 alarm(0); 409 alarm(0);
408 signal(SIGALRM, SIG_IGN); 410 signal(SIGALRM, SIG_IGN);
409 } else { 411 } else {
410 // we reach this point if the alarm handler got called 412 // we reach this point if the alarm handler got called
411 closetty(); 413 closetty();
412 close(modemfd); 414 close(modemfd);
413 modemfd = -1; 415 modemfd = -1;
414 errmsg = i18n("The modem does not respond."); 416 errmsg = i18n("The modem does not respond.");
415 return false; 417 return false;
416 } 418 }
417 419
418#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.
419 tcgetattr(modemfd, &temptty); 421 tcgetattr(modemfd, &temptty);
420 cfsetospeed(&temptty, B0); 422 cfsetospeed(&temptty, B0);
421 cfsetispeed(&temptty, B0); 423 cfsetispeed(&temptty, B0);
422 tcsetattr(modemfd, TCSAFLUSH, &temptty); 424 tcsetattr(modemfd, TCSAFLUSH, &temptty);
423#else 425#else
424 int modemstat; 426 int modemstat;
425 ioctl(modemfd, TIOCMGET, &modemstat); 427 ioctl(modemfd, TIOCMGET, &modemstat);
426 modemstat &= ~TIOCM_DTR; 428 modemstat &= ~TIOCM_DTR;
427 ioctl(modemfd, TIOCMSET, &modemstat); 429 ioctl(modemfd, TIOCMSET, &modemstat);
428 ioctl(modemfd, TIOCMGET, &modemstat); 430 ioctl(modemfd, TIOCMGET, &modemstat);
429 modemstat |= TIOCM_DTR; 431 modemstat |= TIOCM_DTR;
430 ioctl(modemfd, TIOCMSET, &modemstat); 432 ioctl(modemfd, TIOCMSET, &modemstat);
431#endif 433#endif
432 434
433 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 secs 435 usleep(_pppdata->modemInitDelay() * 10000); // 0.01 - 3.0 secs
434 436
435 cfsetospeed(&temptty, modemspeed()); 437 cfsetospeed(&temptty, modemspeed());
436 cfsetispeed(&temptty, modemspeed()); 438 cfsetispeed(&temptty, modemspeed());
437 tcsetattr(modemfd, TCSAFLUSH, &temptty); 439 tcsetattr(modemfd, TCSAFLUSH, &temptty);
438#endif 440#endif
439 return true; 441 return true;
440 } else 442 } else
441 return false; 443 return false;
442} 444}
443 445
444 446
445void Modem::escape_to_command_mode() { 447void Modem::escape_to_command_mode() {
446 // 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.
447 // 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.
448 // When a modem sends the host the CONNECT string, that signals 450 // When a modem sends the host the CONNECT string, that signals
449 // 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.)
450 // 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.
451 // 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.
452 // 454 //
453 tcflush(modemfd, TCIOFLUSH); 455 tcflush(modemfd, TCIOFLUSH);
454 456
455 // +3 because quiet time must be greater than guard time. 457 // +3 because quiet time must be greater than guard time.
456 usleep((_pppdata->modemEscapeGuardTime()+3)*20000); 458 usleep((_pppdata->modemEscapeGuardTime()+3)*20000);
457 QCString tmp = _pppdata->modemEscapeStr().local8Bit(); 459 QCString tmp = _pppdata->modemEscapeStr().local8Bit();
458 write(modemfd, tmp.data(), tmp.length()); 460 write(modemfd, tmp.data(), tmp.length());
459 tcflush(modemfd, TCIOFLUSH); 461 tcflush(modemfd, TCIOFLUSH);
460 usleep((_pppdata->modemEscapeGuardTime()+3)*20000); 462 usleep((_pppdata->modemEscapeGuardTime()+3)*20000);
461 463
462 data_mode = false; 464 data_mode = false;
463} 465}
464 466
465 467
466const QString Modem::modemMessage() { 468const QString Modem::modemMessage() {
467 return errmsg; 469 return errmsg;
468} 470}
469 471
470 472
471QString Modem::parseModemSpeed(const QString &s) { 473QString Modem::parseModemSpeed(const QString &s) {
472 // this is a small (and bad) parser for modem speeds 474 // this is a small (and bad) parser for modem speeds
473 int rx = -1; 475 int rx = -1;
474 int tx = -1; 476 int tx = -1;
475 int i; 477 int i;
476 QString result; 478 QString result;
477 479
478 qDebug( "Modem reported result string: %s", s.latin1()); 480 qDebug( "Modem reported result string: %s", s.latin1());
479 481
480 const int RXMAX = 7; 482 const int RXMAX = 7;
481 const int TXMAX = 2; 483 const int TXMAX = 2;
482 QRegExp rrx[RXMAX] = { 484 QRegExp rrx[RXMAX] = {
483 QRegExp("[0-9]+[:/ ]RX", false), 485 QRegExp("[0-9]+[:/ ]RX", false),
484 QRegExp("[0-9]+RX", false), 486 QRegExp("[0-9]+RX", false),
485 QRegExp("[/: -][0-9]+[/: ]", false), 487 QRegExp("[/: -][0-9]+[/: ]", false),
486 QRegExp("[/: -][0-9]+$", false), 488 QRegExp("[/: -][0-9]+$", false),
487 QRegExp("CARRIER [^0-9]*[0-9]+", false), 489 QRegExp("CARRIER [^0-9]*[0-9]+", false),
488 QRegExp("CONNECT [^0-9]*[0-9]+", false), 490 QRegExp("CONNECT [^0-9]*[0-9]+", false),
489 QRegExp("[0-9]+") // panic mode 491 QRegExp("[0-9]+") // panic mode
490 }; 492 };
491 493
492 QRegExp trx[TXMAX] = { 494 QRegExp trx[TXMAX] = {
493 QRegExp("[0-9]+[:/ ]TX", false), 495 QRegExp("[0-9]+[:/ ]TX", false),
494 QRegExp("[0-9]+TX", false) 496 QRegExp("[0-9]+TX", false)
495 }; 497 };
496 498
497 for(i = 0; i < RXMAX; i++) { 499 for(i = 0; i < RXMAX; i++) {
498 int len, idx, result; 500 int len, idx, result;
499 if((idx = rrx[i].match(s,0,&len)) > -1) { 501 if((idx = rrx[i].match(s,0,&len)) > -1) {
500// if((idx = rrx[i].search(s)) > -1) { 502// if((idx = rrx[i].search(s)) > -1) {
501 // len = rrx[i].matchedLength(); 503 // len = rrx[i].matchedLength();
502 504
503 // 505 //
504 // 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
505 // and len contains how long the match is. Extract the match. 507 // and len contains how long the match is. Extract the match.
506 // 508 //
507 QString sub = s.mid(idx, len); 509 QString sub = s.mid(idx, len);
508 510
509 // 511 //
510 // Now extract the digits only from the match, which will 512 // Now extract the digits only from the match, which will
511 // then be converted to an int. 513 // then be converted to an int.
512 // 514 //
513 if ((idx = rrx[RXMAX-1].match( sub,0,&len )) > -1) { 515 if ((idx = rrx[RXMAX-1].match( sub,0,&len )) > -1) {
514// if ((idx = rrx[RXMAX-1].search( sub )) > -1) { 516// if ((idx = rrx[RXMAX-1].search( sub )) > -1) {
515// len = rrx[RXMAX-1].matchedLength(); 517// len = rrx[RXMAX-1].matchedLength();
516 sub = sub.mid(idx, len); 518 sub = sub.mid(idx, len);
517 result = sub.toInt(); 519 result = sub.toInt();
518 if(result > 0) { 520 if(result > 0) {
519 rx = result; 521 rx = result;
520 break; 522 break;
521 } 523 }
522 } 524 }
523 } 525 }
524 } 526 }
525 527
526 for(i = 0; i < TXMAX; i++) { 528 for(i = 0; i < TXMAX; i++) {
527 int len, idx, result; 529 int len, idx, result;
528 if((idx = trx[i].match(s,0,&len)) > -1) { 530 if((idx = trx[i].match(s,0,&len)) > -1) {
529// if((idx = trx[i].search(s)) > -1) { 531// if((idx = trx[i].search(s)) > -1) {
530// len = trx[i].matchedLength(); 532// len = trx[i].matchedLength();
531 533
532 // 534 //
533 // 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
534 // and len contains how long the match is. Extract the match. 536 // and len contains how long the match is. Extract the match.
535 // 537 //
536 QString sub = s.mid(idx, len); 538 QString sub = s.mid(idx, len);
537 539
538 // 540 //
539 // Now extract the digits only from the match, which will then 541 // Now extract the digits only from the match, which will then
540 // be converted to an int. 542 // be converted to an int.
541 // 543 //
542 if((idx = rrx[RXMAX-1].match(sub,0,&len)) > -1) { 544 if((idx = rrx[RXMAX-1].match(sub,0,&len)) > -1) {
543// if((idx = rrx[RXMAX-1].search(sub)) > -1) { 545// if((idx = rrx[RXMAX-1].search(sub)) > -1) {
544// len = rrx[RXMAX-1].matchedLength(); 546// len = rrx[RXMAX-1].matchedLength();
545 sub = sub.mid(idx, len); 547 sub = sub.mid(idx, len);
546 result = sub.toInt(); 548 result = sub.toInt();
547 if(result > 0) { 549 if(result > 0) {
548 tx = result; 550 tx = result;
549 break; 551 break;
550 } 552 }
551 } 553 }
552 } 554 }
553 } 555 }
554 556
555 if(rx == -1 && tx == -1) 557 if(rx == -1 && tx == -1)
556 result = i18n("Unknown speed"); 558 result = i18n("Unknown speed");
557 else if(tx == -1) 559 else if(tx == -1)
558 result.setNum(rx); 560 result.setNum(rx);
559 else if(rx == -1) // should not happen 561 else if(rx == -1) // should not happen
560 result.setNum(tx); 562 result.setNum(tx);
561 else 563 else
562 result.sprintf("%d/%d", rx, tx); 564 result.sprintf("%d/%d", rx, tx);
563 565
564 qDebug( "The parsed result is: %s", result.latin1()); 566 qDebug( "The parsed result is: %s", result.latin1());
565 567
566 return result; 568 return result;
567} 569}
568 570
569 571
570// 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
571// a lock file can't be created ( permission problem ) 573// a lock file can't be created ( permission problem )
572int Modem::lockdevice() { 574int Modem::lockdevice() {
573 int fd; 575 int fd;
574 char newlock[80]=""; // safe 576 char newlock[80]=""; // safe
575 577
576 if(!_pppdata->modemLockFile()) { 578 if(!_pppdata->modemLockFile()) {
577 qDebug("The user doesn't want a lockfile."); 579 qDebug("The user doesn't want a lockfile.");
578 return 0; 580 return 0;
579 } 581 }
580 582
581 if (modem_is_locked) 583 if (modem_is_locked)
582 return 1; 584 return 1;
583 585
584 QString lockfile = LOCK_DIR"/LCK.."; 586 QString lockfile = LOCK_DIR"/LCK..";
585 lockfile += _pppdata->modemDevice().mid(5); // append everything after /dev/ 587 lockfile += _pppdata->modemDevice().mid(5); // append everything after /dev/
586 588
587 if(access(QFile::encodeName(lockfile), F_OK) == 0) { 589 if(access(QFile::encodeName(lockfile), F_OK) == 0) {
588// if ((fd = Requester::rq-> 590// if ((fd = Requester::rq->
589if ((fd = openLockfile(QFile::encodeName(lockfile), O_RDONLY)) >= 0) { 591if ((fd = openLockfile(QFile::encodeName(lockfile), O_RDONLY)) >= 0) {
590 // 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
591 // file has more than 32 bytes, skip the rest 593 // file has more than 32 bytes, skip the rest
592 char oldlock[33]; // safe 594 char oldlock[33]; // safe
593 int sz = read(fd, &oldlock, 32); 595 int sz = read(fd, &oldlock, 32);
594 close (fd); 596 close (fd);
595 if (sz <= 0) 597 if (sz <= 0)
596 return 1; 598 return 1;
597 oldlock[sz] = '\0'; 599 oldlock[sz] = '\0';
598 600
599 qDebug( "Device is locked by: %s", oldlock); 601 qDebug( "Device is locked by: %s", oldlock);
600 602
601 int oldpid; 603 int oldpid;
602 int match = sscanf(oldlock, "%d", &oldpid); 604 int match = sscanf(oldlock, "%d", &oldpid);
603 605
604 // found a pid in lockfile ? 606 // found a pid in lockfile ?
605 if (match < 1 || oldpid <= 0) 607 if (match < 1 || oldpid <= 0)
606 return 1; 608 return 1;
607 609
608 // check if process exists 610 // check if process exists
609 if (kill((pid_t)oldpid, 0) == 0 || errno != ESRCH) 611 if (kill((pid_t)oldpid, 0) == 0 || errno != ESRCH)
610 return 1; 612 return 1;
611 613
612 qDebug( "lockfile is stale" ); 614 qDebug( "lockfile is stale" );
613 } 615 }
614 } 616 }
615 617
616 fd = openLockfile(_pppdata->modemDevice(),O_WRONLY|O_TRUNC|O_CREAT); 618 fd = openLockfile(_pppdata->modemDevice(),O_WRONLY|O_TRUNC|O_CREAT);
617 if(fd >= 0) { 619 if(fd >= 0) {
618 sprintf(newlock,"%010d\n", getpid()); 620 sprintf(newlock,"%010d\n", getpid());
619 qDebug("Locking Device: %s", newlock); 621 qDebug("Locking Device: %s", newlock);
620 622
621 write(fd, newlock, strlen(newlock)); 623 write(fd, newlock, strlen(newlock));
622 close(fd); 624 close(fd);
623 modem_is_locked=true; 625 modem_is_locked=true;
624 626
625 return 0; 627 return 0;
626 } 628 }
627 629
628 return -1; 630 return -1;
629 631
630} 632}
631 633
632 634
633// UnLock modem device 635// UnLock modem device
634void Modem::unlockdevice() { 636void Modem::unlockdevice() {
635 if (modem_is_locked) { 637 if (modem_is_locked) {
636 qDebug( "UnLocking Modem Device" ); 638 qDebug( "UnLocking Modem Device" );
637 close(modemfd); 639 close(modemfd);
638 modemfd = -1; 640 modemfd = -1;
639 unlink(lockfile); 641 unlink(lockfile);
640 lockfile[0] = '\0'; 642 lockfile[0] = '\0';
641 modem_is_locked=false; 643 modem_is_locked=false;
642 } 644 }
643} 645}
644 646
645int Modem::openLockfile( QString lockfile, int flags) 647int Modem::openLockfile( QString lockfile, int flags)
646{ 648{
647 int fd; 649 int fd;
648 int mode; 650 int mode;
649 flags = O_RDONLY; 651 flags = O_RDONLY;
650 if(flags == O_WRONLY|O_TRUNC|O_CREAT) 652 if(flags == O_WRONLY|O_TRUNC|O_CREAT)
651 mode = 0644; 653 mode = 0644;
652 else 654 else
653 mode = 0; 655 mode = 0;
654 656
655 lockfile = LOCK_DIR; 657 lockfile = LOCK_DIR;
656 lockfile += "/LCK.."; 658 lockfile += "/LCK..";
657 lockfile += device.right( device.length() - device.findRev("/") -1 ); 659 lockfile += device.right( device.length() - device.findRev("/") -1 );
658 qDebug("lockfile >%s<",lockfile.latin1()); 660 qDebug("lockfile >%s<",lockfile.latin1());
659 // TODO: 661 // TODO:
660 // struct stat st; 662 // struct stat st;
661 // if(stat(lockfile.data(), &st) == -1) { 663 // if(stat(lockfile.data(), &st) == -1) {
662 // if(errno == EBADF) 664 // if(errno == EBADF)
663 // return -1; 665 // return -1;
664 // } else { 666 // } else {
665 // // make sure that this is a regular file 667 // // make sure that this is a regular file
666 // if(!S_ISREG(st.st_mode)) 668 // if(!S_ISREG(st.st_mode))
667 // return -1; 669 // return -1;
668 // } 670 // }
669 if ((fd = open(lockfile, flags, mode)) == -1) { 671 if ((fd = open(lockfile, flags, mode)) == -1) {
670 qDebug("error opening lockfile!"); 672 qDebug("error opening lockfile!");
671 lockfile = QString::null; 673 lockfile = QString::null;
672 fd = open(DEVNULL, O_RDONLY); 674 fd = open(DEVNULL, O_RDONLY);
673 } else 675 } else
674 fchown(fd, 0, 0); 676 fchown(fd, 0, 0);
675 return fd; 677 return fd;
676} 678}
677 679
678 680
679 681
680void alarm_handler(int) { 682void alarm_handler(int) {
681 // fprintf(stderr, "alarm_handler(): Received SIGALRM\n"); 683 // fprintf(stderr, "alarm_handler(): Received SIGALRM\n");
682 684
683 // jump 685 // jump
684 siglongjmp(jmp_buffer, 1); 686 siglongjmp(jmp_buffer, 1);
685} 687}
686 688
687 689
688const char* Modem::authFile(Auth method, int version) { 690const char* Modem::authFile(Auth method, int version) {
689 switch(method|version) { 691 switch(method|version) {
690 case PAP|Original: 692 case PAP|Original:
691 return PAP_AUTH_FILE; 693 return PAP_AUTH_FILE;
692 break; 694 break;
693 case PAP|New: 695 case PAP|New:
694 return PAP_AUTH_FILE".new"; 696 return PAP_AUTH_FILE".new";
695 break; 697 break;
696 case PAP|Old: 698 case PAP|Old:
697 return PAP_AUTH_FILE".old"; 699 return PAP_AUTH_FILE".old";
698 break; 700 break;
699 case CHAP|Original: 701 case CHAP|Original:
700 return CHAP_AUTH_FILE; 702 return CHAP_AUTH_FILE;
701 break; 703 break;
702 case CHAP|New: 704 case CHAP|New:
703 return CHAP_AUTH_FILE".new"; 705 return CHAP_AUTH_FILE".new";
704 break; 706 break;
705 case CHAP|Old: 707 case CHAP|Old:
706 return CHAP_AUTH_FILE".old"; 708 return CHAP_AUTH_FILE".old";
707 break; 709 break;
708 default: 710 default:
709 return 0L; 711 return 0L;
710 } 712 }
711} 713}
712 714
713 715
714bool Modem::createAuthFile(Auth method, const char *username, const char *password) { 716bool Modem::createAuthFile(Auth method, const char *username, const char *password) {
715 const char *authfile, *oldName, *newName; 717 const char *authfile, *oldName, *newName;
716 char line[100]; 718 char line[100];
717 char regexp[2*MaxStrLen+30]; 719 char regexp[2*MaxStrLen+30];
718 regex_t preg; 720 regex_t preg;
719 721
720 if(!(authfile = authFile(method))) 722 if(!(authfile = authFile(method)))
721 return false; 723 return false;
722 724
723 if(!(newName = authFile(method, New))) 725 if(!(newName = authFile(method, New)))
724 return false; 726 return false;
725 727
726 // look for username, "username" or 'username' 728 // look for username, "username" or 'username'
727 // 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
728 snprintf(regexp, sizeof(regexp), "^[ \t]*%s[ \t]\\|^[ \t]*[\"\']%s[\"\']", 730 snprintf(regexp, sizeof(regexp), "^[ \t]*%s[ \t]\\|^[ \t]*[\"\']%s[\"\']",
729 username,username); 731 username,username);
730 MY_ASSERT(regcomp(&preg, regexp, 0) == 0); 732 MY_ASSERT(regcomp(&preg, regexp, 0) == 0);
731 733
732 // copy to new file pap- or chap-secrets 734 // copy to new file pap- or chap-secrets
733 int old_umask = umask(0077); 735 int old_umask = umask(0077);
734 FILE *fout = fopen(newName, "w"); 736 FILE *fout = fopen(newName, "w");
735 if(fout) { 737 if(fout) {
736 // copy old file 738 // copy old file
737 FILE *fin = fopen(authfile, "r"); 739 FILE *fin = fopen(authfile, "r");
738 if(fin) { 740 if(fin) {
739 while(fgets(line, sizeof(line), fin)) { 741 while(fgets(line, sizeof(line), fin)) {
740 if(regexec(&preg, line, 0, 0L, 0) == 0) 742 if(regexec(&preg, line, 0, 0L, 0) == 0)
741 continue; 743 continue;
742 fputs(line, fout); 744 fputs(line, fout);
743 } 745 }
744 fclose(fin); 746 fclose(fin);
745 } 747 }
746 748
747 // append user/pass pair 749 // append user/pass pair
748 fprintf(fout, "\"%s\"\t*\t\"%s\"\n", username, password); 750 fprintf(fout, "\"%s\"\t*\t\"%s\"\n", username, password);
749 fclose(fout); 751 fclose(fout);
750 } 752 }
751 753
752 // restore umask 754 // restore umask
753 umask(old_umask); 755 umask(old_umask);
754 756
755 // free memory allocated by regcomp 757 // free memory allocated by regcomp
756 regfree(&preg); 758 regfree(&preg);
757 759
758 if(!(oldName = authFile(method, Old))) 760 if(!(oldName = authFile(method, Old)))
759 return false; 761 return false;
760 762
761 // delete old file if any 763 // delete old file if any
762 unlink(oldName); 764 unlink(oldName);
763 765
764 rename(authfile, oldName); 766 rename(authfile, oldName);
765 rename(newName, authfile); 767 rename(newName, authfile);
766 768
767 return true; 769 return true;
768} 770}
769 771
770 772
771bool Modem::removeAuthFile(Auth method) { 773bool Modem::removeAuthFile(Auth method) {
772 const char *authfile, *oldName; 774 const char *authfile, *oldName;
773 775
774 if(!(authfile = authFile(method))) 776 if(!(authfile = authFile(method)))
775 return false; 777 return false;
776 if(!(oldName = authFile(method, Old))) 778 if(!(oldName = authFile(method, Old)))
777 return false; 779 return false;
778 780
779 if(access(oldName, F_OK) == 0) { 781 if(access(oldName, F_OK) == 0) {
780 unlink(authfile); 782 unlink(authfile);
781 return (rename(oldName, authfile) == 0); 783 return (rename(oldName, authfile) == 0);
782 } else 784 } else
783 return false; 785 return false;
784} 786}
785 787
786 788
787bool Modem::setSecret(int method, const char* name, const char* password) 789bool Modem::setSecret(int method, const char* name, const char* password)
788{ 790{
789 791
790 Auth auth; 792 Auth auth;
791 if(method == AUTH_PAPCHAP) 793 if(method == AUTH_PAPCHAP)
792 return setSecret(AUTH_PAP, name, password) && 794 return setSecret(AUTH_PAP, name, password) &&
793 setSecret(AUTH_CHAP, name, password); 795 setSecret(AUTH_CHAP, name, password);
794 796
795 switch(method) { 797 switch(method) {
796 case AUTH_PAP: 798 case AUTH_PAP:
797 auth = Modem::PAP; 799 auth = Modem::PAP;
798 break; 800 break;
799 case AUTH_CHAP: 801 case AUTH_CHAP:
800 auth = Modem::CHAP; 802 auth = Modem::CHAP;