summaryrefslogtreecommitdiff
path: root/noncore/settings/networksettings2/networksettings2/system.cpp
Unidiff
Diffstat (limited to 'noncore/settings/networksettings2/networksettings2/system.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/settings/networksettings2/networksettings2/system.cpp286
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
48System::~System( void ) { 50System::~System( void ) {
49 if( ProcDevNet ) 51 if( ProcDevNet )
50 delete ProcDevNet; 52 delete ProcDevNet;
51} 53}
52 54
53int System::runAsRoot( const QString & S ) { 55int 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; 108int 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 ) { 154void 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
112void System::refreshStatistics( InterfaceInfo & I ) { 169void 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
361void 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 434InterfaceInfo * 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>
389static FILE * logf = 0; 450static FILE * logf = 0;
390 451
391void VLog( char * Format, ... ) { 452void 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
418void LogClose( void ) { 484void 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
428QString removeSpaces( const QString & X ) { 494QString 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
508MyProcess::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
525MyProcess::~MyProcess() {
526 delete P;
527}
528
529void 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
550void 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 ); 571void MyProcess::SLOT_ProcessExited( Opie::Core::OProcess * ) {
432 return SL.join( "_" ); 572 emit processExited( this );
433} 573}