Diffstat (limited to 'noncore/settings/networksettings2/networksettings2/system.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/settings/networksettings2/networksettings2/system.cpp | 286 |
1 files changed, 213 insertions, 73 deletions
diff --git a/noncore/settings/networksettings2/networksettings2/system.cpp b/noncore/settings/networksettings2/networksettings2/system.cpp index 298bdc9..141484c 100644 --- a/noncore/settings/networksettings2/networksettings2/system.cpp +++ b/noncore/settings/networksettings2/networksettings2/system.cpp | |||
@@ -10,12 +10,14 @@ | |||
10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include <stdio.h> | 11 | #include <stdio.h> |
12 | #include <fcntl.h> | 12 | #include <fcntl.h> |
13 | #include <errno.h> | 13 | #include <errno.h> |
14 | #include <unistd.h> | 14 | #include <unistd.h> |
15 | 15 | ||
16 | #include <opie2/oprocess.h> | ||
17 | |||
16 | #include <qdir.h> | 18 | #include <qdir.h> |
17 | #include <qregexp.h> | 19 | #include <qregexp.h> |
18 | #include <qstringlist.h> | 20 | #include <qstringlist.h> |
19 | #include <qfile.h> | 21 | #include <qfile.h> |
20 | #include <qtextstream.h> | 22 | #include <qtextstream.h> |
21 | #include <qapplication.h> | 23 | #include <qapplication.h> |
@@ -47,69 +49,124 @@ System::System( void ) : QObject(), ProbedInterfaces() { | |||
47 | 49 | ||
48 | System::~System( void ) { | 50 | System::~System( void ) { |
49 | if( ProcDevNet ) | 51 | if( ProcDevNet ) |
50 | delete ProcDevNet; | 52 | delete ProcDevNet; |
51 | } | 53 | } |
52 | 54 | ||
53 | int System::runAsRoot( const QString & S ) { | 55 | int System::runAsRoot( QStringList & S ) { |
54 | QString MyS = S; | ||
55 | char * usr = getenv("USER"); | 56 | char * usr = getenv("USER"); |
56 | char ch; | ||
57 | 57 | ||
58 | if( S.isEmpty() ) { | 58 | if( S.count() == 0 ) { |
59 | // loophole to start shell | 59 | // loophole to start shell |
60 | return 8888; | 60 | return 8888; |
61 | } | 61 | } |
62 | if( usr == 0 || strcmp( usr, "root" ) ) { | 62 | if( usr == 0 || strcmp( usr, "root" ) ) { |
63 | // unknown or non-root user -> use SUDO | 63 | // unknown or non-root user -> use SUDO |
64 | MyS.prepend( "sudo " ); | 64 | S.prepend( "sudo" ); |
65 | } | 65 | } |
66 | 66 | ||
67 | Log(("Executing %s\n", MyS.latin1() )); | 67 | if( getenv( "NS2TESTMODE" ) ) { |
68 | owarn << "TESTMODE !!! execute " | ||
69 | << S.join( " ") | ||
70 | << oendl; | ||
71 | } else { | ||
72 | MyProcess * P = new MyProcess(); | ||
73 | emit processEvent( tr("Command : ") + S.join( " " ) ); | ||
74 | |||
75 | P->process() << S; | ||
76 | |||
77 | connect( P, | ||
78 | SIGNAL( stdoutLine( const QString & ) ), | ||
79 | this, | ||
80 | SIGNAL( stdoutLine( const QString & ) ) ); | ||
81 | |||
82 | connect( P, | ||
83 | SIGNAL( stderrLine( const QString & ) ), | ||
84 | this, | ||
85 | SIGNAL( stderrLine( const QString & ) ) ); | ||
86 | |||
87 | connect( P, | ||
88 | SIGNAL(processExited(MyProcess*) ), | ||
89 | this, SLOT | ||
90 | (SLOT_ProcessExited(MyProcess*) ) ); | ||
68 | 91 | ||
69 | emit lineFromCommand( tr("Command : ") + MyS ); | 92 | Log(("Executing %s\n", S.join( " " ).latin1() )); |
70 | emit lineFromCommand( "---------------" ); | 93 | |
71 | Log(( "Command : %s\n", MyS.latin1() ) ); | 94 | if( ! P->process().start( OProcess::DontCare, |
72 | MyS += " 2>&1 "; | 95 | OProcess::AllOutput ) ) { |
73 | OutputOfCmd = popen( MyS.latin1(), "r" ) ; | 96 | owarn << "Error starting " << S << oendl; |
74 | if( ! OutputOfCmd ) { | 97 | delete P; |
75 | // cannot fork | 98 | // error starting app |
76 | return 1; | 99 | return 1; |
77 | } | 100 | } |
101 | owarn << "Started " << S << oendl; | ||
102 | } | ||
78 | 103 | ||
79 | // read all data | 104 | // all is fine |
80 | QString Line = ""; | 105 | return 0; |
81 | while( 1 ) { | ||
82 | if( fread( &ch, 1, 1, OutputOfCmd ) < 1 ) | ||
83 | // eof | ||
84 | break; | ||
85 | if( ch == '\n' || ch == '\r' ) { | ||
86 | if( ! Line.isEmpty() ) { | ||
87 | Log(( "read cmd output : **%s**\n", Line.latin1() ) ); | ||
88 | emit lineFromCommand( Line ); | ||
89 | Line = ""; | ||
90 | qApp->processEvents(); | ||
91 | } | 106 | } |
92 | } else { | 107 | |
93 | Line += ch; | 108 | int System::execAsUser( QStringList & SL ) { |
109 | MyProcess * P = new MyProcess(); | ||
110 | CurrentQPEUser CU = NSResources->currentUser(); | ||
111 | char * usr = getenv("USER"); | ||
112 | |||
113 | if( strcmp( usr, "root" ) == 0 ) { | ||
114 | // find user running qpe | ||
115 | if( CU.UserName.isEmpty() ) { | ||
116 | // if we come here, the exec was not successfull | ||
117 | Log(("User not known \n" )); | ||
118 | return 0; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | // now we are ready to exec the requested command | ||
123 | setuid( CU.Uid ); | ||
124 | setgid( CU.Gid ); | ||
125 | |||
126 | for( unsigned int i = 0 ; i < CU.EnvList.count() ; i ++ ) { | ||
127 | QString X; | ||
128 | QStringList SL; | ||
129 | X = CU.EnvList[i]; | ||
130 | SL = QStringList::split( "=", X ); | ||
131 | P->process().setEnvironment( SL[0], SL[1] ); | ||
94 | } | 132 | } |
133 | |||
134 | P->process() << SL; | ||
135 | |||
136 | emit processEvent( tr("Command : ") + SL.join( " " ) ); | ||
137 | |||
138 | Log(("Executing as user %s : %s\n", | ||
139 | CU.UserName.latin1(), | ||
140 | SL.join( " " ).latin1() )); | ||
141 | |||
142 | int rv = ( P->process().start( OProcess::DontCare, | ||
143 | OProcess::NoCommunication ) ); | ||
144 | delete P; | ||
145 | |||
146 | if( rv ) { | ||
147 | // if we come here, the exec was not successfull | ||
148 | Log(("Could not exec : %d\n", errno )); | ||
95 | } | 149 | } |
96 | 150 | ||
97 | if( ! Line.isEmpty() ) { | 151 | return rv; |
98 | emit lineFromCommand( Line ); | ||
99 | Log(( "read cmd output : **%s**\n", Line.latin1() ) ); | ||
100 | } | 152 | } |
101 | Log(( "End of command\n", Line.latin1() ) ); | ||
102 | 153 | ||
103 | if( pclose( OutputOfCmd ) < 0 ) { | 154 | void System::SLOT_ProcessExited( MyProcess * P ) { |
104 | // error in command | 155 | QString R; |
105 | return 3; | 156 | |
157 | for( QValueListConstIterator<QCString> it = P->process().args().begin(); | ||
158 | it != P->process().args().end(); | ||
159 | ++it ) { | ||
160 | R += (*it); | ||
161 | R += " "; | ||
106 | } | 162 | } |
107 | 163 | ||
108 | // all is fine | 164 | R += "Returned with " + QString().setNum( P->process().exitStatus() ); |
109 | return 0; | 165 | emit processEvent( R ); |
166 | delete P; | ||
110 | } | 167 | } |
111 | 168 | ||
112 | void System::refreshStatistics( InterfaceInfo & I ) { | 169 | void System::refreshStatistics( InterfaceInfo & I ) { |
113 | if( ! ProcDevNet ) { | 170 | if( ! ProcDevNet ) { |
114 | return; | 171 | return; |
115 | } | 172 | } |
@@ -195,21 +252,35 @@ void System::probeInterfaces( void ) { | |||
195 | it.current(); | 252 | it.current(); |
196 | ++it ) { | 253 | ++it ) { |
197 | it.current()->IsUp = 0; | 254 | it.current()->IsUp = 0; |
198 | } | 255 | } |
199 | 256 | ||
200 | sockfd = socket(PF_INET, SOCK_DGRAM, 0); | 257 | sockfd = socket(PF_INET, SOCK_DGRAM, 0); |
201 | if(sockfd == -1) | 258 | if(sockfd == -1) { |
259 | owarn << "Cannot open INET socket " | ||
260 | << errno | ||
261 | << " " | ||
262 | << strerror( errno ) | ||
263 | << oendl; | ||
202 | return; | 264 | return; |
265 | } | ||
203 | 266 | ||
204 | // read interfaces from /proc/dev/net | 267 | // read interfaces from /proc/dev/net |
205 | // SIOCGIFCONF does not return ALL interfaces ???!? | 268 | // SIOCGIFCONF does not return ALL interfaces ???!? |
206 | ProcDevNet = new QFile(PROCNETDEV); | 269 | ProcDevNet = new QFile(PROCNETDEV); |
207 | if( ! ProcDevNet->open(IO_ReadOnly) ) { | 270 | if( ! ProcDevNet->open(IO_ReadOnly) ) { |
271 | owarn << "Cannot open " | ||
272 | << PROCNETDEV | ||
273 | << " " | ||
274 | << errno | ||
275 | << " " | ||
276 | << strerror( errno ) | ||
277 | << oendl; | ||
208 | delete ProcDevNet; | 278 | delete ProcDevNet; |
209 | ProcDevNet =0; | 279 | ProcDevNet =0; |
280 | ::close( sockfd ); | ||
210 | return; | 281 | return; |
211 | } | 282 | } |
212 | 283 | ||
213 | QString line; | 284 | QString line; |
214 | QString NicName; | 285 | QString NicName; |
215 | QTextStream procTs(ProcDevNet); | 286 | QTextStream procTs(ProcDevNet); |
@@ -226,16 +297,16 @@ void System::probeInterfaces( void ) { | |||
226 | 297 | ||
227 | // set name for ioctl | 298 | // set name for ioctl |
228 | strcpy( ifrs.ifr_name, NicName.latin1() ); | 299 | strcpy( ifrs.ifr_name, NicName.latin1() ); |
229 | 300 | ||
230 | if ( ! ( IFI = ProbedInterfaces.find( NicName ) ) ) { | 301 | if ( ! ( IFI = ProbedInterfaces.find( NicName ) ) ) { |
231 | // new nic | 302 | // new nic |
232 | Log(("NEWNIC %s\n", NicName.latin1())); | 303 | Log(("New NIC found : %s\n", NicName.latin1())); |
233 | IFI = new InterfaceInfo; | 304 | IFI = new InterfaceInfo; |
234 | IFI->Name = line.left(loc); | 305 | IFI->Name = line.left(loc); |
235 | IFI->NetNode = 0; | 306 | IFI->Collection = 0; |
236 | ProbedInterfaces.insert( IFI->Name, IFI ); | 307 | ProbedInterfaces.insert( IFI->Name, IFI ); |
237 | 308 | ||
238 | // get dynamic info | 309 | // get dynamic info |
239 | if( ioctl(sockfd, SIOCGIFFLAGS, &ifrs) >= 0 ) { | 310 | if( ioctl(sockfd, SIOCGIFFLAGS, &ifrs) >= 0 ) { |
240 | IFI->IsPointToPoint = ((ifrs.ifr_flags & IFF_POINTOPOINT) == IFF_POINTOPOINT); | 311 | IFI->IsPointToPoint = ((ifrs.ifr_flags & IFF_POINTOPOINT) == IFF_POINTOPOINT); |
241 | } else { | 312 | } else { |
@@ -253,13 +324,13 @@ void System::probeInterfaces( void ) { | |||
253 | } | 324 | } |
254 | 325 | ||
255 | IFI->CardType = 999999; | 326 | IFI->CardType = 999999; |
256 | IFI->MACAddress = ""; | 327 | IFI->MACAddress = ""; |
257 | 328 | ||
258 | if( ioctl(sockfd, SIOCGIFHWADDR, &ifrs) >= 0 ) { | 329 | if( ioctl(sockfd, SIOCGIFHWADDR, &ifrs) >= 0 ) { |
259 | Log(("%s = %d\n", IFI->Name.latin1(), | 330 | Log(("Family for NIC %s : %d\n", IFI->Name.latin1(), |
260 | ifrs.ifr_hwaddr.sa_family )); | 331 | ifrs.ifr_hwaddr.sa_family )); |
261 | 332 | ||
262 | IFI->CardType = ifrs.ifr_hwaddr.sa_family; | 333 | IFI->CardType = ifrs.ifr_hwaddr.sa_family; |
263 | switch( ifrs.ifr_hwaddr.sa_family ) { | 334 | switch( ifrs.ifr_hwaddr.sa_family ) { |
264 | case ARPHRD_ETHER : // regular MAC address | 335 | case ARPHRD_ETHER : // regular MAC address |
265 | // valid address -> convert to regular ::: format | 336 | // valid address -> convert to regular ::: format |
@@ -321,13 +392,13 @@ void System::probeInterfaces( void ) { | |||
321 | break; | 392 | break; |
322 | case ARPHRD_IRDA : // IRDA | 393 | case ARPHRD_IRDA : // IRDA |
323 | break; | 394 | break; |
324 | } | 395 | } |
325 | } | 396 | } |
326 | } else // else already probed before -> just update | 397 | } else // else already probed before -> just update |
327 | Log(("OLDNIC %s\n", NicName.latin1())); | 398 | Log(("Redetected NIC %s\n", NicName.latin1())); |
328 | 399 | ||
329 | // get dynamic info | 400 | // get dynamic info |
330 | if( ioctl(sockfd, SIOCGIFFLAGS, &ifrs) >= 0 ) { | 401 | if( ioctl(sockfd, SIOCGIFFLAGS, &ifrs) >= 0 ) { |
331 | IFI->IsUp = ((ifrs.ifr_flags & IFF_UP) == IFF_UP); | 402 | IFI->IsUp = ((ifrs.ifr_flags & IFF_UP) == IFF_UP); |
332 | IFI->HasMulticast = ((ifrs.ifr_flags & IFF_MULTICAST) == IFF_MULTICAST); | 403 | IFI->HasMulticast = ((ifrs.ifr_flags & IFF_MULTICAST) == IFF_MULTICAST); |
333 | } else { | 404 | } else { |
@@ -351,70 +422,65 @@ void System::probeInterfaces( void ) { | |||
351 | if( ioctl(sockfd, SIOCGIFNETMASK, &ifrs) >= 0 ) { | 422 | if( ioctl(sockfd, SIOCGIFNETMASK, &ifrs) >= 0 ) { |
352 | IFI->Netmask = | 423 | IFI->Netmask = |
353 | inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_netmask)->sin_addr); | 424 | inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_netmask)->sin_addr); |
354 | } else { | 425 | } else { |
355 | IFI->Netmask = ""; | 426 | IFI->Netmask = ""; |
356 | } | 427 | } |
357 | Log(("NIC %s UP %d\n", NicName.latin1(), IFI->IsUp )); | 428 | Log(("NIC %s UP ? %d\n", NicName.latin1(), IFI->IsUp )); |
358 | } | 429 | } |
359 | } | ||
360 | |||
361 | void System::execAsUser( QString & Cmd, char * argv[] ) { | ||
362 | CurrentQPEUser CU = NSResources->currentUser(); | ||
363 | 430 | ||
364 | if( CU.UserName.isEmpty() ) { | 431 | ::close( sockfd ); |
365 | // if we come here, the exec was not successfull | ||
366 | Log(("User not known \n" )); | ||
367 | return; | ||
368 | } | 432 | } |
369 | 433 | ||
370 | // now we are ready to exec the requested command | 434 | InterfaceInfo * System::findInterface( const QString & N ) { |
371 | setuid( CU.Uid ); | 435 | InterfaceInfo * Run; |
372 | setgid( CU.Gid ); | 436 | // has PAN connection UP interface ? |
373 | 437 | for( QDictIterator<InterfaceInfo> It(ProbedInterfaces); | |
374 | char ** envp = (char **)alloca( sizeof( char *) * | 438 | It.current(); |
375 | (CU.EnvList.count()+1) ); | 439 | ++It ) { |
376 | 440 | Run = It.current(); | |
377 | for( unsigned int i = 0 ; i < CU.EnvList.count() ; i ++ ) { | 441 | if( N == Run->Name ) { |
378 | *(envp+i) = CU.EnvList[i]; | 442 | // this PAN connection is up |
443 | return Run; | ||
379 | } | 444 | } |
380 | envp[CU.EnvList.count()]=NULL; | 445 | } |
381 | 446 | return 0; | |
382 | execve( Cmd.latin1(), argv, envp ); | ||
383 | |||
384 | // if we come here, the exec was not successfull | ||
385 | Log(("Could not exec : %d\n", errno )); | ||
386 | } | 447 | } |
387 | 448 | ||
388 | #include <stdarg.h> | 449 | #include <stdarg.h> |
389 | static FILE * logf = 0; | 450 | static FILE * logf = 0; |
390 | 451 | ||
391 | void VLog( char * Format, ... ) { | 452 | void VLog( char * Format, ... ) { |
392 | va_list l; | 453 | va_list l; |
393 | 454 | ||
394 | va_start(l, Format ); | 455 | va_start(l, Format ); |
395 | 456 | ||
396 | if( logf == (FILE *)0 ) { | 457 | if( logf == (FILE *)0 ) { |
397 | if( getenv("NS2STDERR") ) { | 458 | QString S = getenv("NS2LOG"); |
459 | if( S == "stderr" ) { | ||
398 | logf = stderr; | 460 | logf = stderr; |
399 | } else { | 461 | } else if( S.isEmpty() ) { |
400 | logf = fopen( "/tmp/ns2log", "a" ); | 462 | logf = fopen( "/tmp/ns2log", "a" ); |
463 | } else { | ||
464 | logf = fopen( S, "a" ); | ||
401 | } | 465 | } |
466 | |||
402 | if( ! logf ) { | 467 | if( ! logf ) { |
403 | fprintf( stderr, "Cannot open logfile /tmp/ns2log %d\n", | 468 | fprintf( stderr, "Cannot open logfile %s : %d\n", |
404 | errno ); | 469 | S.latin1(), errno ); |
405 | logf = (FILE *)1; | 470 | logf = (FILE *)1; |
406 | } else { | 471 | } else { |
407 | fprintf( logf, "____ OPEN LOGFILE ____\n"); | 472 | fprintf( logf, "____ OPEN LOGFILE ____\n"); |
408 | } | 473 | } |
409 | } | 474 | } |
410 | 475 | ||
411 | if( (long)logf > 1 ) { | 476 | if( (unsigned long)logf > 1 ) { |
412 | vfprintf( logf, Format, l ); | 477 | vfprintf( logf, Format, l ); |
413 | } | 478 | } |
414 | va_end( l ); | 479 | va_end( l ); |
480 | fflush( logf ); | ||
415 | 481 | ||
416 | } | 482 | } |
417 | 483 | ||
418 | void LogClose( void ) { | 484 | void LogClose( void ) { |
419 | if( (long)logf > 1 ) { | 485 | if( (long)logf > 1 ) { |
420 | fprintf( logf, "____ CLOSE LOGFILE ____\n"); | 486 | fprintf( logf, "____ CLOSE LOGFILE ____\n"); |
@@ -423,11 +489,85 @@ void LogClose( void ) { | |||
423 | } | 489 | } |
424 | logf = 0; | 490 | logf = 0; |
425 | } | 491 | } |
426 | } | 492 | } |
427 | 493 | ||
428 | QString removeSpaces( const QString & X ) { | 494 | QString removeSpaces( const QString & X ) { |
429 | QStringList SL; | 495 | QString Y; |
496 | Y = X.simplifyWhiteSpace(); | ||
497 | Y.replace( QRegExp(" "), "_" ); | ||
498 | owarn << X << " **" << Y << "**" << oendl; | ||
499 | return Y; | ||
500 | } | ||
501 | |||
502 | // | ||
503 | // | ||
504 | // | ||
505 | // | ||
506 | // | ||
507 | |||
508 | MyProcess::MyProcess() : QObject(), StdoutBuffer(), StderrBuffer() { | ||
509 | P = new OProcess(); | ||
510 | connect( P, | ||
511 | SIGNAL( receivedStdout(Opie::Core::OProcess*, char*, int ) ), | ||
512 | this, | ||
513 | SLOT( SLOT_Stdout(Opie::Core::OProcess*,char*,int) ) ); | ||
514 | |||
515 | connect( P, | ||
516 | SIGNAL( receivedStderr(Opie::Core::OProcess*, char*, int ) ), | ||
517 | this, | ||
518 | SLOT( SLOT_Stderr(Opie::Core::OProcess*,char*,int) ) ); | ||
519 | connect( P, | ||
520 | SIGNAL( processExited(Opie::Core::OProcess*) ), | ||
521 | this, | ||
522 | SLOT( SLOT_ProcessExited(Opie::Core::OProcess*) ) ); | ||
523 | } | ||
524 | |||
525 | MyProcess::~MyProcess() { | ||
526 | delete P; | ||
527 | } | ||
528 | |||
529 | void MyProcess::SLOT_Stdout( Opie::Core::OProcess * , char * Buf, int len ) { | ||
530 | char * LB = (char *)alloca( len + 1 ); | ||
531 | memcpy( LB, Buf, len ); | ||
532 | LB[len] = '\0'; | ||
533 | |||
534 | // now input is zero terminated | ||
535 | StdoutBuffer += LB; | ||
536 | |||
537 | owarn << "Received " << len << " bytes on stdout" << oendl; | ||
538 | // see if we have some lines (allow empty lines) | ||
539 | QStringList SL = QStringList::split( "\n", StdoutBuffer, TRUE ); | ||
540 | |||
541 | for( unsigned int i = 0; i < SL.count()-1; i ++ ) { | ||
542 | Log(( "Stdout : \"%s\"\n", SL[i].latin1() ) ); | ||
543 | emit stdoutLine( SL[i] ); | ||
544 | } | ||
545 | |||
546 | // last line is rest | ||
547 | StdoutBuffer = SL[ SL.count()-1 ]; | ||
548 | } | ||
549 | |||
550 | void MyProcess::SLOT_Stderr( Opie::Core::OProcess * , char * Buf, int len ) { | ||
551 | char * LB = (char *)alloca( len + 1 ); | ||
552 | memcpy( LB, Buf, len ); | ||
553 | LB[len] = '\0'; | ||
554 | |||
555 | // now input is zero terminated | ||
556 | StderrBuffer += LB; | ||
557 | |||
558 | owarn << "Received " << len << " bytes on stderr" << oendl; | ||
559 | // see if we have some lines (allow empty lines) | ||
560 | QStringList SL = QStringList::split( "\n", StderrBuffer, TRUE ); | ||
561 | |||
562 | for( unsigned int i = 0; i < SL.count()-1; i ++ ) { | ||
563 | Log(( "Stderr : \"%s\"\n", SL[i].latin1() ) ); | ||
564 | emit stderrLine( SL[i] ); | ||
565 | } | ||
566 | |||
567 | // last line is rest | ||
568 | StderrBuffer = SL[ SL.count()-1 ]; | ||
569 | } | ||
430 | 570 | ||
431 | SL = QStringList::split( " ", X ); | 571 | void MyProcess::SLOT_ProcessExited( Opie::Core::OProcess * ) { |
432 | return SL.join( "_" ); | 572 | emit processExited( this ); |
433 | } | 573 | } |