Diffstat (limited to 'noncore/settings/networksettings2/networksettings2') (more/less context) (show whitespace changes)
11 files changed, 764 insertions, 213 deletions
diff --git a/noncore/settings/networksettings2/networksettings2/GUIUtils.h b/noncore/settings/networksettings2/networksettings2/GUIUtils.h index 23290a9..baf6f0c 100644 --- a/noncore/settings/networksettings2/networksettings2/GUIUtils.h +++ b/noncore/settings/networksettings2/networksettings2/GUIUtils.h @@ -33,2 +33,11 @@ +#define STXT(a, b) \ + b->setText( a ); + +#define SCB(a, b) \ + b->setChecked( a ); + +#define SSB( Data,Wdg) \ + Wdg->setValue( Data ) + extern bool validIP( const QString & S ); diff --git a/noncore/settings/networksettings2/networksettings2/Utils.h b/noncore/settings/networksettings2/networksettings2/Utils.h index 739476e..301aac1 100644 --- a/noncore/settings/networksettings2/networksettings2/Utils.h +++ b/noncore/settings/networksettings2/networksettings2/Utils.h @@ -3,2 +3,4 @@ +#include <opie2/odebug.h> + #define Log(x) VLog x diff --git a/noncore/settings/networksettings2/networksettings2/netnode.cpp b/noncore/settings/networksettings2/networksettings2/netnode.cpp index 110786a..17653bd 100644 --- a/noncore/settings/networksettings2/networksettings2/netnode.cpp +++ b/noncore/settings/networksettings2/networksettings2/netnode.cpp @@ -4,3 +4,2 @@ - #include <qpainter.h> @@ -13,6 +12,20 @@ -#include "asdevice.h" -#include "asline.h" -#include "asconnection.h" -#include "asfullsetup.h" +static char * ActionName[] = { + "Disable", + "Enable", + "Activate", + "Deactivate", + "Up", + "Down" +}; + +static char * StateName[] = { + "Unchecked", + "Unknown", + "Unavailable", + "Disabled", + "Off", + "Available", + "IsUp" +}; @@ -67,2 +80,17 @@ void ANetNode::setAttribute( QString & Attr, QString & Value ){ +bool ANetNode::isToplevel( void ) { + const char ** P = provides(); + while( *P ) { + if( strcmp( *P, "fullsetup") == 0 ) + return 1; + P ++; + } + return 0; +} + +bool ANetNode::openFile( SystemFile & SF, + ANetNodeInstance * NNI ) { + return (NNI ) ? NNI->openFile( SF ) : 0 ; +} + // @@ -86,3 +114,3 @@ void ANetNodeInstance::initialize( void ) { void ANetNodeInstance::setAttribute( QString & Attr, QString & Value ){ - if( Attr == "name" ) { + if( Attr == "__name" ) { setName( Value.latin1() ); @@ -94,3 +122,3 @@ void ANetNodeInstance::setAttribute( QString & Attr, QString & Value ){ void ANetNodeInstance::saveAttributes( QTextStream & TS ) { - TS << "name=" << name() << endl; + TS << "__name=" << name() << endl; saveSpecificAttribute( TS ); @@ -114,2 +142,3 @@ NodeCollection::NodeCollection( void ) : QList<ANetNodeInstance>() { CurrentState = Unchecked; + AssignedInterface = 0; } @@ -125,2 +154,3 @@ NodeCollection::NodeCollection( QTextStream & TS ) : IsNew = 0; + AssignedInterface = 0; CurrentState = Unchecked; @@ -149,3 +179,2 @@ NodeCollection::NodeCollection( QTextStream & TS ) : } else if( A == "number" ) { - Log(( "Profile number %s\n", N.latin1() )); setNumber( N.toLong() ); @@ -161,2 +190,5 @@ NodeCollection::NodeCollection( QTextStream & TS ) : } while( 1 ); + + Log(( "Profile number %s : %d nodes\n", + N.latin1(), count() )); } @@ -169,3 +201,3 @@ const QString & NodeCollection::description( void ) { ANetNodeInstance * NNI = getToplevel(); - return (NNI) ? NNI->runtime()->asFullSetup()->description() : Name; + return (NNI) ? NNI->runtime()->description() : Name; } @@ -256,3 +288,4 @@ QPixmap NodeCollection::devicePixmap( void ) { - QPixmap Mini = NSResources->getPixmap( device()->netNode()->pixmapName() ); + QPixmap Mini = NSResources->getPixmap( + device()->netNode()->pixmapName() ); @@ -282,3 +315,3 @@ QString NodeCollection::stateName( State_t S) { case Off : - return qApp->translate( "networksettings2", "Off"); + return qApp->translate( "networksettings2", "Inactive"); case Available : @@ -286,3 +319,3 @@ QString NodeCollection::stateName( State_t S) { case IsUp : - return qApp->translate( "networksettings2", "IsUp"); + return qApp->translate( "networksettings2", "Up"); case Unchecked : /* FT */ @@ -302,7 +335,7 @@ void NodeCollection::reassign( void ) { -bool NodeCollection::triggersVPN() { - return getToplevel()->runtime()->asFullSetup()->triggersVPN(); +const QStringList & NodeCollection::triggers() { + return getToplevel()->runtime()->triggers(); } -bool NodeCollection::hasDataForFile( const QString & S ) { +bool NodeCollection::hasDataForFile( SystemFile & S ) { return ( firstWithDataForFile( S ) != 0 ); @@ -310,3 +343,3 @@ bool NodeCollection::hasDataForFile( const QString & S ) { -ANetNodeInstance * NodeCollection::firstWithDataForFile( const QString & S ) { +ANetNodeInstance * NodeCollection::firstWithDataForFile( SystemFile & S ) { for( QListIterator<ANetNodeInstance> it(*this); @@ -315,5 +348,2 @@ ANetNodeInstance * NodeCollection::firstWithDataForFile( const QString & S ) { if( it.current()->hasDataForFile( S ) ) { - Log(( "Node %s has data for %s\n", - it.current()->nodeClass()->name(), - S.latin1() )); return it.current(); @@ -324,5 +354,137 @@ ANetNodeInstance * NodeCollection::firstWithDataForFile( const QString & S ) { +State_t NodeCollection::state( bool Update ) { + State_t NodeState; + + if( CurrentState == Unchecked || Update ) { + // collect states of all nodes until with get the 'higest' + // state possible + + Log(( "Connection %s state %s\n", + Name.latin1(), StateName[CurrentState] )); + + CurrentState = Unknown; + for( QListIterator<ANetNodeInstance> it(*this); + it.current(); + ++it ) { + Log(( "-> Detect %s\n", it.current()->name() )); + NodeState = it.current()->runtime()->detectState(); + Log(( " state %s\n", StateName[NodeState] )); + + if( NodeState == Disabled || + NodeState == IsUp ) { + // max + CurrentState = NodeState; + break; + } + + if( NodeState > CurrentState ) { + // higher + CurrentState = NodeState; + } + } + } + + return CurrentState; +} + +QString NodeCollection::setState( Action_t A, bool Force ) { + + QString msg; + Action_t Actions[10]; + int NoOfActions = 0; + + // get current state + state( Force ); + + switch( A ) { + case Disable : + if( CurrentState < Disabled ) { + // disabled + CurrentState = Disabled; + return QString(); + } + + if( CurrentState == IsUp ) { + Actions[NoOfActions++] = Down; + Actions[NoOfActions++] = Deactivate; + } else if( CurrentState == Available ) { + Actions[NoOfActions++] = Deactivate; + } + Actions[NoOfActions++] = Disable; + break; + case Enable : + // always possible -> detected state is new state + Actions[NoOfActions++] = Enable; + break; + case Activate : + if( ! Force ) { + if( CurrentState >= Available ) { + // already available + return QString(); + } + + if( CurrentState != Off ) { + return qApp->translate( "System", + "State should be off" ); + } + } + + Actions[NoOfActions++] = Activate; + break; + case Deactivate : + if( ! Force ) { + if( CurrentState < Off ) { + // already inactive + return QString(); + } + } + + if( CurrentState == IsUp ) { + Actions[NoOfActions++] = Down; + } + Actions[NoOfActions++] = Deactivate; + break; + case Up : + if( ! Force ) { + if( CurrentState == IsUp ) { + return QString(); + } + if( CurrentState < Off ) { + return qApp->translate( "System", + "State should at least be off" ); + } + } + if( CurrentState == Off ) { + Actions[NoOfActions++] = Activate; + } + Actions[NoOfActions++] = Up; + break; + case Down : + if( ! Force ) { + if( CurrentState < Available ) { + // OK + return QString(); + } + } + Actions[NoOfActions++] = Down; + break; + } + + // send actions to all nodes + Log(( "Action %s requires %d steps\n", + ActionName[A], NoOfActions )); + + for( int i = 0 ; i < NoOfActions; i ++ ) { + // setState recurses through the tree depth first + msg = getToplevel()->runtime()->setState( this, Actions[i], Force ); + if( ! msg.isEmpty() ) { + return msg; + } + } + return QString(); +} + // // -// RUNTIMEINFO +// RuntimeInfo // @@ -330,8 +492,20 @@ ANetNodeInstance * NodeCollection::firstWithDataForFile( const QString & S ) { -InterfaceInfo * RuntimeInfo::assignedInterface( void ) { - return netNode()->nextNode()->runtime()->assignedInterface(); +QString RuntimeInfo::setState( NodeCollection * NC, + Action_t A, + bool Force ) { + QString M; + RuntimeInfo * Deeper = nextNode(); + + if( Deeper ) { + // first go deeper + M = Deeper->setState( NC, A, Force ); + if( ! M.isEmpty() ) + return M; } -AsDevice * RuntimeInfo::device( void ) { - return netNode()->nextNode()->runtime()->device(); + // set my own state + Log (( "-> Act upon %s\n", netNode()->name() )); + M = setMyState( NC, A, Force ); + Log (( " result %s\n", M.latin1() )); + return M; } diff --git a/noncore/settings/networksettings2/networksettings2/netnode.h b/noncore/settings/networksettings2/networksettings2/netnode.h index d3d7b34..4626381 100644 --- a/noncore/settings/networksettings2/networksettings2/netnode.h +++ b/noncore/settings/networksettings2/networksettings2/netnode.h @@ -12,2 +12,3 @@ #include <Utils.h> +#include <system.h> @@ -28,2 +29,3 @@ class RuntimeInfo; class InterfaceInfo; +class NSResources; @@ -57,13 +59,13 @@ typedef enum State { typedef enum Action { - // to make the device unavailable functionally + // to make the device unavailable functionally -> to disabled Disable = 0, - // to make the device available functionally + // to make the device available functionally -> to off Enable = 1, - // bring the hardware up + // bring the hardware up -> to Available Activate = 2, - // bring the hardware down + // bring the hardware down -> to off Deactivate = 3, - // bring the connection up + // bring the connection up -> to IsUp Up = 4, - // bring the connection down + // bring the connection down -> to Available Down = 5 @@ -92,4 +94,3 @@ public: // does this Node provide a Connection - inline bool isToplevel( void ) - { return strcmp( provides(), "fullsetup") == 0 ; } + bool isToplevel( void ); @@ -112,18 +113,30 @@ public: // do instances of this noce class have data for this file - virtual bool hasDataForFile( const QString & ) + virtual bool hasDataForFile( SystemFile & ) { return 0; } + // open proper file SF identified by S + // this method is called by NS2. + // + // overrule this ONLY if this proper file is a common file + // for all NNI of this node class and the data generated + // by each of the NNI needs to be put in one file + // + // if this is the case the file should be (re)opened in append + // return 0 if file cannot be opened + virtual bool openFile( SystemFile &SF, + ANetNodeInstance * NNI ); + // generate instance independent stuff // 0 : data output, 1 no data, 2 error - virtual short generateFile( const QString & , - const QString & , - QTextStream & , - long ) + virtual short generatePreamble( SystemFile & ) + { return 1; } + + // generate instance independent stuff + // 0 : data output, 1 no data, 2 error + virtual short generatePostamble( SystemFile & ) { return 1; } - // generate instance dependent but profile common stuff + // generate instance dependent but instance common stuff // 0 : data output, 1 no data, 2 error - virtual short generateFile( const QString & , - const QString & , - QTextStream & , + virtual short generateFile( SystemFile &, ANetNodeInstance * , @@ -132,3 +145,2 @@ public: - // generate NIC name based on instance nr @@ -143,5 +155,6 @@ public: - // return list of files that are specific for this node class - virtual QStringList * properFiles( void ) - { return 0; } + // return ID list for each file generated specially for + // this node type + virtual QStringList properFiles( void ) + { return QStringList(); } @@ -162,4 +175,6 @@ public: - // return feature this NetNode provides - virtual const char * provides( void ) = 0; + // return features this NetNode provides + virtual const char ** provides( void ) = 0; + + // return features this NetNode needs virtual const char ** needs( void ) = 0; @@ -226,3 +241,3 @@ public: - inline const char * provides( void ) + inline const char ** provides( void ) { return NodeType->provides(); } @@ -246,3 +261,3 @@ public: // open proper file identified by S - virtual QFile * openFile( const QString & ) + virtual bool openFile( SystemFile & ) { return 0; } @@ -250,3 +265,3 @@ public: // check if this node (or sub nodes) have data for this file - virtual bool hasDataForFile( const QString & S ) + virtual bool hasDataForFile( SystemFile & S ) { return nodeClass()->hasDataForFile( S ); } @@ -256,8 +271,6 @@ public: // this is called within the code of the parent - virtual short generateFileEmbedded( const QString & ID, - const QString & Path, - QTextStream & TS, + virtual short generateFileEmbedded( SystemFile & SF, long DevNr ) { ANetNodeInstance * NNI = nextNode(); - return (NNI) ? NNI->generateFileEmbedded( ID, Path, TS, DevNr ) : 1; + return (NNI) ? NNI->generateFileEmbedded( SF, DevNr ) : 1; } @@ -266,8 +279,6 @@ public: // (or find the first node that does) - virtual short generateFile( const QString & ID, - const QString & Path, - QTextStream & TS, + virtual short generateFile( SystemFile & SF, long DevNr ) { ANetNodeInstance * NNI = nextNode(); - return (NNI) ? NNI->generateFile( ID, Path, TS, DevNr ) : 1; + return (NNI) ? NNI->generateFile( SF, DevNr ) : 1; } @@ -325,11 +336,16 @@ public : - // downcast implemented by specify runtime classes - virtual AsDevice * asDevice( void ) - { return 0; } - virtual AsConnection * asConnection( void ) - { return 0; } - virtual AsLine * asLine( void ) - { return 0; } - virtual AsFullSetup * asFullSetup( void ) - { return 0; } + // + // + // methods to be overloaded by connection capable + // runtimes + // + // + + + // + // + // methods to be overloaded by device capable + // runtimes + // + // @@ -337,17 +353,97 @@ public : // recurse deeper if this node cannot answer that question - virtual bool handlesInterface( const QString & ) - { return 0; } - virtual bool handlesInterface( const InterfaceInfo & ) - { return 0; } - virtual InterfaceInfo * assignedInterface( void ); - virtual AsDevice * device( void ); + virtual bool handlesInterface( const QString & S ) { + RuntimeInfo * RI = device(); + if( RI ) { + return RI->handlesInterface( S ); + } + return 0; + } + bool handlesInterface( const InterfaceInfo & I ) { + RuntimeInfo * RI = device(); + if( RI ) { + return RI->handlesInterface( I ); + } + return 0; + } - ANetNodeInstance * netNode() + // + // + // methods to be overloaded by full setup capable + // runtimes + // + // + + // return description for this full setup + virtual const QString & description( void ) { + return fullSetup()->description( ); + } + // return triggers that should fire when this + // setup is brought up + virtual const QStringList & triggers( void ) { + return fullSetup()->triggers( ); + } + + // + // + // methods to be overloaded by line capable + // runtimes + // + // + + // return the device file ('/dev/xxx') created + // by this line capable runtime + virtual QString deviceFile( void ) { + RuntimeInfo * RI = line(); + if( RI ) { + return RI->deviceFile(); + } + return QString(); + } + + // + // + // runtime interface + // + // + + // return the node that offers device capability + virtual RuntimeInfo * device( void ) + { RuntimeInfo * RI = nextNode(); + return (RI) ? RI->device() : 0; + } + + // return the node that offers connection capability + virtual RuntimeInfo * connection( void ) + { RuntimeInfo * RI = nextNode(); + return (RI) ? RI->connection() : 0; + } + + // return the node that offers line capability + virtual RuntimeInfo * line( void ) + { RuntimeInfo * RI = nextNode(); + return (RI) ? RI->line() : 0; + } + + // return the node that offers full setup capability + virtual RuntimeInfo * fullSetup( void ) + { RuntimeInfo * RI = nextNode(); + return (RI) ? RI->fullSetup() : 0; + } + + inline ANetNodeInstance * netNode() { return NNI; } - NodeCollection * connection() + + inline NodeCollection * nodeCollection() { return NNI->connection(); } - virtual void detectState( NodeCollection * NC ) = 0; - virtual bool setState( NodeCollection * NC, Action_t A, bool Force = 0 ) = 0; - virtual bool canSetState( State_t Curr, Action_t A ) = 0; + virtual State_t detectState( void ) = 0; + // public API to set the state + virtual QString setState( NodeCollection * NC, + Action_t A, + bool Force = 0 ); + + inline RuntimeInfo * nextNode( void ) { + ANetNodeInstance * NNI = netNode()->nextNode(); + return (NNI) ? NNI->runtime() : 0; + } @@ -360,2 +456,7 @@ protected : + // set state of this node (private API) + virtual QString setMyState( NodeCollection * NC, + Action_t A, + bool Force = 0 ) = 0; + // connection this runtime info belongs to @@ -394,25 +495,29 @@ public : + // return the interface in the OS that is assigned to + // this device inline InterfaceInfo * assignedInterface( void ) { - return getToplevel()->runtime()->assignedInterface(); + return AssignedInterface; } - inline AsDevice * device() { - return getToplevel()->runtime()->device(); + // assign the interface to this device + inline void assignInterface( InterfaceInfo * NI ) { + if( NI == 0 ) { + if( AssignedInterface ) { + AssignedInterface->assignConnection( 0 ); } - - bool triggersVPN(); - - inline State_t state( bool Update = 0 ) - { Log(( "%s state %d(=%d?)\n", Name.latin1(), CurrentState, - Unchecked )); - if( CurrentState == Unchecked || Update ) { - Log(( "TL %p TLR %p\n", - getToplevel(), - getToplevel()->runtime() )); - // need to get current state - getToplevel()->runtime()->detectState( this ); } - return CurrentState; + AssignedInterface = NI; + if( AssignedInterface ) { + AssignedInterface->assignConnection( this ); + } } + inline RuntimeInfo * device() { + return getToplevel()->runtime()->device(); + } + + const QStringList & triggers(); + + State_t state( bool Update = 0 ); + // get the ixmap for this device @@ -426,6 +531,3 @@ public : - inline bool setState( Action_t A, bool Force =0 ) - { return getToplevel()->runtime()->setState( this, A, Force ); } - inline bool canSetState( Action_t A ) - { return getToplevel()->runtime()->canSetState( CurrentState, A ); } + QString setState( Action_t A, bool Force = 0 ); @@ -458,12 +560,10 @@ public : // file identified by S - bool hasDataForFile( const QString & S ); - ANetNodeInstance * firstWithDataForFile( const QString & S ); + bool hasDataForFile( SystemFile & S ); + ANetNodeInstance * firstWithDataForFile( SystemFile & ); // generate items for this file -> toplevel call - short generateFile( const QString & FID, // identification of file - const QString & FName, // effective filename of file - QTextStream & TS, // stream to file + short generateFile( SystemFile & SF, long DN // device number ) - { return getToplevel()->generateFile( FID, FName, TS, DN ); } + { return getToplevel()->generateFile( SF, DN ); } @@ -491,2 +591,4 @@ private : + InterfaceInfo * AssignedInterface; + }; diff --git a/noncore/settings/networksettings2/networksettings2/networksettings2.pro b/noncore/settings/networksettings2/networksettings2/networksettings2.pro index d1e42b7..f2ba9df 100644 --- a/noncore/settings/networksettings2/networksettings2/networksettings2.pro +++ b/noncore/settings/networksettings2/networksettings2/networksettings2.pro @@ -7,9 +7,5 @@ HEADERS = netnode.h \ system.h \ - asline.h \ GUIUtils.h \ - asconnection.h \ - asfullsetup.h \ systemfile.h \ - wextensions.h \ - asdevice.h + wextensions.h SOURCES = netnode.cpp \ diff --git a/noncore/settings/networksettings2/networksettings2/resources.cpp b/noncore/settings/networksettings2/networksettings2/resources.cpp index 2f17693..8b3b4fe 100644 --- a/noncore/settings/networksettings2/networksettings2/resources.cpp +++ b/noncore/settings/networksettings2/networksettings2/resources.cpp @@ -47,6 +47,10 @@ TheNSResources::TheNSResources( void ) : NodeTypeNameMap(), - const char * Provides = InnerIt.current()->NetNode->provides(); + const char ** Provides = InnerIt.current()->NetNode->provides(); NeedsRun = OuterIt.current()->NetNode->needs(); + for( ; *NeedsRun; NeedsRun ++ ) { - if( strcmp( Provides, *NeedsRun ) == 0 ) { + const char ** PRun; + PRun = Provides; + for( ; *PRun; PRun ++ ) { + if( strcmp( *PRun, *NeedsRun ) == 0 ) { // inner provides what outer needs @@ -59,2 +63,3 @@ TheNSResources::TheNSResources( void ) : NodeTypeNameMap(), } + } OuterIt.current()->NetNode->setAlternatives( NNLP ); @@ -63,19 +68,13 @@ TheNSResources::TheNSResources( void ) : NodeTypeNameMap(), - // define Node types to Description map - NodeTypeNameMap.insert( "device", tr( "Network Device" ) ); - NodeTypeNameMap.insert( "line", tr( "Character device" ) ); - NodeTypeNameMap.insert( "connection", tr( "IP Connection" ) ); - NodeTypeNameMap.insert( "fullsetup", tr( "Connection Profile" ) ); - - NodeTypeDescriptionMap.insert( "device", + // define built in Node types to Description map + addNodeType( "device", tr( "Network Device" ), tr( "<p>Devices that can handle IP packets</p>" ) ); - NodeTypeDescriptionMap.insert( "line", + addNodeType( "line", tr( "Character device" ), tr( "<p>Devices that can handle single bytes</p>" ) ); - NodeTypeDescriptionMap.insert( "connection", + addNodeType( "connection", tr( "IP Connection" ), tr( "<p>Nodes that provide working IP connections</p>" ) ); - NodeTypeDescriptionMap.insert( "fullsetup", + addNodeType( "fullsetup", tr( "Connection Profile" ), tr( "<p>Fully configured connection profile</p>" ) ); - - // define system files - addSystemFile( "interfaces", "/tmp/interfaces", 1 ); + addNodeType( "GPRS", tr( "Connection to GPRS device" ), + tr( "<p>Connection to a GPRS capable device</p>" ) ); @@ -90,2 +89,11 @@ TheNSResources::~TheNSResources( void ) { +void TheNSResources::addNodeType( const QString & ID, + const QString & Name, + const QString & Descr ) { + if( NodeTypeNameMap[ID].isEmpty() ) { + NodeTypeNameMap.insert( ID, Name ); + NodeTypeDescriptionMap.insert( ID, Descr ); + } +} + void TheNSResources::addSystemFile( const QString & ID, @@ -222,4 +230,6 @@ QPixmap TheNSResources::getPixmap( const QString & QS ) { S += QS; - Log(("%s\n", S.latin1() )); P = Resource::loadPixmap( S ); + if( P.isNull() ) { + Log(( "Cannot load %s\n", S.latin1() )); + } return ( P.isNull() ) ? QPixmap() : P; @@ -271,2 +281,12 @@ NodeCollection * TheNSResources::findConnection( const QString & S ) { +NodeCollection * TheNSResources::getConnection( int nr ) { + for( QDictIterator<NodeCollection> it(ConnectionsMap); + it.current(); + ++it ) { + if( it.current()->number() == nr ) { + return it.current(); + } + } + return 0; +} /* diff --git a/noncore/settings/networksettings2/networksettings2/resources.h b/noncore/settings/networksettings2/networksettings2/resources.h index 23b120e..634cd39 100644 --- a/noncore/settings/networksettings2/networksettings2/resources.h +++ b/noncore/settings/networksettings2/networksettings2/resources.h @@ -69,2 +69,7 @@ public : + // define new plugin (=node) + void addNodeType( const QString & ID, + const QString & LongName, + const QString & Description ); + Name2SystemFile_t & systemFiles( void ) @@ -101,2 +106,3 @@ public : NodeCollection * findConnection( const QString & N ); + NodeCollection * getConnection( int nr ); Name2Connection_t & connections( void ) 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 @@ +#include <opie2/oprocess.h> + #include <qdir.h> @@ -52,8 +54,6 @@ System::~System( void ) { -int System::runAsRoot( const QString & S ) { - QString MyS = S; +int System::runAsRoot( QStringList & S ) { char * usr = getenv("USER"); - char ch; - if( S.isEmpty() ) { + if( S.count() == 0 ) { // loophole to start shell @@ -63,48 +63,105 @@ int System::runAsRoot( const QString & S ) { // unknown or non-root user -> use SUDO - MyS.prepend( "sudo " ); + S.prepend( "sudo" ); } - Log(("Executing %s\n", MyS.latin1() )); + if( getenv( "NS2TESTMODE" ) ) { + owarn << "TESTMODE !!! execute " + << S.join( " ") + << oendl; + } else { + MyProcess * P = new MyProcess(); + emit processEvent( tr("Command : ") + S.join( " " ) ); + + P->process() << S; + + connect( P, + SIGNAL( stdoutLine( const QString & ) ), + this, + SIGNAL( stdoutLine( const QString & ) ) ); + + connect( P, + SIGNAL( stderrLine( const QString & ) ), + this, + SIGNAL( stderrLine( const QString & ) ) ); + + connect( P, + SIGNAL(processExited(MyProcess*) ), + this, SLOT + (SLOT_ProcessExited(MyProcess*) ) ); - emit lineFromCommand( tr("Command : ") + MyS ); - emit lineFromCommand( "---------------" ); - Log(( "Command : %s\n", MyS.latin1() ) ); - MyS += " 2>&1 "; - OutputOfCmd = popen( MyS.latin1(), "r" ) ; - if( ! OutputOfCmd ) { - // cannot fork + Log(("Executing %s\n", S.join( " " ).latin1() )); + + if( ! P->process().start( OProcess::DontCare, + OProcess::AllOutput ) ) { + owarn << "Error starting " << S << oendl; + delete P; + // error starting app return 1; } + owarn << "Started " << S << oendl; + } - // read all data - QString Line = ""; - while( 1 ) { - if( fread( &ch, 1, 1, OutputOfCmd ) < 1 ) - // eof - break; - if( ch == '\n' || ch == '\r' ) { - if( ! Line.isEmpty() ) { - Log(( "read cmd output : **%s**\n", Line.latin1() ) ); - emit lineFromCommand( Line ); - Line = ""; - qApp->processEvents(); + // all is fine + return 0; } - } else { - Line += ch; + +int System::execAsUser( QStringList & SL ) { + MyProcess * P = new MyProcess(); + CurrentQPEUser CU = NSResources->currentUser(); + char * usr = getenv("USER"); + + if( strcmp( usr, "root" ) == 0 ) { + // find user running qpe + if( CU.UserName.isEmpty() ) { + // if we come here, the exec was not successfull + Log(("User not known \n" )); + return 0; + } + } + + // now we are ready to exec the requested command + setuid( CU.Uid ); + setgid( CU.Gid ); + + for( unsigned int i = 0 ; i < CU.EnvList.count() ; i ++ ) { + QString X; + QStringList SL; + X = CU.EnvList[i]; + SL = QStringList::split( "=", X ); + P->process().setEnvironment( SL[0], SL[1] ); } + + P->process() << SL; + + emit processEvent( tr("Command : ") + SL.join( " " ) ); + + Log(("Executing as user %s : %s\n", + CU.UserName.latin1(), + SL.join( " " ).latin1() )); + + int rv = ( P->process().start( OProcess::DontCare, + OProcess::NoCommunication ) ); + delete P; + + if( rv ) { + // if we come here, the exec was not successfull + Log(("Could not exec : %d\n", errno )); } - if( ! Line.isEmpty() ) { - emit lineFromCommand( Line ); - Log(( "read cmd output : **%s**\n", Line.latin1() ) ); + return rv; } - Log(( "End of command\n", Line.latin1() ) ); - if( pclose( OutputOfCmd ) < 0 ) { - // error in command - return 3; +void System::SLOT_ProcessExited( MyProcess * P ) { + QString R; + + for( QValueListConstIterator<QCString> it = P->process().args().begin(); + it != P->process().args().end(); + ++it ) { + R += (*it); + R += " "; } - // all is fine - return 0; + R += "Returned with " + QString().setNum( P->process().exitStatus() ); + emit processEvent( R ); + delete P; } @@ -200,4 +257,10 @@ void System::probeInterfaces( void ) { sockfd = socket(PF_INET, SOCK_DGRAM, 0); - if(sockfd == -1) + if(sockfd == -1) { + owarn << "Cannot open INET socket " + << errno + << " " + << strerror( errno ) + << oendl; return; + } @@ -207,4 +270,12 @@ void System::probeInterfaces( void ) { if( ! ProcDevNet->open(IO_ReadOnly) ) { + owarn << "Cannot open " + << PROCNETDEV + << " " + << errno + << " " + << strerror( errno ) + << oendl; delete ProcDevNet; ProcDevNet =0; + ::close( sockfd ); return; @@ -231,6 +302,6 @@ void System::probeInterfaces( void ) { // new nic - Log(("NEWNIC %s\n", NicName.latin1())); + Log(("New NIC found : %s\n", NicName.latin1())); IFI = new InterfaceInfo; IFI->Name = line.left(loc); - IFI->NetNode = 0; + IFI->Collection = 0; ProbedInterfaces.insert( IFI->Name, IFI ); @@ -258,3 +329,3 @@ void System::probeInterfaces( void ) { if( ioctl(sockfd, SIOCGIFHWADDR, &ifrs) >= 0 ) { - Log(("%s = %d\n", IFI->Name.latin1(), + Log(("Family for NIC %s : %d\n", IFI->Name.latin1(), ifrs.ifr_hwaddr.sa_family )); @@ -326,3 +397,3 @@ void System::probeInterfaces( void ) { } else // else already probed before -> just update - Log(("OLDNIC %s\n", NicName.latin1())); + Log(("Redetected NIC %s\n", NicName.latin1())); @@ -356,31 +427,21 @@ void System::probeInterfaces( void ) { } - Log(("NIC %s UP %d\n", NicName.latin1(), IFI->IsUp )); + Log(("NIC %s UP ? %d\n", NicName.latin1(), IFI->IsUp )); } -} - -void System::execAsUser( QString & Cmd, char * argv[] ) { - CurrentQPEUser CU = NSResources->currentUser(); - if( CU.UserName.isEmpty() ) { - // if we come here, the exec was not successfull - Log(("User not known \n" )); - return; + ::close( sockfd ); } - // now we are ready to exec the requested command - setuid( CU.Uid ); - setgid( CU.Gid ); - - char ** envp = (char **)alloca( sizeof( char *) * - (CU.EnvList.count()+1) ); - - for( unsigned int i = 0 ; i < CU.EnvList.count() ; i ++ ) { - *(envp+i) = CU.EnvList[i]; +InterfaceInfo * System::findInterface( const QString & N ) { + InterfaceInfo * Run; + // has PAN connection UP interface ? + for( QDictIterator<InterfaceInfo> It(ProbedInterfaces); + It.current(); + ++It ) { + Run = It.current(); + if( N == Run->Name ) { + // this PAN connection is up + return Run; } - envp[CU.EnvList.count()]=NULL; - - execve( Cmd.latin1(), argv, envp ); - - // if we come here, the exec was not successfull - Log(("Could not exec : %d\n", errno )); + } + return 0; } @@ -396,10 +457,14 @@ void VLog( char * Format, ... ) { if( logf == (FILE *)0 ) { - if( getenv("NS2STDERR") ) { + QString S = getenv("NS2LOG"); + if( S == "stderr" ) { logf = stderr; - } else { + } else if( S.isEmpty() ) { logf = fopen( "/tmp/ns2log", "a" ); + } else { + logf = fopen( S, "a" ); } + if( ! logf ) { - fprintf( stderr, "Cannot open logfile /tmp/ns2log %d\n", - errno ); + fprintf( stderr, "Cannot open logfile %s : %d\n", + S.latin1(), errno ); logf = (FILE *)1; @@ -410,3 +475,3 @@ void VLog( char * Format, ... ) { - if( (long)logf > 1 ) { + if( (unsigned long)logf > 1 ) { vfprintf( logf, Format, l ); @@ -414,2 +479,3 @@ void VLog( char * Format, ... ) { va_end( l ); + fflush( logf ); @@ -428,6 +494,80 @@ void LogClose( void ) { QString removeSpaces( const QString & X ) { - QStringList SL; + QString Y; + Y = X.simplifyWhiteSpace(); + Y.replace( QRegExp(" "), "_" ); + owarn << X << " **" << Y << "**" << oendl; + return Y; +} + +// +// +// +// +// + +MyProcess::MyProcess() : QObject(), StdoutBuffer(), StderrBuffer() { + P = new OProcess(); + connect( P, + SIGNAL( receivedStdout(Opie::Core::OProcess*, char*, int ) ), + this, + SLOT( SLOT_Stdout(Opie::Core::OProcess*,char*,int) ) ); + + connect( P, + SIGNAL( receivedStderr(Opie::Core::OProcess*, char*, int ) ), + this, + SLOT( SLOT_Stderr(Opie::Core::OProcess*,char*,int) ) ); + connect( P, + SIGNAL( processExited(Opie::Core::OProcess*) ), + this, + SLOT( SLOT_ProcessExited(Opie::Core::OProcess*) ) ); +} + +MyProcess::~MyProcess() { + delete P; +} + +void MyProcess::SLOT_Stdout( Opie::Core::OProcess * , char * Buf, int len ) { + char * LB = (char *)alloca( len + 1 ); + memcpy( LB, Buf, len ); + LB[len] = '\0'; + + // now input is zero terminated + StdoutBuffer += LB; + + owarn << "Received " << len << " bytes on stdout" << oendl; + // see if we have some lines (allow empty lines) + QStringList SL = QStringList::split( "\n", StdoutBuffer, TRUE ); + + for( unsigned int i = 0; i < SL.count()-1; i ++ ) { + Log(( "Stdout : \"%s\"\n", SL[i].latin1() ) ); + emit stdoutLine( SL[i] ); + } + + // last line is rest + StdoutBuffer = SL[ SL.count()-1 ]; +} + +void MyProcess::SLOT_Stderr( Opie::Core::OProcess * , char * Buf, int len ) { + char * LB = (char *)alloca( len + 1 ); + memcpy( LB, Buf, len ); + LB[len] = '\0'; + + // now input is zero terminated + StderrBuffer += LB; + + owarn << "Received " << len << " bytes on stderr" << oendl; + // see if we have some lines (allow empty lines) + QStringList SL = QStringList::split( "\n", StderrBuffer, TRUE ); + + for( unsigned int i = 0; i < SL.count()-1; i ++ ) { + Log(( "Stderr : \"%s\"\n", SL[i].latin1() ) ); + emit stderrLine( SL[i] ); + } + + // last line is rest + StderrBuffer = SL[ SL.count()-1 ]; +} - SL = QStringList::split( " ", X ); - return SL.join( "_" ); +void MyProcess::SLOT_ProcessExited( Opie::Core::OProcess * ) { + emit processExited( this ); } diff --git a/noncore/settings/networksettings2/networksettings2/system.h b/noncore/settings/networksettings2/networksettings2/system.h index 33af391..e67d695 100644 --- a/noncore/settings/networksettings2/networksettings2/system.h +++ b/noncore/settings/networksettings2/networksettings2/system.h @@ -3,2 +3,8 @@ +#include <qstring.h> + +#include <opie2/oprocess.h> + +using namespace Opie::Core; + // for hardware types @@ -9,2 +15,3 @@ +class NodeCollection; class ANetNodeInstance; @@ -12,2 +19,33 @@ class QFile; +class MyProcess : public QObject { + + Q_OBJECT + +public : + + MyProcess(); + ~MyProcess(); + + inline OProcess & process() + { return *P; } + +public slots : + + void SLOT_Stdout( Opie::Core::OProcess * P, char *, int ); + void SLOT_Stderr( Opie::Core::OProcess * P, char *, int ); + void SLOT_ProcessExited( Opie::Core::OProcess * P); + +signals : + + void stdoutLine( const QString & ); + void stderrLine( const QString & ); + void processExited( MyProcess * ); + +private : + + QString StdoutBuffer; + QString StderrBuffer; + OProcess * P; +}; + class InterfaceInfo { @@ -24,9 +62,9 @@ public : - ANetNodeInstance * assignedNode() - { return NetNode; } + NodeCollection * assignedConnection() + { return Collection; } - void assignNode( ANetNodeInstance * NNI ) - { NetNode = NNI; } + void assignConnection( NodeCollection * NNI ) + { Collection = NNI; } - ANetNodeInstance * NetNode; // netnode taking care of me + NodeCollection * Collection; // connection taking care of me QString Name; // name of interface @@ -66,6 +104,6 @@ public : // exec command as root - int runAsRoot( const QString & S ); + int runAsRoot( QStringList & S ); // exec command as user - void execAsUser( QString & Cmd, char * argv[] ); + int execAsUser( QStringList & Cmd ); @@ -77,5 +115,13 @@ public : + InterfaceInfo * findInterface( const QString & DevName ); + +private slots : + + void SLOT_ProcessExited( MyProcess * ); + signals : - void lineFromCommand( const QString & S ); + void stdoutLine( const QString & ); + void stderrLine( const QString & ); + void processEvent( const QString & ); @@ -86,3 +132,2 @@ private : QFile * ProcDevNet; - }; diff --git a/noncore/settings/networksettings2/networksettings2/systemfile.cpp b/noncore/settings/networksettings2/networksettings2/systemfile.cpp index 2b40834..82fd43a 100644 --- a/noncore/settings/networksettings2/networksettings2/systemfile.cpp +++ b/noncore/settings/networksettings2/networksettings2/systemfile.cpp @@ -18,2 +18,3 @@ SystemFile::SystemFile( const QString & N, Path = P; + InAppend = 0; F = 0; @@ -65,5 +66,18 @@ SystemFile::SystemFile( const QString & N, +SystemFile::SystemFile( const QString & N, bool KDI ){ + Name = N; + Path = ""; + InAppend = 0; + F =0; + KnowsDeviceInstances = KDI; + hasPreSection = + hasPostSection = + hasPreNodeSection = + hasPostNodeSection = + hasPreDeviceSection = + hasPostDeviceSection = 0; +} + SystemFile::~SystemFile( void ) { - if( F ) - delete F; + close(); } @@ -71,2 +85,6 @@ SystemFile::~SystemFile( void ) { bool SystemFile::open( void ) { + QString Prefix = getenv( "NS2OUTPUTTO" ); + + if( Prefix != "stderr" /* && Name != "interfaces" */ ) { + // generate files where the need to be if( F ) { @@ -76,6 +94,24 @@ bool SystemFile::open( void ) { - F = new QFile( Path + "bup" ); - if( ! F->open( IO_WriteOnly ) ) { + F = new QFile( Prefix + Path + ((InAppend)?"":"bup") ); + Log(( "Open systemfile %s\n", F->name().latin1() )); + if( ! F->open( ((InAppend)?IO_Append : 0 ) | IO_WriteOnly ) ) { return 0; } + } else { + if( ! F ) { + owarn << "!!!!!!!!!!!!!!!!!! " << oendl; + owarn << "!!!! TESTMODE !!!!" << oendl; + owarn << "!!!!!!!!!!!!!!!!!! " << oendl; + owarn << "!!!!" << oendl; + owarn << "!!!! GENERATE " << Path << oendl; + if( InAppend ) { + owarn << "!!!! In APPEND mode" << oendl; + } + owarn << "!!!!" << oendl; + owarn << "!!!!!!!!!!!!!!!!!!" << oendl; + + F = new QFile(); + F->open( IO_WriteOnly, stderr ); + } + } setDevice( F ); @@ -85,3 +121,3 @@ bool SystemFile::open( void ) { bool SystemFile::close( void ) { - if( ! F ) { + if( ! F || ! F->isOpen() ) { return 1 ; @@ -89,3 +125,9 @@ bool SystemFile::close( void ) { - QString OldP = Path + "bup"; + QString Prefix = getenv( "NS2OUTPUTTO" ); + + if( Prefix == "stderr" ) { + return 1; + } + + QString OldP = Prefix + Path + "bup"; @@ -95,4 +137,8 @@ bool SystemFile::close( void ) { + if( ! InAppend ) { + owarn << "Rename " << OldP << " to " << Path << oendl; return ( rename( OldP.latin1(), Path.latin1() ) >= 0 ); } + return 1; +} diff --git a/noncore/settings/networksettings2/networksettings2/systemfile.h b/noncore/settings/networksettings2/networksettings2/systemfile.h index ceed605..a950c4d 100644 --- a/noncore/settings/networksettings2/networksettings2/systemfile.h +++ b/noncore/settings/networksettings2/networksettings2/systemfile.h @@ -16,8 +16,16 @@ public : bool KnowsDevicesInstances ); + SystemFile( const QString & Name, + bool KnowsDevicesInstances = 0 ); ~SystemFile( void ); + void setName( const QString & S ) + { Name = S; } const QString & name( void ) const { return Name; } + + void setPath( const QString & S ) + { Path = S; } const QString & path( void ) const { return Path; } + bool knowsDeviceInstances( void ) const @@ -25,2 +33,4 @@ public : + void setAppendMode( bool A) + { InAppend = A; }; bool open( void ); @@ -47,2 +57,3 @@ private : bool KnowsDeviceInstances; + bool InAppend; |