Diffstat (limited to 'noncore/settings/networksettings2/networksettings2') (more/less context) (ignore whitespace changes)
11 files changed, 788 insertions, 237 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 @@ -28,9 +28,18 @@ #define CIM(Data,Wdg,FL) \ if( Wdg->currentItem() != Data) { \ FL = 1; \ Data = Wdg->currentItem(); \ } +#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 ); #endif 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 @@ -1,9 +1,11 @@ #ifndef __UTILS_H #define __UTILS_H +#include <opie2/odebug.h> + #define Log(x) VLog x extern void VLog( char * Format, ... ); extern void LogClose( void ); extern QString removeSpaces( const QString & X ); #endif 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 @@ -1,23 +1,36 @@ #include <time.h> #include <qpe/qpeapplication.h> #include <qpe/resource.h> - #include <qpainter.h> #include <qbitmap.h> #include <qtextstream.h> #include <qpixmap.h> #include "resources.h" #include "netnode.h" -#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" +}; QString & deQuote( QString & X ) { if( X[0] == '"' ) { // remove end and trailing "" and \x -> x QChar R; long idx; @@ -62,12 +75,27 @@ void ANetNode::saveAttributes( QTextStream & TS ) { } void ANetNode::setAttribute( QString & Attr, QString & Value ){ setSpecificAttribute( Attr, 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 ; +} + // // // ANETNODEINSTANCE // // @@ -81,21 +109,21 @@ void ANetNodeInstance::initialize( void ) { N.sprintf( "-%ld", InstanceCounter++ ); N.prepend( NodeType->name() ); setName( N.latin1() ); } void ANetNodeInstance::setAttribute( QString & Attr, QString & Value ){ - if( Attr == "name" ) { + if( Attr == "__name" ) { setName( Value.latin1() ); } else { setSpecificAttribute( Attr, Value ); } } void ANetNodeInstance::saveAttributes( QTextStream & TS ) { - TS << "name=" << name() << endl; + TS << "__name=" << name() << endl; saveSpecificAttribute( TS ); } ANetNodeInstance * ANetNodeInstance::nextNode( void ) { return connection()->findNext( this ); } @@ -109,23 +137,25 @@ ANetNodeInstance * ANetNodeInstance::nextNode( void ) { NodeCollection::NodeCollection( void ) : QList<ANetNodeInstance>() { IsModified = 0; Index = -1; Name=""; IsNew = 1; CurrentState = Unchecked; + AssignedInterface = 0; } NodeCollection::NodeCollection( QTextStream & TS ) : QList<ANetNodeInstance>() { long idx; bool InError = 0; QString S, A, N; IsModified = 0; Index = -1; Name=""; IsNew = 0; + AssignedInterface = 0; CurrentState = Unchecked; do { S = TS.readLine(); if( S.isEmpty() ) { if( InError ) { @@ -144,33 +174,35 @@ NodeCollection::NodeCollection( QTextStream & TS ) : N.stripWhiteSpace(); N = deQuote( N ); if( A == "name" ) { Name = N; } else if( A == "number" ) { - Log(( "Profile number %s\n", N.latin1() )); setNumber( N.toLong() ); } else if( A == "node" ) { ANetNodeInstance * NNI = NSResources->findNodeInstance( N ); if( NNI && ! InError ) { append( NSResources->findNodeInstance( N ) ); } else { // could not find a node type -> collection invalid InError = 1; } } } while( 1 ); + + Log(( "Profile number %s : %d nodes\n", + N.latin1(), count() )); } NodeCollection::~NodeCollection( void ) { } const QString & NodeCollection::description( void ) { ANetNodeInstance * NNI = getToplevel(); - return (NNI) ? NNI->runtime()->asFullSetup()->description() : Name; + return (NNI) ? NNI->runtime()->description() : Name; } void NodeCollection::append( ANetNodeInstance * NNI ) { NNI->setConnection( this ); QList<ANetNodeInstance>::append( NNI ); } @@ -251,13 +283,14 @@ static char * State2PixmapTbl[] = { }; QPixmap NodeCollection::devicePixmap( void ) { QPixmap pm = NSResources->getPixmap( getToplevel()->nextNode()->pixmapName()+"-large"); - QPixmap Mini = NSResources->getPixmap( device()->netNode()->pixmapName() ); + QPixmap Mini = NSResources->getPixmap( + device()->netNode()->pixmapName() ); if( pm.isNull() || Mini.isNull() ) return Resource::loadPixmap("Unknown"); QPainter painter( &pm ); painter.drawPixmap( pm.width()-Mini.width(), @@ -277,17 +310,17 @@ QString NodeCollection::stateName( State_t S) { return qApp->translate( "networksettings2", "Unknown"); case Unavailable : return qApp->translate( "networksettings2", "Unavailable"); case Disabled : return qApp->translate( "networksettings2", "Disabled"); case Off : - return qApp->translate( "networksettings2", "Off"); + return qApp->translate( "networksettings2", "Inactive"); case Available : return qApp->translate( "networksettings2", "Available"); case IsUp : - return qApp->translate( "networksettings2", "IsUp"); + return qApp->translate( "networksettings2", "Up"); case Unchecked : /* FT */ default : break; } return QString(""); } @@ -297,41 +330,182 @@ void NodeCollection::reassign( void ) { it.current(); ++it ) { it.current()->setConnection( this ); } } -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 ); } -ANetNodeInstance * NodeCollection::firstWithDataForFile( const QString & S ) { +ANetNodeInstance * NodeCollection::firstWithDataForFile( SystemFile & S ) { for( QListIterator<ANetNodeInstance> it(*this); it.current(); ++it ) { if( it.current()->hasDataForFile( S ) ) { - Log(( "Node %s has data for %s\n", - it.current()->nodeClass()->name(), - S.latin1() )); return it.current(); } } return 0; } +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 // // -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 @@ -7,12 +7,13 @@ #include <qpixmap.h> #include <qstringlist.h> #include <qobject.h> #include <time.h> #include <Utils.h> +#include <system.h> // difference feature interfaces class AsDevice; class AsLine; class AsConnection; class AsFullSetup; @@ -23,12 +24,13 @@ class AsFullSetup; class ANetNode; class ANetNodeInstance; class NodeCollection; class QTextStream; class RuntimeInfo; class InterfaceInfo; +class NSResources; extern QString & deQuote( QString & X ); extern QString quote( QString X ); #include "systemfile.h" @@ -52,27 +54,27 @@ typedef enum State { Available = 5, // if connection is being used IsUp = 6 } State_t; 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 } Action_t; -class ANetNode : public QObject{ +class ANetNode : public QObject { public: typedef QArray<ANetNode *> NetNodeList; ANetNode( const char * Name ) : QObject( 0, Name ) {} @@ -87,14 +89,13 @@ public: inline int done( void ) { return Done; } inline void setDone( int D ) { Done = D; } // does this Node provide a Connection - inline bool isToplevel( void ) - { return strcmp( provides(), "fullsetup") == 0 ; } + bool isToplevel( void ); // set the value of an attribute void setAttribute( QString & Attr, QString & Value ) ; void saveAttributes( QTextStream & TS ) ; // compiled references to 'needed' NetNodes -> needs list @@ -107,46 +108,58 @@ public: // // Virtual methods with sensible default // // // 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 * , long ) { return 1; } - // generate NIC name based on instance nr // only relevant if node instances are devices virtual QString genNic( long ) { return QString(""); } // max number of instances for this node type // only relevant if node instances are devices virtual long instanceCount( void ) { return 1; } - // 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(); } // // // pure virtual methods with sensible default // // @@ -157,14 +170,16 @@ public: // description for this NetNode virtual const QString nodeDescription() = 0; // create a blank instance of a net node virtual ANetNodeInstance * createInstance( void ) = 0; - // 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; protected : NetNodeList * Alternatives; @@ -221,13 +236,13 @@ public: { Description = S; } // pixmap for this instance -> from NetNode inline const QString pixmapName( void ) { return NodeType->pixmapName(); } - inline const char * provides( void ) + inline const char ** provides( void ) { return NodeType->provides(); } inline const char ** needs( void ) { return NodeType->needs(); } inline void setConnection( NodeCollection * NC ) @@ -241,38 +256,34 @@ public: // // // open proper file identified by S - virtual QFile * openFile( const QString & ) + virtual bool openFile( SystemFile & ) { return 0; } // 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 ); } // generate code specific for this node but embedded // in the section of the parent // 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; } // generate code specific for this node // (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; } // return true if this node instance is triggered by this trigger // could be delegated to deeper instances virtual bool triggeredBy( const QString & ) { return 0; } @@ -320,47 +331,137 @@ class RuntimeInfo : public QObject { public : RuntimeInfo( ANetNodeInstance * TheNNI ) { NNI = TheNNI; } - // 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 + // + // // does this node handles this interface e.g.eth0 // 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 ); - - ANetNodeInstance * netNode() + 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; + } + + // + // + // 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; + } signals : // sent by device if state changes void stateChanged( State_t S, ANetNodeInstance * NNI ); 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 ANetNodeInstance * NNI; }; class NodeCollection : public QList<ANetNodeInstance> { @@ -389,48 +490,49 @@ public : { IsModified = N ; } inline bool handlesInterface( const QString & S ) { return getToplevel()->runtime()->handlesInterface( S ); } + // 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() { + // assign the interface to this device + inline void assignInterface( InterfaceInfo * NI ) { + if( NI == 0 ) { + if( AssignedInterface ) { + AssignedInterface->assignConnection( 0 ); + } + } + AssignedInterface = NI; + if( AssignedInterface ) { + AssignedInterface->assignConnection( this ); + } + } + + inline RuntimeInfo * device() { return getToplevel()->runtime()->device(); } - 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; - } + const QStringList & triggers(); + + State_t state( bool Update = 0 ); // get the ixmap for this device QPixmap devicePixmap( void ); QPixmap statePixmap( State_t S ); inline QPixmap statePixmap( bool Update = 0 ) { return statePixmap( state(Update) ); } QString stateName( State_t ); inline QString stateName( bool Update = 0 ) { return stateName( state(Update) ); } - 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 ); void save( QTextStream & TS ); void append( ANetNodeInstance * NNI ); // makes sure that all items in the connection point to @@ -453,22 +555,20 @@ public : { return CurrentState; } inline void setCurrentState( State_t S ) { CurrentState = S; } // return TRUE if this node can have data to be inserted in // 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 ); } bool triggeredBy( const QString & Trigger ) { return getToplevel()->triggeredBy( Trigger ); } private : @@ -486,9 +586,11 @@ private : bool IsNew; // index in listbox int Index; bool IsModified; int Done; + InterfaceInfo * AssignedInterface; + }; #endif 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 @@ -2,19 +2,15 @@ TEMPLATE = lib CONFIG += qt warn_on release #CONFIG += qt warn_on debug DESTDIR = $(OPIEDIR)/lib$(PROJMAK) HEADERS = netnode.h \ resources.h \ system.h \ - asline.h \ GUIUtils.h \ - asconnection.h \ - asfullsetup.h \ systemfile.h \ - wextensions.h \ - asdevice.h + wextensions.h SOURCES = netnode.cpp \ GUIUtils.cpp \ system.cpp \ systemfile.cpp \ wextensions.cpp \ resources.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 @@ -42,55 +42,63 @@ TheNSResources::TheNSResources( void ) : NodeTypeNameMap(), for ( QDictIterator<NetNode_t> InnerIt( AllNodeTypes ); InnerIt.current(); ++InnerIt ) { if( InnerIt.current() == OuterIt.current() ) // avoid recursive continue; - 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 ) { - // inner provides what outer needs - NNL.resize( NNL.size() + 1 ); - NNL[NNL.size()-1] = InnerIt.current()->NetNode; - Done = 1; // break from 2 loops - break; + const char ** PRun; + PRun = Provides; + for( ; *PRun; PRun ++ ) { + if( strcmp( *PRun, *NeedsRun ) == 0 ) { + // inner provides what outer needs + NNL.resize( NNL.size() + 1 ); + NNL[NNL.size()-1] = InnerIt.current()->NetNode; + Done = 1; // break from 2 loops + break; + } } } } OuterIt.current()->NetNode->setAlternatives( NNLP ); } } - // 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", - tr( "<p>Devices that can handle IP packets</p>" ) ); - NodeTypeDescriptionMap.insert( "line", - tr( "<p>Devices that can handle single bytes</p>" ) ); - NodeTypeDescriptionMap.insert( "connection", - tr( "<p>Nodes that provide working IP connections</p>" ) ); - NodeTypeDescriptionMap.insert( "fullsetup", - tr( "<p>Fully configured connection profile</p>" ) ); - - // define system files - addSystemFile( "interfaces", "/tmp/interfaces", 1 ); + // define built in Node types to Description map + addNodeType( "device", tr( "Network Device" ), + tr( "<p>Devices that can handle IP packets</p>" ) ); + addNodeType( "line", tr( "Character device" ), + tr( "<p>Devices that can handle single bytes</p>" ) ); + addNodeType( "connection", tr( "IP Connection" ), + tr( "<p>Nodes that provide working IP connections</p>" ) ); + addNodeType( "fullsetup", tr( "Connection Profile" ), + tr( "<p>Fully configured connection profile</p>" ) ); + addNodeType( "GPRS", tr( "Connection to GPRS device" ), + tr( "<p>Connection to a GPRS capable device</p>" ) ); // get access to the system TheSystem = new System(); } TheNSResources::~TheNSResources( void ) { delete TheSystem; } +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, const QString & P, bool KDI ) { if( ! SystemFiles.find( ID ) ) { // new system file SystemFiles.insert( ID, new SystemFile( ID, P, KDI ) ); @@ -217,14 +225,16 @@ bool TheNSResources::loadNetNode( } QPixmap TheNSResources::getPixmap( const QString & QS ) { QPixmap P; QString S("networksettings2/"); 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; } QString TheNSResources::tr( const char * s ) { return qApp->translate( "resource", s ); } @@ -266,12 +276,22 @@ void TheNSResources::removeConnection( const QString & N ) { } NodeCollection * TheNSResources::findConnection( const QString & S ) { return ConnectionsMap[ S ]; } +NodeCollection * TheNSResources::getConnection( int nr ) { + for( QDictIterator<NodeCollection> it(ConnectionsMap); + it.current(); + ++it ) { + if( it.current()->number() == nr ) { + return it.current(); + } + } + return 0; +} /* void TheNSResources::renumberConnections( void ) { Name2Connection_t & M = NSResources->connections(); NodeCollection * NC; // for all connections 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 @@ -64,12 +64,17 @@ public : { return AllNodeTypes.find(X)!=0; } ANetNode * findNetNode( const QString & N ) { NetNode_t * NNT = AllNodeTypes.find(N); return (NNT) ? NNT->NetNode : 0; } + // define new plugin (=node) + void addNodeType( const QString & ID, + const QString & LongName, + const QString & Description ); + Name2SystemFile_t & systemFiles( void ) { return SystemFiles; } void addSystemFile( const QString & ID, const QString & P, bool KDI ); @@ -96,12 +101,13 @@ public : const QString & netNode2Name( const char * Type ); const QString & netNode2Description( const char * Type ); void addConnection( NodeCollection * NC ); void removeConnection( const QString & N ); NodeCollection * findConnection( const QString & N ); + NodeCollection * getConnection( int nr ); Name2Connection_t & connections( void ) { return ConnectionsMap; } inline bool userKnown( void ) { return CurrentUser.known(); } CurrentQPEUser & currentUser( 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 @@ -10,12 +10,14 @@ #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> +#include <opie2/oprocess.h> + #include <qdir.h> #include <qregexp.h> #include <qstringlist.h> #include <qfile.h> #include <qtextstream.h> #include <qapplication.h> @@ -47,69 +49,124 @@ System::System( void ) : QObject(), ProbedInterfaces() { System::~System( void ) { if( ProcDevNet ) delete ProcDevNet; } -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 return 8888; } if( usr == 0 || strcmp( usr, "root" ) ) { // unknown or non-root user -> use SUDO - MyS.prepend( "sudo " ); + S.prepend( "sudo" ); } - Log(("Executing %s\n", MyS.latin1() )); - - 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 - return 1; + 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*) ) ); + + 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; +} + +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; } - } else { - Line += ch; } - } - if( ! Line.isEmpty() ) { - emit lineFromCommand( Line ); - Log(( "read cmd output : **%s**\n", Line.latin1() ) ); - } - Log(( "End of command\n", Line.latin1() ) ); + // now we are ready to exec the requested command + setuid( CU.Uid ); + setgid( CU.Gid ); - if( pclose( OutputOfCmd ) < 0 ) { - // error in command - return 3; - } + 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] ); + } - // all is fine - return 0; + 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 )); + } + + return rv; +} + +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 += " "; + } + + R += "Returned with " + QString().setNum( P->process().exitStatus() ); + emit processEvent( R ); + delete P; } void System::refreshStatistics( InterfaceInfo & I ) { if( ! ProcDevNet ) { return; } @@ -195,21 +252,35 @@ void System::probeInterfaces( void ) { it.current(); ++it ) { it.current()->IsUp = 0; } sockfd = socket(PF_INET, SOCK_DGRAM, 0); - if(sockfd == -1) + if(sockfd == -1) { + owarn << "Cannot open INET socket " + << errno + << " " + << strerror( errno ) + << oendl; return; + } // read interfaces from /proc/dev/net // SIOCGIFCONF does not return ALL interfaces ???!? ProcDevNet = new QFile(PROCNETDEV); if( ! ProcDevNet->open(IO_ReadOnly) ) { + owarn << "Cannot open " + << PROCNETDEV + << " " + << errno + << " " + << strerror( errno ) + << oendl; delete ProcDevNet; ProcDevNet =0; + ::close( sockfd ); return; } QString line; QString NicName; QTextStream procTs(ProcDevNet); @@ -226,16 +297,16 @@ void System::probeInterfaces( void ) { // set name for ioctl strcpy( ifrs.ifr_name, NicName.latin1() ); if ( ! ( IFI = ProbedInterfaces.find( NicName ) ) ) { // 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 ); // get dynamic info if( ioctl(sockfd, SIOCGIFFLAGS, &ifrs) >= 0 ) { IFI->IsPointToPoint = ((ifrs.ifr_flags & IFF_POINTOPOINT) == IFF_POINTOPOINT); } else { @@ -253,13 +324,13 @@ void System::probeInterfaces( void ) { } IFI->CardType = 999999; IFI->MACAddress = ""; 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 )); IFI->CardType = ifrs.ifr_hwaddr.sa_family; switch( ifrs.ifr_hwaddr.sa_family ) { case ARPHRD_ETHER : // regular MAC address // valid address -> convert to regular ::: format @@ -321,13 +392,13 @@ void System::probeInterfaces( void ) { break; case ARPHRD_IRDA : // IRDA break; } } } else // else already probed before -> just update - Log(("OLDNIC %s\n", NicName.latin1())); + Log(("Redetected NIC %s\n", NicName.latin1())); // get dynamic info if( ioctl(sockfd, SIOCGIFFLAGS, &ifrs) >= 0 ) { IFI->IsUp = ((ifrs.ifr_flags & IFF_UP) == IFF_UP); IFI->HasMulticast = ((ifrs.ifr_flags & IFF_MULTICAST) == IFF_MULTICAST); } else { @@ -351,70 +422,65 @@ void System::probeInterfaces( void ) { if( ioctl(sockfd, SIOCGIFNETMASK, &ifrs) >= 0 ) { IFI->Netmask = inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_netmask)->sin_addr); } else { IFI->Netmask = ""; } - 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; - } - // 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) ); + ::close( sockfd ); +} - 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; } #include <stdarg.h> static FILE * logf = 0; void VLog( char * Format, ... ) { va_list l; va_start(l, 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; } else { fprintf( logf, "____ OPEN LOGFILE ____\n"); } } - if( (long)logf > 1 ) { + if( (unsigned long)logf > 1 ) { vfprintf( logf, Format, l ); } va_end( l ); + fflush( logf ); } void LogClose( void ) { if( (long)logf > 1 ) { fprintf( logf, "____ CLOSE LOGFILE ____\n"); @@ -423,11 +489,85 @@ void LogClose( void ) { } logf = 0; } } 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 @@ -1,37 +1,75 @@ #ifndef __SYSTEM__H #define __SYSTEM__H +#include <qstring.h> + +#include <opie2/oprocess.h> + +using namespace Opie::Core; + // for hardware types #include <net/if_arp.h> #include <qdict.h> #include <qobject.h> #include <stdio.h> +class NodeCollection; class ANetNodeInstance; 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 { public : InterfaceInfo() : Name(), MACAddress(), BCastAddress(), Netmask(), DstAddress() { } - 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 int CardType; // type of card QString MACAddress; // MAC address QString Address; // IP Address QString BCastAddress; // Broadcast Address QString Netmask; // Netmask @@ -61,30 +99,37 @@ public : QDict<InterfaceInfo> & interfaces( void ) { return ProbedInterfaces; } InterfaceInfo * interface( const QString& N ) { return ProbedInterfaces[N]; } // 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 ); // refresh stats for this interface void refreshStatistics( InterfaceInfo & ); // reloads interfaces void probeInterfaces( void ); + 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 & ); private : QDict<InterfaceInfo> ProbedInterfaces; FILE * OutputOfCmd; QFile * ProcDevNet; - }; #endif 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 @@ -13,12 +13,13 @@ QString TemplDir; SystemFile::SystemFile( const QString & N, const QString & P, bool KDI ){ Name = N; Path = P; + InAppend = 0; F = 0; // get template info { QString S; QFileInfo FI; // find location of templates @@ -60,43 +61,88 @@ SystemFile::SystemFile( const QString & N, hasPostDeviceSection = ( FI.exists() && FI.isReadable() ); } KnowsDeviceInstances = KDI; } +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(); } bool SystemFile::open( void ) { - if( F ) { - F->close(); - delete F; - } + QString Prefix = getenv( "NS2OUTPUTTO" ); + + if( Prefix != "stderr" /* && Name != "interfaces" */ ) { + // generate files where the need to be + if( F ) { + F->close(); + delete F; + } - F = new QFile( Path + "bup" ); - if( ! F->open( IO_WriteOnly ) ) { - return 0; + 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 ); return 1; } bool SystemFile::close( void ) { - if( ! F ) { + if( ! F || ! F->isOpen() ) { return 1 ; } - QString OldP = Path + "bup"; + QString Prefix = getenv( "NS2OUTPUTTO" ); + + if( Prefix == "stderr" ) { + return 1; + } + + QString OldP = Prefix + Path + "bup"; F->close(); delete F; F = 0; - return ( rename( OldP.latin1(), Path.latin1() ) >= 0 ); + if( ! InAppend ) { + owarn << "Rename " << OldP << " to " << Path << oendl; + return ( rename( OldP.latin1(), Path.latin1() ) >= 0 ); + } + return 1; } bool SystemFile::preSection( void ) { if( hasPreSection ) { QFile Fl( TemplDir + Name + "/presection" ); if( ! Fl.open( IO_ReadOnly ) ) 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 @@ -11,21 +11,31 @@ class SystemFile : public QTextStream { public : SystemFile( const QString & Name, const QString & Path, 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 { return KnowsDeviceInstances; } + void setAppendMode( bool A) + { InAppend = A; }; bool open( void ); bool close( void ); bool preSection( void ); bool postSection( void ); bool preNodeSection( ANetNodeInstance * NNI, long DevNr ); @@ -42,9 +52,10 @@ private : bool hasPostSection; bool hasPreNodeSection; bool hasPostNodeSection; bool hasPreDeviceSection; bool hasPostDeviceSection; bool KnowsDeviceInstances; + bool InAppend; }; #endif |