-rw-r--r-- | noncore/settings/networksettings/ppp/modem.cpp | 2 |
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 | |||
@@ -223,801 +223,801 @@ bool Modem::opentty() { | |||
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 | ||
259 | bool Modem::closetty() { | 259 | bool 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 | ||
279 | void Modem::readtty(int) { | 279 | void 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 | ||
295 | void Modem::notify(const QObject *receiver, const char *member) { | 295 | void 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 | ||
301 | void Modem::stop() { | 301 | void Modem::stop() { |
302 | disconnect(SIGNAL(charWaiting(unsigned char))); | 302 | disconnect(SIGNAL(charWaiting(unsigned char))); |
303 | stopNotifier(); | 303 | stopNotifier(); |
304 | } | 304 | } |
305 | 305 | ||
306 | 306 | ||
307 | void Modem::startNotifier() { | 307 | void 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 | ||
321 | void Modem::stopNotifier() { | 321 | void 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 | ||
332 | void Modem::flush() { | 332 | void 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 | ||
338 | bool Modem::writeChar(unsigned char c) { | 338 | bool 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 | ||
352 | bool Modem::writeLine(const char *buf) { | 352 | bool 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 | ||
382 | bool Modem::hangup() { | 382 | bool 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 | ||
447 | void Modem::escape_to_command_mode() { | 447 | void 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 | ||
468 | const QString Modem::modemMessage() { | 468 | const QString Modem::modemMessage() { |
469 | return errmsg; | 469 | return errmsg; |
470 | } | 470 | } |
471 | 471 | ||
472 | 472 | ||
473 | QString Modem::parseModemSpeed(const QString &s) { | 473 | QString 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 ) |
574 | int Modem::lockdevice() { | 574 | int 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-> |
591 | if ((fd = openLockfile(QFile::encodeName(lockfile), O_RDONLY)) >= 0) { | 591 | if ((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 |
636 | void Modem::unlockdevice() { | 636 | void 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 | ||
647 | int Modem::openLockfile( QString lockfile, int flags) | 647 | int 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 | ||
682 | void alarm_handler(int) { | 682 | void 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 | ||
690 | const char* Modem::authFile(Auth method, int version) { | 690 | const 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 | ||
716 | bool Modem::createAuthFile(Auth method, const char *username, const char *password) { | 716 | bool 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 | ||
773 | bool Modem::removeAuthFile(Auth method) { | 773 | bool 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 | ||
789 | bool Modem::setSecret(int method, const char* name, const char* password) | 789 | bool 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 | ||
812 | bool Modem::removeSecret(int method) | 812 | bool 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 | ||
829 | int checkForInterface() | 829 | int 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 | ||
870 | bool Modem::execpppd(const char *arguments) { | 870 | bool 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 | ||
934 | bool Modem::killpppd() { | 934 | bool 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 | ||
949 | void Modem::parseargs(char* buf, char** args) { | 949 | void 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 | ||
989 | bool Modem::execPPPDaemon(const QString & arguments) | 989 | bool 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 | ||
998 | void Modem::killPPPDaemon() | 998 | void Modem::killPPPDaemon() |
999 | { | 999 | { |
1000 | _pppdata->setpppdRunning(false); | 1000 | _pppdata->setpppdRunning(false); |
1001 | killpppd(); | 1001 | killpppd(); |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | int Modem::pppdExitStatus() | 1004 | int Modem::pppdExitStatus() |
1005 | { | 1005 | { |
1006 | return _pppdExitStatus; | 1006 | return _pppdExitStatus; |
1007 | } | 1007 | } |
1008 | 1008 | ||
1009 | int Modem::openResolv(int flags) | 1009 | int 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 | ||
1019 | bool Modem::setHostname(const QString & name) | 1019 | bool 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 | ||