Diffstat (limited to 'noncore/settings/networksettings2/networksettings2/system.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/settings/networksettings2/networksettings2/system.cpp | 298 |
1 files changed, 219 insertions, 79 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 | |||
@@ -15,2 +15,4 @@ | |||
15 | 15 | ||
16 | #include <opie2/oprocess.h> | ||
17 | |||
16 | #include <qdir.h> | 18 | #include <qdir.h> |
@@ -52,8 +54,6 @@ System::~System( void ) { | |||
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 |
@@ -63,48 +63,105 @@ int System::runAsRoot( const QString & S ) { | |||
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 | 68 | owarn << "TESTMODE !!! execute " | |
69 | emit lineFromCommand( tr("Command : ") + MyS ); | 69 | << S.join( " ") |
70 | emit lineFromCommand( "---------------" ); | 70 | << oendl; |
71 | Log(( "Command : %s\n", MyS.latin1() ) ); | 71 | } else { |
72 | MyS += " 2>&1 "; | 72 | MyProcess * P = new MyProcess(); |
73 | OutputOfCmd = popen( MyS.latin1(), "r" ) ; | 73 | emit processEvent( tr("Command : ") + S.join( " " ) ); |
74 | if( ! OutputOfCmd ) { | 74 | |
75 | // cannot fork | 75 | P->process() << S; |
76 | return 1; | 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*) ) ); | ||
91 | |||
92 | Log(("Executing %s\n", S.join( " " ).latin1() )); | ||
93 | |||
94 | if( ! P->process().start( OProcess::DontCare, | ||
95 | OProcess::AllOutput ) ) { | ||
96 | owarn << "Error starting " << S << oendl; | ||
97 | delete P; | ||
98 | // error starting app | ||
99 | return 1; | ||
100 | } | ||
101 | owarn << "Started " << S << oendl; | ||
77 | } | 102 | } |
78 | 103 | ||
79 | // read all data | 104 | // all is fine |
80 | QString Line = ""; | 105 | return 0; |
81 | while( 1 ) { | 106 | } |
82 | if( fread( &ch, 1, 1, OutputOfCmd ) < 1 ) | 107 | |
83 | // eof | 108 | int System::execAsUser( QStringList & SL ) { |
84 | break; | 109 | MyProcess * P = new MyProcess(); |
85 | if( ch == '\n' || ch == '\r' ) { | 110 | CurrentQPEUser CU = NSResources->currentUser(); |
86 | if( ! Line.isEmpty() ) { | 111 | char * usr = getenv("USER"); |
87 | Log(( "read cmd output : **%s**\n", Line.latin1() ) ); | 112 | |
88 | emit lineFromCommand( Line ); | 113 | if( strcmp( usr, "root" ) == 0 ) { |
89 | Line = ""; | 114 | // find user running qpe |
90 | qApp->processEvents(); | 115 | if( CU.UserName.isEmpty() ) { |
116 | // if we come here, the exec was not successfull | ||
117 | Log(("User not known \n" )); | ||
118 | return 0; | ||
91 | } | 119 | } |
92 | } else { | ||
93 | Line += ch; | ||
94 | } | 120 | } |
95 | } | ||
96 | 121 | ||
97 | if( ! Line.isEmpty() ) { | 122 | // now we are ready to exec the requested command |
98 | emit lineFromCommand( Line ); | 123 | setuid( CU.Uid ); |
99 | Log(( "read cmd output : **%s**\n", Line.latin1() ) ); | 124 | setgid( CU.Gid ); |
100 | } | ||
101 | Log(( "End of command\n", Line.latin1() ) ); | ||
102 | 125 | ||
103 | if( pclose( OutputOfCmd ) < 0 ) { | 126 | for( unsigned int i = 0 ; i < CU.EnvList.count() ; i ++ ) { |
104 | // error in command | 127 | QString X; |
105 | return 3; | 128 | QStringList SL; |
106 | } | 129 | X = CU.EnvList[i]; |
130 | SL = QStringList::split( "=", X ); | ||
131 | P->process().setEnvironment( SL[0], SL[1] ); | ||
132 | } | ||
107 | 133 | ||
108 | // all is fine | 134 | P->process() << SL; |
109 | return 0; | 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 )); | ||
149 | } | ||
150 | |||
151 | return rv; | ||
152 | } | ||
153 | |||
154 | void System::SLOT_ProcessExited( MyProcess * P ) { | ||
155 | QString R; | ||
156 | |||
157 | for( QValueListConstIterator<QCString> it = P->process().args().begin(); | ||
158 | it != P->process().args().end(); | ||
159 | ++it ) { | ||
160 | R += (*it); | ||
161 | R += " "; | ||
162 | } | ||
163 | |||
164 | R += "Returned with " + QString().setNum( P->process().exitStatus() ); | ||
165 | emit processEvent( R ); | ||
166 | delete P; | ||
110 | } | 167 | } |
@@ -200,4 +257,10 @@ void System::probeInterfaces( void ) { | |||
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 | ||
@@ -207,4 +270,12 @@ void System::probeInterfaces( void ) { | |||
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; |
@@ -231,6 +302,6 @@ void System::probeInterfaces( void ) { | |||
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 ); |
@@ -258,3 +329,3 @@ void System::probeInterfaces( void ) { | |||
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 )); |
@@ -326,3 +397,3 @@ void System::probeInterfaces( void ) { | |||
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 | ||
@@ -356,31 +427,21 @@ void System::probeInterfaces( void ) { | |||
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 | |||
364 | if( CU.UserName.isEmpty() ) { | ||
365 | // if we come here, the exec was not successfull | ||
366 | Log(("User not known \n" )); | ||
367 | return; | ||
368 | } | ||
369 | 430 | ||
370 | // now we are ready to exec the requested command | 431 | ::close( sockfd ); |
371 | setuid( CU.Uid ); | 432 | } |
372 | setgid( CU.Gid ); | ||
373 | |||
374 | char ** envp = (char **)alloca( sizeof( char *) * | ||
375 | (CU.EnvList.count()+1) ); | ||
376 | 433 | ||
377 | for( unsigned int i = 0 ; i < CU.EnvList.count() ; i ++ ) { | 434 | InterfaceInfo * System::findInterface( const QString & N ) { |
378 | *(envp+i) = CU.EnvList[i]; | 435 | InterfaceInfo * Run; |
436 | // has PAN connection UP interface ? | ||
437 | for( QDictIterator<InterfaceInfo> It(ProbedInterfaces); | ||
438 | It.current(); | ||
439 | ++It ) { | ||
440 | Run = It.current(); | ||
441 | if( N == Run->Name ) { | ||
442 | // this PAN connection is up | ||
443 | return Run; | ||
444 | } | ||
379 | } | 445 | } |
380 | envp[CU.EnvList.count()]=NULL; | 446 | return 0; |
381 | |||
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 | } |
@@ -396,10 +457,14 @@ void VLog( char * Format, ... ) { | |||
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; |
@@ -410,3 +475,3 @@ void VLog( char * Format, ... ) { | |||
410 | 475 | ||
411 | if( (long)logf > 1 ) { | 476 | if( (unsigned long)logf > 1 ) { |
412 | vfprintf( logf, Format, l ); | 477 | vfprintf( logf, Format, l ); |
@@ -414,2 +479,3 @@ void VLog( char * Format, ... ) { | |||
414 | va_end( l ); | 479 | va_end( l ); |
480 | fflush( logf ); | ||
415 | 481 | ||
@@ -428,6 +494,80 @@ void LogClose( void ) { | |||
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 | } |