author | tille <tille> | 2003-05-22 15:08:21 (UTC) |
---|---|---|
committer | tille <tille> | 2003-05-22 15:08:21 (UTC) |
commit | 273857932d4d4af9bf78bfca92f2986163e5f4f6 (patch) (unidiff) | |
tree | fd809cda2eefdbb3d39567f956513511cb43dd3d /noncore/settings/networksettings/ppp/modem.cpp | |
parent | 4364269ddceef65bf06f475e2dcface882d37ed4 (diff) | |
download | opie-273857932d4d4af9bf78bfca92f2986163e5f4f6.zip opie-273857932d4d4af9bf78bfca92f2986163e5f4f6.tar.gz opie-273857932d4d4af9bf78bfca92f2986163e5f4f6.tar.bz2 |
finds the modem of my laptop now,
thanks to the kppp team
Diffstat (limited to 'noncore/settings/networksettings/ppp/modem.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/settings/networksettings/ppp/modem.cpp | 671 |
1 files changed, 671 insertions, 0 deletions
diff --git a/noncore/settings/networksettings/ppp/modem.cpp b/noncore/settings/networksettings/ppp/modem.cpp new file mode 100644 index 0000000..e9e3f06 --- a/dev/null +++ b/noncore/settings/networksettings/ppp/modem.cpp | |||
@@ -0,0 +1,671 @@ | |||
1 | /* | ||
2 | * kPPP: A pppd Front End for the KDE project | ||
3 | * | ||
4 | * $Id$ | ||
5 | * | ||
6 | * Copyright (C) 1997 Bernd Johannes Wuebben | ||
7 | * wuebben@math.cornell.edu | ||
8 | * | ||
9 | * This file was added by Harri Porten <porten@tu-harburg.de> | ||
10 | * | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU Library General Public | ||
14 | * License as published by the Free Software Foundation; either | ||
15 | * version 2 of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
20 | * Library General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU Library General Public | ||
23 | * License along with this program; if not, write to the Free | ||
24 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | ||
26 | |||
27 | #include <errno.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <fcntl.h> | ||
30 | #include <signal.h> | ||
31 | #include <sys/ioctl.h> | ||
32 | #include <setjmp.h> | ||
33 | #include <qregexp.h> | ||
34 | #include <assert.h> | ||
35 | |||
36 | #include "modem.h" | ||
37 | #include "pppdata.h" | ||
38 | //#include "requester.h" | ||
39 | //#include <klocale.h> | ||
40 | #define i18n QObject::tr | ||
41 | #define qError qDebug | ||
42 | //#include <kdebug.h> | ||
43 | //#include <config.h> | ||
44 | |||
45 | #define MY_ASSERT(x) if (!(x)) { \ | ||
46 | qFatal( "ASSERT: \"%s\" in %s (%d)\n",#x,__FILE__,__LINE__); \ | ||
47 | exit(1); } | ||
48 | |||
49 | |||
50 | static sigjmp_buf jmp_buffer; | ||
51 | |||
52 | Modem *Modem::modem = 0; | ||
53 | |||
54 | Modem::Modem() : | ||
55 | modemfd(-1), | ||
56 | sn(0L), | ||
57 | data_mode(false), | ||
58 | modem_is_locked(false) | ||
59 | { | ||
60 | lockfile[0] = '\0'; | ||
61 | device = "/dev/modem"; | ||
62 | assert(modem==0); | ||
63 | modem = this; | ||
64 | } | ||
65 | |||
66 | |||
67 | Modem::~Modem() { | ||
68 | modem = 0; | ||
69 | } | ||
70 | |||
71 | |||
72 | speed_t Modem::modemspeed() { | ||
73 | // convert the string modem speed int the gpppdata object to a t_speed type | ||
74 | // to set the modem. The constants here should all be ifdef'd because | ||
75 | // other systems may not have them | ||
76 | int i = gpppdata.speed().toInt()/100; | ||
77 | |||
78 | switch(i) { | ||
79 | case 24: | ||
80 | return B2400; | ||
81 | break; | ||
82 | case 96: | ||
83 | return B9600; | ||
84 | break; | ||
85 | case 192: | ||
86 | return B19200; | ||
87 | break; | ||
88 | case 384: | ||
89 | return B38400; | ||
90 | break; | ||
91 | #ifdef B57600 | ||
92 | case 576: | ||
93 | return B57600; | ||
94 | break; | ||
95 | #endif | ||
96 | |||
97 | #ifdef B115200 | ||
98 | case 1152: | ||
99 | return B115200; | ||
100 | break; | ||
101 | #endif | ||
102 | |||
103 | #ifdef B230400 | ||
104 | case 2304: | ||
105 | return B230400; | ||
106 | break; | ||
107 | #endif | ||
108 | |||
109 | #ifdef B460800 | ||
110 | case 4608: | ||
111 | return B460800; | ||
112 | break; | ||
113 | #endif | ||
114 | |||
115 | default: | ||
116 | return B38400; | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | bool Modem::opentty() { | ||
122 | // int flags; | ||
123 | |||
124 | //begin if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) { | ||
125 | close(modemfd); | ||
126 | // device = "/dev/modem";//deviceByIndex(request.modem.deviceNum); | ||
127 | if ((modemfd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) == -1) { | ||
128 | qDebug("error opening modem device !"); | ||
129 | errmsg = i18n("Unable to open modem."); | ||
130 | return false; | ||
131 | } | ||
132 | //bend if((modemfd = Requester::rq->openModem(gpppdata.modemDevice()))<0) { | ||
133 | //} | ||
134 | |||
135 | #if 0 | ||
136 | if(gpppdata.UseCDLine()) { | ||
137 | if(ioctl(modemfd, TIOCMGET, &flags) == -1) { | ||
138 | errmsg = i18n("Unable to detect state of CD line."); | ||
139 | ::close(modemfd); | ||
140 | modemfd = -1; | ||
141 | return false; | ||
142 | } | ||
143 | if ((flags&TIOCM_CD) == 0) { | ||
144 | errmsg = i18n("The modem is not ready."); | ||
145 | ::close(modemfd); | ||
146 | modemfd = -1; | ||
147 | return false; | ||
148 | } | ||
149 | } | ||
150 | #endif | ||
151 | |||
152 | tcdrain (modemfd); | ||
153 | tcflush (modemfd, TCIOFLUSH); | ||
154 | |||
155 | if(tcgetattr(modemfd, &tty) < 0){ | ||
156 | // this helps in some cases | ||
157 | tcsendbreak(modemfd, 0); | ||
158 | sleep(1); | ||
159 | if(tcgetattr(modemfd, &tty) < 0){ | ||
160 | errmsg = i18n("The modem is busy."); | ||
161 | ::close(modemfd); | ||
162 | modemfd = -1; | ||
163 | return false; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | memset(&initial_tty,'\0',sizeof(initial_tty)); | ||
168 | |||
169 | initial_tty = tty; | ||
170 | |||
171 | tty.c_cc[VMIN] = 0; // nonblocking | ||
172 | tty.c_cc[VTIME] = 0; | ||
173 | tty.c_oflag = 0; | ||
174 | tty.c_lflag = 0; | ||
175 | |||
176 | tty.c_cflag &= ~(CSIZE | CSTOPB | PARENB); | ||
177 | tty.c_cflag |= CS8 | CREAD; | ||
178 | tty.c_cflag |= CLOCAL; // ignore modem status lines | ||
179 | tty.c_iflag = IGNBRK | IGNPAR /* | ISTRIP */ ; | ||
180 | tty.c_lflag &= ~ICANON; // non-canonical mode | ||
181 | tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE); | ||
182 | |||
183 | |||
184 | if(gpppdata.flowcontrol() != "None") { | ||
185 | if(gpppdata.flowcontrol() == "CRTSCTS") { | ||
186 | tty.c_cflag |= CRTSCTS; | ||
187 | } | ||
188 | else { | ||
189 | tty.c_iflag |= IXON | IXOFF; | ||
190 | tty.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ | ||
191 | tty.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ | ||
192 | } | ||
193 | } | ||
194 | else { | ||
195 | tty.c_cflag &= ~CRTSCTS; | ||
196 | tty.c_iflag &= ~(IXON | IXOFF); | ||
197 | } | ||
198 | |||
199 | cfsetospeed(&tty, modemspeed()); | ||
200 | cfsetispeed(&tty, modemspeed()); | ||
201 | |||
202 | tcdrain(modemfd); | ||
203 | |||
204 | if(tcsetattr(modemfd, TCSANOW, &tty) < 0){ | ||
205 | errmsg = i18n("The modem is busy."); | ||
206 | ::close(modemfd); | ||
207 | modemfd=-1; | ||
208 | return false; | ||
209 | } | ||
210 | |||
211 | errmsg = i18n("Modem Ready."); | ||
212 | return true; | ||
213 | } | ||
214 | |||
215 | |||
216 | bool Modem::closetty() { | ||
217 | if(modemfd >=0 ) { | ||
218 | stop(); | ||
219 | /* discard data not read or transmitted */ | ||
220 | tcflush(modemfd, TCIOFLUSH); | ||
221 | |||
222 | if(tcsetattr(modemfd, TCSANOW, &initial_tty) < 0){ | ||
223 | errmsg = i18n("Can't restore tty settings: tcsetattr()\n"); | ||
224 | ::close(modemfd); | ||
225 | modemfd = -1; | ||
226 | return false; | ||
227 | } | ||
228 | ::close(modemfd); | ||
229 | modemfd = -1; | ||
230 | } | ||
231 | |||
232 | return true; | ||
233 | } | ||
234 | |||
235 | |||
236 | void Modem::readtty(int) { | ||
237 | char buffer[200]; | ||
238 | unsigned char c; | ||
239 | int len; | ||
240 | |||
241 | // read data in chunks of up to 200 bytes | ||
242 | if((len = ::read(modemfd, buffer, 200)) > 0) { | ||
243 | // split buffer into single characters for further processing | ||
244 | for(int i = 0; i < len; i++) { | ||
245 | c = buffer[i] & 0x7F; | ||
246 | emit charWaiting(c); | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | |||
251 | |||
252 | void Modem::notify(const QObject *receiver, const char *member) { | ||
253 | connect(this, SIGNAL(charWaiting(unsigned char)), receiver, member); | ||
254 | startNotifier(); | ||
255 | } | ||
256 | |||
257 | |||
258 | void Modem::stop() { | ||
259 | disconnect(SIGNAL(charWaiting(unsigned char))); | ||
260 | stopNotifier(); | ||
261 | } | ||
262 | |||
263 | |||
264 | void Modem::startNotifier() { | ||
265 | if(modemfd >= 0) { | ||
266 | if(sn == 0) { | ||
267 | sn = new QSocketNotifier(modemfd, QSocketNotifier::Read, this); | ||
268 | connect(sn, SIGNAL(activated(int)), SLOT(readtty(int))); | ||
269 | qDebug("QSocketNotifier started!"); | ||
270 | } else { | ||
271 | qDebug("QSocketNotifier re-enabled!"); | ||
272 | sn->setEnabled(true); | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | |||
277 | |||
278 | void Modem::stopNotifier() { | ||
279 | if(sn != 0) { | ||
280 | sn->setEnabled(false); | ||
281 | disconnect(sn); | ||
282 | delete sn; | ||
283 | sn = 0; | ||
284 | qDebug( "QSocketNotifier stopped!" ); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | |||
289 | void Modem::flush() { | ||
290 | char c; | ||
291 | while(read(modemfd, &c, 1) == 1); | ||
292 | } | ||
293 | |||
294 | |||
295 | bool Modem::writeChar(unsigned char c) { | ||
296 | int s; | ||
297 | do { | ||
298 | s = write(modemfd, &c, 1); | ||
299 | if (s < 0) { | ||
300 | qError( "write() in Modem::writeChar failed" ); | ||
301 | return false; | ||
302 | } | ||
303 | } while(s == 0); | ||
304 | |||
305 | return true; | ||
306 | } | ||
307 | |||
308 | |||
309 | bool Modem::writeLine(const char *buf) { | ||
310 | int len = strlen(buf); | ||
311 | char *b = new char[len+2]; | ||
312 | memcpy(b, buf, len); | ||
313 | // different modems seem to need different line terminations | ||
314 | QString term = gpppdata.enter(); | ||
315 | if(term == "LF") | ||
316 | b[len++]='\n'; | ||
317 | else if(term == "CR") | ||
318 | b[len++]='\r'; | ||
319 | else if(term == "CR/LF") { | ||
320 | b[len++]='\r'; | ||
321 | b[len++]='\n'; | ||
322 | } | ||
323 | int l = len; | ||
324 | while(l) { | ||
325 | int wr = write(modemfd, &b[len-l], l); | ||
326 | if(wr < 0) { | ||
327 | // TODO do something meaningful with the error code (or ignore it | ||
328 | qError( "write() in Modem::writeLine failed" ); | ||
329 | delete[] b; | ||
330 | return false; | ||
331 | } | ||
332 | l -= wr; | ||
333 | } | ||
334 | delete[] b; | ||
335 | return true; | ||
336 | } | ||
337 | |||
338 | |||
339 | bool Modem::hangup() { | ||
340 | // this should really get the modem to hang up and go into command mode | ||
341 | // If anyone sees a fault in the following please let me know, since | ||
342 | // this is probably the most imporant snippet of code in the whole of | ||
343 | // kppp. If people complain about kppp being stuck, this piece of code | ||
344 | // is most likely the reason. | ||
345 | struct termios temptty; | ||
346 | |||
347 | if(modemfd >= 0) { | ||
348 | |||
349 | // is this Escape & HangupStr stuff really necessary ? (Harri) | ||
350 | |||
351 | if (data_mode) escape_to_command_mode(); | ||
352 | |||
353 | // Then hangup command | ||
354 | writeLine(gpppdata.modemHangupStr().local8Bit()); | ||
355 | |||
356 | usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 sec | ||
357 | |||
358 | #ifndef DEBUG_WO_DIALING | ||
359 | if (sigsetjmp(jmp_buffer, 1) == 0) { | ||
360 | // set alarm in case tcsendbreak() hangs | ||
361 | signal(SIGALRM, alarm_handler); | ||
362 | alarm(2); | ||
363 | |||
364 | tcsendbreak(modemfd, 0); | ||
365 | |||
366 | alarm(0); | ||
367 | signal(SIGALRM, SIG_IGN); | ||
368 | } else { | ||
369 | // we reach this point if the alarm handler got called | ||
370 | closetty(); | ||
371 | close(modemfd); | ||
372 | modemfd = -1; | ||
373 | errmsg = i18n("The modem does not respond."); | ||
374 | return false; | ||
375 | } | ||
376 | |||
377 | #ifndef __svr4__ // drops DTR but doesn't set it afterwards again. not good for init. | ||
378 | tcgetattr(modemfd, &temptty); | ||
379 | cfsetospeed(&temptty, B0); | ||
380 | cfsetispeed(&temptty, B0); | ||
381 | tcsetattr(modemfd, TCSAFLUSH, &temptty); | ||
382 | #else | ||
383 | int modemstat; | ||
384 | ioctl(modemfd, TIOCMGET, &modemstat); | ||
385 | modemstat &= ~TIOCM_DTR; | ||
386 | ioctl(modemfd, TIOCMSET, &modemstat); | ||
387 | ioctl(modemfd, TIOCMGET, &modemstat); | ||
388 | modemstat |= TIOCM_DTR; | ||
389 | ioctl(modemfd, TIOCMSET, &modemstat); | ||
390 | #endif | ||
391 | |||
392 | usleep(gpppdata.modemInitDelay() * 10000); // 0.01 - 3.0 secs | ||
393 | |||
394 | cfsetospeed(&temptty, modemspeed()); | ||
395 | cfsetispeed(&temptty, modemspeed()); | ||
396 | tcsetattr(modemfd, TCSAFLUSH, &temptty); | ||
397 | #endif | ||
398 | return true; | ||
399 | } else | ||
400 | return false; | ||
401 | } | ||
402 | |||
403 | |||
404 | void Modem::escape_to_command_mode() { | ||
405 | // Send Properly bracketed escape code to put the modem back into command state. | ||
406 | // A modem will accept AT commands only when it is in command state. | ||
407 | // When a modem sends the host the CONNECT string, that signals | ||
408 | // that the modem is now in the connect state (no long accepts AT commands.) | ||
409 | // Need to send properly timed escape sequence to put modem in command state. | ||
410 | // Escape codes and guard times are controlled by S2 and S12 values. | ||
411 | // | ||
412 | tcflush(modemfd, TCIOFLUSH); | ||
413 | |||
414 | // +3 because quiet time must be greater than guard time. | ||
415 | usleep((gpppdata.modemEscapeGuardTime()+3)*20000); | ||
416 | QCString tmp = gpppdata.modemEscapeStr().local8Bit(); | ||
417 | write(modemfd, tmp.data(), tmp.length()); | ||
418 | tcflush(modemfd, TCIOFLUSH); | ||
419 | usleep((gpppdata.modemEscapeGuardTime()+3)*20000); | ||
420 | |||
421 | data_mode = false; | ||
422 | } | ||
423 | |||
424 | |||
425 | const QString Modem::modemMessage() { | ||
426 | return errmsg; | ||
427 | } | ||
428 | |||
429 | |||
430 | QString Modem::parseModemSpeed(const QString &s) { | ||
431 | // this is a small (and bad) parser for modem speeds | ||
432 | int rx = -1; | ||
433 | int tx = -1; | ||
434 | int i; | ||
435 | QString result; | ||
436 | |||
437 | qDebug( "Modem reported result string: %s", s.latin1()); | ||
438 | |||
439 | const int RXMAX = 7; | ||
440 | const int TXMAX = 2; | ||
441 | QRegExp rrx[RXMAX] = { | ||
442 | QRegExp("[0-9]+[:/ ]RX", false), | ||
443 | QRegExp("[0-9]+RX", false), | ||
444 | QRegExp("[/: -][0-9]+[/: ]", false), | ||
445 | QRegExp("[/: -][0-9]+$", false), | ||
446 | QRegExp("CARRIER [^0-9]*[0-9]+", false), | ||
447 | QRegExp("CONNECT [^0-9]*[0-9]+", false), | ||
448 | QRegExp("[0-9]+") // panic mode | ||
449 | }; | ||
450 | |||
451 | QRegExp trx[TXMAX] = { | ||
452 | QRegExp("[0-9]+[:/ ]TX", false), | ||
453 | QRegExp("[0-9]+TX", false) | ||
454 | }; | ||
455 | |||
456 | for(i = 0; i < RXMAX; i++) { | ||
457 | int len, idx, result; | ||
458 | if((idx = rrx[i].match(s,0,&len)) > -1) { | ||
459 | // if((idx = rrx[i].search(s)) > -1) { | ||
460 | // len = rrx[i].matchedLength(); | ||
461 | |||
462 | // | ||
463 | // rrx[i] has been matched, idx contains the start of the match | ||
464 | // and len contains how long the match is. Extract the match. | ||
465 | // | ||
466 | QString sub = s.mid(idx, len); | ||
467 | |||
468 | // | ||
469 | // Now extract the digits only from the match, which will | ||
470 | // then be converted to an int. | ||
471 | // | ||
472 | if ((idx = rrx[RXMAX-1].match( sub,0,&len )) > -1) { | ||
473 | // if ((idx = rrx[RXMAX-1].search( sub )) > -1) { | ||
474 | // len = rrx[RXMAX-1].matchedLength(); | ||
475 | sub = sub.mid(idx, len); | ||
476 | result = sub.toInt(); | ||
477 | if(result > 0) { | ||
478 | rx = result; | ||
479 | break; | ||
480 | } | ||
481 | } | ||
482 | } | ||
483 | } | ||
484 | |||
485 | for(i = 0; i < TXMAX; i++) { | ||
486 | int len, idx, result; | ||
487 | if((idx = trx[i].match(s,0,&len)) > -1) { | ||
488 | // if((idx = trx[i].search(s)) > -1) { | ||
489 | // len = trx[i].matchedLength(); | ||
490 | |||
491 | // | ||
492 | // trx[i] has been matched, idx contains the start of the match | ||
493 | // and len contains how long the match is. Extract the match. | ||
494 | // | ||
495 | QString sub = s.mid(idx, len); | ||
496 | |||
497 | // | ||
498 | // Now extract the digits only from the match, which will then | ||
499 | // be converted to an int. | ||
500 | // | ||
501 | if((idx = rrx[RXMAX-1].match(sub,0,&len)) > -1) { | ||
502 | // if((idx = rrx[RXMAX-1].search(sub)) > -1) { | ||
503 | // len = rrx[RXMAX-1].matchedLength(); | ||
504 | sub = sub.mid(idx, len); | ||
505 | result = sub.toInt(); | ||
506 | if(result > 0) { | ||
507 | tx = result; | ||
508 | break; | ||
509 | } | ||
510 | } | ||
511 | } | ||
512 | } | ||
513 | |||
514 | if(rx == -1 && tx == -1) | ||
515 | result = i18n("Unknown speed"); | ||
516 | else if(tx == -1) | ||
517 | result.setNum(rx); | ||
518 | else if(rx == -1) // should not happen | ||
519 | result.setNum(tx); | ||
520 | else | ||
521 | result.sprintf("%d/%d", rx, tx); | ||
522 | |||
523 | qDebug( "The parsed result is: %s", result.latin1()); | ||
524 | |||
525 | return result; | ||
526 | } | ||
527 | |||
528 | |||
529 | // Lock modem device. Returns 0 on success 1 if the modem is locked and -1 if | ||
530 | // a lock file can't be created ( permission problem ) | ||
531 | int Modem::lockdevice() { | ||
532 | int fd; | ||
533 | char newlock[80]=""; // safe | ||
534 | |||
535 | if(!gpppdata.modemLockFile()) { | ||
536 | qDebug("The user doesn't want a lockfile."); | ||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | if (modem_is_locked) | ||
541 | return 1; | ||
542 | |||
543 | QString lockfile = LOCK_DIR"/LCK.."; | ||
544 | lockfile += gpppdata.modemDevice().mid(5); // append everything after /dev/ | ||
545 | |||
546 | if(access(QFile::encodeName(lockfile), F_OK) == 0) { | ||
547 | // if ((fd = Requester::rq-> | ||
548 | if ((fd = openLockfile(QFile::encodeName(lockfile), O_RDONLY)) >= 0) { | ||
549 | // Mario: it's not necessary to read more than lets say 32 bytes. If | ||
550 | // file has more than 32 bytes, skip the rest | ||
551 | char oldlock[33]; // safe | ||
552 | int sz = read(fd, &oldlock, 32); | ||
553 | close (fd); | ||
554 | if (sz <= 0) | ||
555 | return 1; | ||
556 | oldlock[sz] = '\0'; | ||
557 | |||
558 | qDebug( "Device is locked by: %s", oldlock); | ||
559 | |||
560 | int oldpid; | ||
561 | int match = sscanf(oldlock, "%d", &oldpid); | ||
562 | |||
563 | // found a pid in lockfile ? | ||
564 | if (match < 1 || oldpid <= 0) | ||
565 | return 1; | ||
566 | |||
567 | // check if process exists | ||
568 | if (kill((pid_t)oldpid, 0) == 0 || errno != ESRCH) | ||
569 | return 1; | ||
570 | |||
571 | qDebug( "lockfile is stale" ); | ||
572 | } | ||
573 | } | ||
574 | |||
575 | fd = openLockfile(gpppdata.modemDevice(),O_WRONLY|O_TRUNC|O_CREAT); | ||
576 | if(fd >= 0) { | ||
577 | sprintf(newlock,"%010d\n", getpid()); | ||
578 | qDebug("Locking Device: %s", newlock); | ||
579 | |||
580 | write(fd, newlock, strlen(newlock)); | ||
581 | close(fd); | ||
582 | modem_is_locked=true; | ||
583 | |||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | return -1; | ||
588 | |||
589 | } | ||
590 | |||
591 | |||
592 | // UnLock modem device | ||
593 | void Modem::unlockdevice() { | ||
594 | if (modem_is_locked) { | ||
595 | qDebug( "UnLocking Modem Device" ); | ||
596 | close(modemfd); | ||
597 | modemfd = -1; | ||
598 | unlink(lockfile); | ||
599 | lockfile[0] = '\0'; | ||
600 | modem_is_locked=false; | ||
601 | } | ||
602 | } | ||
603 | |||
604 | int Modem::openLockfile( QString lockfile, int flags) | ||
605 | { | ||
606 | int fd; | ||
607 | int mode; | ||
608 | flags = O_RDONLY; | ||
609 | if(flags == O_WRONLY|O_TRUNC|O_CREAT) | ||
610 | mode = 0644; | ||
611 | else | ||
612 | mode = 0; | ||
613 | |||
614 | lockfile = LOCK_DIR; | ||
615 | lockfile += "/LCK.."; | ||
616 | lockfile += device.right( device.length() - device.findRev("/") -1 ); | ||
617 | qDebug("lockfile >%s<",lockfile.latin1()); | ||
618 | // TODO: | ||
619 | // struct stat st; | ||
620 | // if(stat(lockfile.data(), &st) == -1) { | ||
621 | // if(errno == EBADF) | ||
622 | // return -1; | ||
623 | // } else { | ||
624 | // // make sure that this is a regular file | ||
625 | // if(!S_ISREG(st.st_mode)) | ||
626 | // return -1; | ||
627 | // } | ||
628 | if ((fd = open(lockfile, flags, mode)) == -1) { | ||
629 | qDebug("error opening lockfile!"); | ||
630 | lockfile = QString::null; | ||
631 | fd = open(DEVNULL, O_RDONLY); | ||
632 | } else | ||
633 | fchown(fd, 0, 0); | ||
634 | return fd; | ||
635 | } | ||
636 | |||
637 | |||
638 | |||
639 | void alarm_handler(int) { | ||
640 | // fprintf(stderr, "alarm_handler(): Received SIGALRM\n"); | ||
641 | |||
642 | // jump | ||
643 | siglongjmp(jmp_buffer, 1); | ||
644 | } | ||
645 | |||
646 | |||
647 | |||
648 | const char* pppdPath() { | ||
649 | // wasting a few bytes | ||
650 | static char buffer[sizeof(PPPDSEARCHPATH)+sizeof(PPPDNAME)]; | ||
651 | static char *pppdPath = 0L; | ||
652 | char *p; | ||
653 | |||
654 | if(pppdPath == 0L) { | ||
655 | const char *c = PPPDSEARCHPATH; | ||
656 | while(*c != '\0') { | ||
657 | while(*c == ':') | ||
658 | c++; | ||
659 | p = buffer; | ||
660 | while(*c != '\0' && *c != ':') | ||
661 | *p++ = *c++; | ||
662 | *p = '\0'; | ||
663 | strcat(p, "/"); | ||
664 | strcat(p, PPPDNAME); | ||
665 | if(access(buffer, F_OK) == 0) | ||
666 | return (pppdPath = buffer); | ||
667 | } | ||
668 | } | ||
669 | |||
670 | return pppdPath; | ||
671 | } | ||