summaryrefslogtreecommitdiff
authorwimpie <wimpie>2004-04-05 01:13:11 (UTC)
committer wimpie <wimpie>2004-04-05 01:13:11 (UTC)
commit6be3d148fc1d610ebfa193012657b3b77d9368e3 (patch) (side-by-side diff)
treed7bbd308d17ffe7557c7749776f4945e499d7c10
parentb0ceb8843ebe9ee3054faa98f08bd255df955aa3 (diff)
downloadopie-6be3d148fc1d610ebfa193012657b3b77d9368e3.zip
opie-6be3d148fc1d610ebfa193012657b3b77d9368e3.tar.gz
opie-6be3d148fc1d610ebfa193012657b3b77d9368e3.tar.bz2
For usb this seems to be working
Also for non-root users (requires using SUDO)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/networksettings2/activateprofile.cpp2
-rw-r--r--noncore/settings/networksettings2/activateprofileGUI.ui4
-rw-r--r--noncore/settings/networksettings2/main.cpp15
-rw-r--r--noncore/settings/networksettings2/network/network_NNI.cpp47
-rw-r--r--noncore/settings/networksettings2/network/networkrun.cpp4
-rw-r--r--noncore/settings/networksettings2/networksettings2/resources.cpp137
-rw-r--r--noncore/settings/networksettings2/networksettings2/resources.h18
-rw-r--r--noncore/settings/networksettings2/networksettings2/system.cpp43
-rw-r--r--noncore/settings/networksettings2/networksettings2/system.h7
-rw-r--r--noncore/settings/networksettings2/nsdata.cpp26
-rw-r--r--noncore/settings/networksettings2/nsdata.h3
11 files changed, 270 insertions, 36 deletions
diff --git a/noncore/settings/networksettings2/activateprofile.cpp b/noncore/settings/networksettings2/activateprofile.cpp
index ba726bb..e4064e3 100644
--- a/noncore/settings/networksettings2/activateprofile.cpp
+++ b/noncore/settings/networksettings2/activateprofile.cpp
@@ -1,29 +1,31 @@
#include <qlistbox.h>
+#include <qlabel.h>
#include "activateprofile.h"
ActivateProfile::ActivateProfile( const char * Interface ) :
ActivateProfileGUI( 0, 0, TRUE ), NSD() {
Possible = NSD.collectPossible( Interface );
+ DeviceName_LBL->setText( Interface );
Profiles_LB->clear();
for( NodeCollection * NC = Possible.first();
NC;
NC = Possible.next() ) {
Profiles_LB->insertItem( NC->devicePixmap(),
NC->name() );
}
}
ActivateProfile::~ActivateProfile( void ) {
}
long ActivateProfile::selectedProfile( void ) {
for( unsigned int i = 0 ; i < Profiles_LB->count(); i ++ ) {
if( Profiles_LB->isSelected(i) ) {
return Possible.at(i)->number();
}
}
return -1;
}
diff --git a/noncore/settings/networksettings2/activateprofileGUI.ui b/noncore/settings/networksettings2/activateprofileGUI.ui
index 296e044..12ab051 100644
--- a/noncore/settings/networksettings2/activateprofileGUI.ui
+++ b/noncore/settings/networksettings2/activateprofileGUI.ui
@@ -1,85 +1,85 @@
<!DOCTYPE UI><UI>
<class>ActivateProfileGUI</class>
<widget>
<class>QDialog</class>
<property stdset="1">
<name>name</name>
<cstring>ActivateProfileGUI</cstring>
</property>
<property stdset="1">
<name>geometry</name>
<rect>
<x>0</x>
<y>0</y>
<width>231</width>
<height>121</height>
</rect>
</property>
<property stdset="1">
<name>caption</name>
- <string>Activate Profile</string>
+ <string>Activate Network</string>
</property>
<property>
<name>layoutMargin</name>
</property>
<property>
<name>layoutSpacing</name>
</property>
<vbox>
<property stdset="1">
<name>margin</name>
<number>2</number>
</property>
<property stdset="1">
<name>spacing</name>
<number>2</number>
</property>
<widget>
<class>QLayoutWidget</class>
<property stdset="1">
<name>name</name>
<cstring>Layout2</cstring>
</property>
<hbox>
<property stdset="1">
<name>margin</name>
<number>0</number>
</property>
<property stdset="1">
<name>spacing</name>
<number>6</number>
</property>
<widget>
<class>QLabel</class>
<property stdset="1">
<name>name</name>
<cstring>TextLabel1</cstring>
</property>
<property stdset="1">
<name>text</name>
- <string>Select profile for device :</string>
+ <string>Select profile to activate for </string>
</property>
</widget>
<widget>
<class>QLabel</class>
<property stdset="1">
<name>name</name>
<cstring>DeviceName_LBL</cstring>
</property>
<property stdset="1">
<name>text</name>
<string>TextLabel2</string>
</property>
</widget>
</hbox>
</widget>
<widget>
<class>QListBox</class>
<property stdset="1">
<name>name</name>
<cstring>Profiles_LB</cstring>
</property>
</widget>
</vbox>
</widget>
</UI>
diff --git a/noncore/settings/networksettings2/main.cpp b/noncore/settings/networksettings2/main.cpp
index 7ec26a7..e2c00f6 100644
--- a/noncore/settings/networksettings2/main.cpp
+++ b/noncore/settings/networksettings2/main.cpp
@@ -1,119 +1,132 @@
#include "nsdata.h"
#include "activateprofile.h"
#include "networksettings.h"
+
#include <qpe/qpeapplication.h>
#include <opie/oapplicationfactory.h>
#ifdef GONE
OPIE_EXPORT_APP( OApplicationFactory<NetworkSettings> )
#else
// just standard GUI
#define ACT_GUI 0
// used by interfaces to request for allow of up/down
#define ACT_REQUEST 1
// regenerate config files
#define ACT_REGEN 2
// used by interfaces to request user prompt
#define ACT_PROMPT 3
int main( int argc, char * argv[] ) {
int rv = 0;
int Action = ACT_GUI;
// could be overruled by -qws
QApplication::Type GuiType = QApplication::GuiClient;
#ifdef _WS_QWS_
QPEApplication * TheApp;
#else
QApplication * TheApp;
#endif
for ( int i = 1; i < argc; i ++ ) {
int rmv;
rmv = 0;
if( strcmp( argv[i], "--regen" ) == 0 ) {
Action = ACT_REGEN;
GuiType = QApplication::Tty;
rmv = 1;
} else if( strcmp( argv[i], "--prompt" ) == 0 ) {
Action = ACT_PROMPT;
rmv = 1;
}
if( rmv ) {
memmove( argv+i, argv+i+rmv,
sizeof( char * ) * (argc-i-rmv) );
i --;
argc -= rmv;
}
}
if( strstr( argv[0], "-request" ) ) {
// called from system to request something
GuiType = QApplication::Tty;
Action = ACT_REQUEST;
}
// Start Qt
#ifdef _WS_QWS_
// because QPEApplication does not handle GuiType well
if( GuiType == QApplication::Tty ) {
// this cast is NOT correct but we do not use
// TheApp anymore ...
TheApp = (QPEApplication *)new QApplication( argc, argv, GuiType );
} else {
TheApp = new QPEApplication( argc, argv, GuiType );
}
#else
TheApp = new QApplication( argc, argv, GuiType );
#endif
// init qt with app widget
switch( Action ) {
case ACT_REQUEST :
{ NetworkSettingsData NS;
- NS.canStart( argv[1] );
+ if( NS.canStart( argv[1] ) ) {
+ QString S;
+ S.sprintf( QPEApplication::qpeDir()+
+ "/bin/networksettings2" );
+ char * MyArgv[4];
+ MyArgv[0] = "networksettings2";
+ MyArgv[1] = "--prompt";
+ MyArgv[2] = argv[1];
+ MyArgv[3] = NULL;
+ NSResources->system().execAsUser( S, MyArgv );
+ // if we come here , failed
+ printf( "%s-cNN-disallowed", argv[1] );
+ }
}
break;
case ACT_REGEN :
{ NetworkSettingsData NS;
// regen returns 0 if OK
rv = (NS.regenerate()) ? 1 : 0;
}
break;
case ACT_PROMPT :
{ ActivateProfile AP(argv[1]);
if( AP.exec() == QDialog::Accepted ) {
printf( "%s-c%ld-allowed", argv[1], AP.selectedProfile() );
} else {
printf( "%s-cNN-disallowed", argv[1] );
}
}
break;
case ACT_GUI :
{ QWidget * W = new NetworkSettings(0);
TheApp->setMainWidget( W );
W->show();
#ifdef _WS_QWS_
W->showMaximized();
#else
W->resize( W->sizeHint() );
#endif
rv = TheApp->exec();
delete W;
}
break;
}
return rv;
}
#endif
// main.cpp
diff --git a/noncore/settings/networksettings2/network/network_NNI.cpp b/noncore/settings/networksettings2/network/network_NNI.cpp
index 054385a..3e368a2 100644
--- a/noncore/settings/networksettings2/network/network_NNI.cpp
+++ b/noncore/settings/networksettings2/network/network_NNI.cpp
@@ -1,168 +1,189 @@
#include <system.h>
#include <asdevice.h>
#include "networkedit.h"
#include "network_NNI.h"
#include "network_NN.h"
ANetwork::ANetwork( NetworkNetNode * PNN ) : ANetNodeInstance( PNN ) {
Data.UseDHCP = 1;
Data.IPAddress = "";
Data.NetMask = "";
Data.Broadcast = "";
Data.Gateway = "";
Data.DNS1 = "";
Data.DNS2 = "";
Data.SendHostname = 0;
Data.Hostname = "";
Data.PreUp_SL.clear();
Data.PreDown_SL.clear();
Data.PostUp_SL.clear();
Data.PostDown_SL.clear();
GUI = 0;
RT = 0;
}
void ANetwork::setSpecificAttribute( QString & A, QString & V ) {
if( A == "usedhcp" ) {
Data.UseDHCP = (V == "yes");
} else if( A == "sendhostname" ) {
Data.SendHostname = (V=="yes");
} else if( A == "hostname" ) {
Data.Hostname = V;
} else if( A == "ipaddress" ) {
Data.IPAddress = V;
} else if( A == "netmask" ) {
Data.NetMask = V;
} else if( A == "broadcast" ) {
Data.Broadcast = V;
} else if( A == "gateway" ) {
Data.Gateway = V;
} else if( A == "dns1" ) {
Data.DNS1 = V;
} else if( A == "dns2" ) {
Data.DNS2 = V;
} else if( A == "preup" ) {
Data.PreUp_SL.append( V );
} else if( A == "predown" ) {
Data.PreDown_SL.append( V );
} else if( A == "postup" ) {
Data.PostUp_SL.append( V );
} else if( A == "postdown" ) {
Data.PostDown_SL.append( V );
}
}
void ANetwork::saveSpecificAttribute( QTextStream & TS ) {
TS << "usedhcp=" << ((Data.UseDHCP) ? "yes" : "no") << endl;
TS << "sendhostname=" << ((Data.SendHostname) ? "yes" : "no") << endl;
TS << "hostname=" << Data.Hostname << endl;
TS << "ipaddress=" << Data.IPAddress << endl;
TS << "netmask=" << Data.NetMask << endl;
TS << "broadcast=" << Data.Broadcast << endl;
TS << "gateway=" << Data.Gateway << endl;
TS << "dns1=" << Data.DNS1 << endl;
TS << "dns2=" << Data.DNS2 << endl;
for ( QStringList::Iterator it = Data.PreUp_SL.begin();
it != Data.PreUp_SL.end();
++it ) {
TS << "preup=" << quote(*it) << endl;
}
for ( QStringList::Iterator it = Data.PreDown_SL.begin();
it != Data.PreDown_SL.end();
++it ) {
TS << "predown=" << quote(*it) << endl;
}
for ( QStringList::Iterator it = Data.PostUp_SL.begin();
it != Data.PostUp_SL.end();
++it ) {
TS << "postup=" << quote(*it) << endl;
}
for ( QStringList::Iterator it = Data.PostDown_SL.begin();
it != Data.PostDown_SL.end();
++it ) {
TS << "postdown=" << quote(*it) << endl;
}
}
QWidget * ANetwork::edit( QWidget * parent ) {
GUI = new NetworkEdit( parent );
GUI->showData( Data );
return GUI;
}
QString ANetwork::acceptable( void ) {
return ( GUI ) ? GUI->acceptable( ) : QString();
}
void ANetwork::commit( void ) {
if( GUI && GUI->commit( Data ) )
setModified( 1 );
}
bool ANetwork::hasDataFor( const QString & S ) {
return S == "interfaces";
}
bool ANetwork::generateDataForCommonFile( SystemFile & S, long DevNr ) {
QString NIC = runtime()->device()->netNode()->nodeClass()->genNic( DevNr );
if( S.name() == "interfaces" ) {
// we can safely call from here since device item is deeper
if( Data.UseDHCP ) {
- S << "iface " << NIC << "-c" << connection()->number() <<
- "-allowed inet dhcp" << endl;
- S << " up echo \"" << NIC << "\" > /tmp/profile-" << connection()->number() <<
- ".up" << Data.IPAddress << endl;
+ S << "iface "
+ << NIC
+ << "-c"
+ << connection()->number()
+ << "-allowed inet dhcp"
+ << endl;
+ S << " up echo \""
+ << NIC
+ << "\" > /tmp/profile-"
+ << connection()->number()
+ << ".up"
+ << endl;
if( Data.SendHostname ) {
- S << " hostname "<< Data.Hostname << endl;
+ S << " hostname "
+ << Data.Hostname
+ << endl;
}
- S << " down rm -f /tmp/profile-" << connection()->number() <<
- ".up" << Data.IPAddress << endl;
+ S << " down rm -f /tmp/profile-"
+ << connection()->number()
+ << ".up"
+ << endl;
} else {
- S << "iface " << NIC << "-c" << connection()->number() <<
- "-allowed inet static" << endl;
- S << " up echo \"" << NIC << "\" > /tmp/profile-" << connection()->number() <<
- ".up" << Data.IPAddress << endl;
- S << " down rm -f /tmp/profile-" << connection()->number() <<
- ".up" << Data.IPAddress << endl;
+ S << "iface "
+ << NIC << "-c"
+ << connection()->number()
+ << "-allowed inet static"
+ << endl;
+ S << " up echo \""
+ << NIC
+ << "\" > /tmp/profile-"
+ << connection()->number()
+ << ".up"
+ << endl;
+ S << " down rm -f /tmp/profile-"
+ << connection()->number()
+ << ".up"
+ << endl;
S << " address " << Data.IPAddress << endl;
S << " broadcast " << Data.Broadcast << endl;
S << " netmask " << Data.NetMask << endl;
// derive network address = IPAddress & netmask
{ QString NW;
QStringList ipal = QStringList::split( '.', Data.IPAddress );
QStringList nmal = QStringList::split( '.', Data.NetMask );
NW = QString( "%1.%2.%3.%4" ).
arg( ipal[0].toShort() & nmal[0].toShort() ).
arg( ipal[1].toShort() & nmal[1].toShort() ).
arg( ipal[2].toShort() & nmal[2].toShort() ).
arg( ipal[3].toShort() & nmal[3].toShort() );
S << " network " << NW << endl;
}
}
for ( QStringList::Iterator it = Data.PreUp_SL.begin();
it != Data.PreUp_SL.end();
++it ) {
S << " pre-up " << (*it) << endl;
}
for ( QStringList::Iterator it = Data.PostUp_SL.begin();
it != Data.PostUp_SL.end();
++it ) {
S << " up " << (*it) << endl;
}
for ( QStringList::Iterator it = Data.PreDown_SL.begin();
it != Data.PreDown_SL.end();
++it ) {
S << " down " << (*it) << endl;
}
for ( QStringList::Iterator it = Data.PostDown_SL.begin();
it != Data.PostDown_SL.end();
++it ) {
S << " post-down " << (*it) << endl;
}
}
return 0;
}
diff --git a/noncore/settings/networksettings2/network/networkrun.cpp b/noncore/settings/networksettings2/network/networkrun.cpp
index ddb9a5f..c19235a 100644
--- a/noncore/settings/networksettings2/network/networkrun.cpp
+++ b/noncore/settings/networksettings2/network/networkrun.cpp
@@ -1,66 +1,66 @@
#include <system.h>
#include <asdevice.h>
#include "networkrun.h"
void NetworkRun::detectState( NodeCollection * NC ) {
RuntimeInfo * RI = netNode()->nextNode()->runtime();
AsDevice * Next = RI->asDevice();
InterfaceInfo * II = Next->assignedInterface();
if( II ) {
// device has assigned interface
NC->setCurrentState( (( II->IsUp ) ? IsUp : Available) );
return;
}
// has no interface -> delegate
RI->detectState( NC );
}
bool NetworkRun::setState( NodeCollection * NC, Action_t A ) {
// we handle UP and DOWN
RuntimeInfo * RI = netNode()->nextNode()->runtime();
AsDevice * Next = RI->asDevice();
InterfaceInfo * II = Next->assignedInterface();
if( A == Up ) {
// we can bring UP if lower level is available
if( NC->currentState() == Available ) {
QString S;
S.sprintf( "ifup %s=%s-c%d-allowed",
II->Name.latin1(), II->Name.latin1(),
connection()->number() );
- NSResources->system().execute( S );
+ NSResources->system().runAsRoot( S );
}
return 1;
} else if( A == Down ) {
if( NC->currentState() == IsUp ) {
QString S;
S.sprintf( "ifdown %s=%s-c%d-allowed",
II->Name.latin1(), II->Name.latin1(),
connection()->number() );
- NSResources->system().execute( S );
+ NSResources->system().runAsRoot( S );
}
return 1;
}
// delegate
return RI->setState( NC, A );
}
bool NetworkRun::canSetState( State_t Curr, Action_t A ) {
// we handle UP and DOWN
RuntimeInfo * RI = netNode()->nextNode()->runtime();
if( A == Up ) {
return ( Curr == Available );
} else if( A == Down ) {
return ( Curr == IsUp );
}
// delegate
return RI->canSetState( Curr, A );
}
bool NetworkRun::handlesInterface( const QString & S ) {
// donno -> pass deeper
return netNode()->nextNode()->runtime()->handlesInterface(S);
}
diff --git a/noncore/settings/networksettings2/networksettings2/resources.cpp b/noncore/settings/networksettings2/networksettings2/resources.cpp
index 0301361..e6ce2b7 100644
--- a/noncore/settings/networksettings2/networksettings2/resources.cpp
+++ b/noncore/settings/networksettings2/networksettings2/resources.cpp
@@ -1,234 +1,369 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
#include <qpixmap.h>
+#include <qdir.h>
#include <qpe/qlibrary.h>
#include <qpe/qpeapplication.h>
-#include <qdir.h>
#include <opie2/odebug.h>
#include <qtopia/resource.h>
#include "netnode.h"
#include "resources.h"
#define PLUGINDIR "plugins/networksettings2"
#define ICONDIR "/pics/networksettings2/"
// single resources instance
TheNSResources * _NSResources = 0;
TheNSResources::TheNSResources( void ) : NodeTypeNameMap(),
ConnectionsMap() {
_NSResources = this;
// load available netnodes
findAvailableNetNodes(QPEApplication::qpeDir() + PLUGINDIR );
// compile provides and needs lists
{ const char ** NeedsRun;
QDictIterator<NetNode_t> OuterIt( AllNodeTypes );
bool Done;
for ( ; OuterIt.current(); ++OuterIt ) {
// find needs list
ANetNode::NetNodeList * NNLP = new ANetNode::NetNodeList;
ANetNode::NetNodeList & NNL = *(NNLP);
// must iterate this way to avoid duplication pointers
for ( QDictIterator<NetNode_t> InnerIt( AllNodeTypes );
InnerIt.current(); ++InnerIt ) {
if( InnerIt.current() == OuterIt.current() )
// avoid recursive
continue;
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;
}
}
}
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( new SystemFile( "interfaces", "./interfaces" ) );
// get access to the system
TheSystem = new System();
+
+ detectCurrentUser();
}
TheNSResources::~TheNSResources( void ) {
delete TheSystem;
}
/**
* Load all modules that are found in the path
* @param path a directory that is scaned for any plugins that can be loaded
* and attempts to load them
*/
void TheNSResources::findAvailableNetNodes(const QString &path){
QDir d(path);
if(!d.exists())
return;
QString lang = ::getenv("LANG");
// Don't want sym links
d.setFilter( QDir::Files | QDir::NoSymLinks );
const QFileInfoList *list = d.entryInfoList();
QFileInfoListIterator it( *list );
QFileInfo *fi;
while ( (fi=it.current()) ) {
if( fi->fileName().contains(".so")){
/* if loaded install translation */
if( loadNetNode(path + "/" + fi->fileName()) ) {
QTranslator *trans = new QTranslator(qApp);
QString fn = QPEApplication::qpeDir()+
"/i18n/"+lang+"/"+
fi->fileName().left( fi->fileName().find(".") )+
".qm";
if( trans->load( fn ) )
qApp->installTranslator( trans );
else
delete trans;
}
}
++it;
}
}
/**
* Attempt to load a function and resolve a function.
* @param pluginFileName - the name of the file in which to attempt to load
* @param resolveString - function pointer to resolve
* @return true of loading is successful
*/
bool TheNSResources::loadNetNode(
const QString &pluginFileName, const QString &resolveString){
QLibrary *lib = new QLibrary(pluginFileName);
void * res = lib->resolve(resolveString);
if( ! res ){
delete lib;
return 0;
}
GetNetNodeListFt_t getNetNodeList = (GetNetNodeListFt_t)res;
// Try to get an object.
QList<ANetNode> PNN;
getNetNodeList( PNN );
if( PNN.isEmpty() ) {
delete lib;
return 0;
}
ANetNode * NNP;
for( QListIterator<ANetNode> it(PNN);
it.current();
++it ) {
NetNode_t * NN;
NNP = it.current();
NN = new NetNode_t;
NN->NetNode = NNP;
NN->TheLibrary = lib;
NN->NodeCountInLib = PNN.count();
// store mapping
AllNodeTypes.insert( NN->NetNode->nodeName(), NN );
}
return 1;
}
QPixmap TheNSResources::getPixmap( const QString & QS ) {
QString S("networksettings2/");
S += QS;
printf( " pixmap %s\n", S.latin1() );
return Resource::loadPixmap( QString("networksettings2/")+QS );
}
QString TheNSResources::tr( const char * s ) {
return qApp->translate( "resource", s );
}
const QString & TheNSResources::netNode2Name( const char * s ) {
return NodeTypeNameMap[s];
}
const QString & TheNSResources::netNode2Description( const char * s ) {
return NodeTypeDescriptionMap[s];
}
void TheNSResources::addConnection( NodeCollection * NC ) {
ANetNodeInstance * NNI;
ConnectionsMap.insert( NC->name(), NC );
// add (new) nodes to NodeList
for( QListIterator<ANetNodeInstance> it(*NC);
it.current();
++it ) {
NNI = it.current();
if( findNodeInstance( NNI->nodeName() ) == 0 ) {
// new item
addNodeInstance( NNI );
}
}
}
void TheNSResources::removeConnection( const QString & N ) {
NodeCollection * NC = findConnection( N );
if( ! NC )
return;
// delete netnodes in this connection
ANetNodeInstance * NNI;
for( NNI = NC->first(); NNI != 0; NNI = NC->next() ) {
removeNodeInstance( NNI->nodeName() );
}
ConnectionsMap.remove( N );
}
NodeCollection * TheNSResources::findConnection( const QString & S ) {
return ConnectionsMap[ S ];
}
void TheNSResources::renumberConnections( void ) {
Name2Connection_t & M = NSResources->connections();
NodeCollection * NC;
// for all connections
NodeCollection::resetMaxNr();
for( QDictIterator<NodeCollection> it(M);
it.current();
++it ) {
NC = it.current();
NC->setNumber( NC->maxConnectionNumber()+1 );
NC->setModified( 1 );
}
}
+
+typedef struct EnvVars {
+ char * Name;
+ int Len;
+} EnvVar_t;
+
+#define AnEV(x) x, sizeof(x)-1
+
+static EnvVar_t EV[] = {
+ // AnEV( "HOME=" ), -> SPECIAL
+ // AnEV( "LOGNAME=" ), -> SPECIAL
+ AnEV( "USER=" ),
+ AnEV( "LD_LIBRARY_PATH=" ),
+ AnEV( "PATH=" ),
+ AnEV( "QTDIR=" ),
+ AnEV( "OPIEDIR=" ),
+ AnEV( "SHELL=" ),
+ { NULL, 0 }
+};
+
+void TheNSResources::detectCurrentUser( void ) {
+ // find current running qpe
+ QString QPEEnvFile = "";
+
+ // open proc dir and find all dirs in it
+ { QRegExp R("[0-9]+");
+ QDir ProcDir( "/proc" );
+ QString QPELoc = QPEApplication::qpeDir() + "bin/qpe";
+ QFileInfo FI;
+ QStringList EL = ProcDir.entryList( QDir::Dirs );
+
+ // print it out
+ for ( QStringList::Iterator it = EL.begin();
+ it != EL.end();
+ ++it ) {
+ if( R.match( (*it) ) >= 0 ) {
+ QString S = ProcDir.path()+"/"+ (*it);
+ S.append( "/exe" );
+ FI.setFile( S );
+ // get the linke
+ S = FI.readLink();
+ if( S == QPELoc ) {
+ // found running qpe
+ QPEEnvFile.sprintf( ProcDir.path()+ "/" + (*it) + "/environ" );
+ break;
+ }
+ }
+ }
+ }
+
+ if( QPEEnvFile.isEmpty() ) {
+ // could not find qpe
+ fprintf( stderr, "Could not find qpe\n" );
+ return;
+ }
+
+ // FI now contains path ProcDir to the cmd dir
+ { char * Buf = 0;
+ char TB[1024];
+ long BufSize = 0;
+ int fd;
+ int rd;
+
+ fd = open( QPEEnvFile.latin1(), O_RDONLY );
+ if( fd < 0 ) {
+ fprintf( stderr, "Could not open %s : %d\n",
+ QPEEnvFile.latin1(), errno );
+ return;
+ }
+
+ while( (rd = read( fd, TB, sizeof(TB) ) ) > 0 ) {
+ Buf = (char *)realloc( Buf, BufSize+rd );
+ memcpy( Buf+BufSize, TB, rd );
+ BufSize += rd;
+ }
+
+ char * Data = Buf;
+ char * DataEnd = Data+BufSize-1;
+
+ // get env items out of list
+ while( Data < DataEnd ) {
+ if( strncmp( Data, "LOGNAME=", 8 ) == 0 ) {
+ CurrentUser.UserName = Data+8;
+ CurrentUser.EnvList.resize( CurrentUser.EnvList.size()+1 );
+ CurrentUser.EnvList[CurrentUser.EnvList.size()-1] =
+ strdup( Data );
+ } else if( strncmp( Data, "HOME=", 5 ) == 0 ) {
+ CurrentUser.HomeDir = Data+5;
+ CurrentUser.EnvList.resize( CurrentUser.EnvList.size()+1 );
+ CurrentUser.EnvList[CurrentUser.EnvList.size()-1] =
+ strdup( Data );
+ } else {
+ EnvVar_t * Run = EV;
+ while( Run->Name ) {
+ if( strncmp( Data, Run->Name, Run->Len ) == 0 ) {
+ CurrentUser.EnvList.resize( CurrentUser.EnvList.size()+1 );
+ CurrentUser.EnvList[CurrentUser.EnvList.size()-1] =
+ strdup( Data );
+ break;
+ }
+ Run ++;
+ }
+ }
+
+ Data += strlen( Data )+1;
+ }
+
+ free( Buf );
+
+ if( ! CurrentUser.UserName.isEmpty() ) {
+ // find user info
+ struct passwd pwd;
+ struct passwd * pwdres;
+
+ if( getpwnam_r( CurrentUser.UserName.latin1(),
+ &pwd, TB, sizeof(TB), &pwdres ) ||
+ pwdres == 0 ) {
+ fprintf( stderr, "Could not determine user %s : %d\n",
+ CurrentUser.UserName.latin1(), errno );
+ return;
+ }
+ CurrentUser.Uid = pwd.pw_uid;
+ CurrentUser.Gid = pwd.pw_gid;
+ } else{
+ CurrentUser.Uid =
+ CurrentUser.Gid = -1;
+ }
+ }
+}
diff --git a/noncore/settings/networksettings2/networksettings2/resources.h b/noncore/settings/networksettings2/networksettings2/resources.h
index 4df3ce3..3048fb3 100644
--- a/noncore/settings/networksettings2/networksettings2/resources.h
+++ b/noncore/settings/networksettings2/networksettings2/resources.h
@@ -1,110 +1,128 @@
#ifndef __RESOURCES__H
#define __RESOURCES__H
#include <qstring.h>
#include <qdict.h>
#include <qmap.h>
#include <qlist.h>
#include "netnode.h"
#include "systemfile.h"
#include "system.h"
class QLibrary;
class QPixmap;
class ANetNode;
class ANetNodeInstance;
typedef void (*GetNetNodeListFt_t)(QList<ANetNode>& PNN );
typedef struct NetNode_S {
ANetNode * NetNode;
QLibrary * TheLibrary;
long NodeCountInLib;
} NetNode_t;
+class CurrentQPEUser {
+
+public :
+ CurrentQPEUser() : UserName(), HomeDir(), EnvList() {}
+
+ QString UserName;
+ QString HomeDir;
+ int Uid;
+ int Gid;
+ QArray<char *> EnvList;
+};
+
typedef QDict<NetNode_t> Name2NetNode_t;
typedef QDict<ANetNodeInstance > Name2Instance_t;
typedef QDict<NodeCollection> Name2Connection_t;
typedef QDict<SystemFile> Name2SystemFile_t;
class TheNSResources {
public :
TheNSResources( void );
~TheNSResources( );
System & system()
{ return *TheSystem; }
QPixmap getPixmap( const QString & Name );
Name2NetNode_t & netNodes( void )
{ return AllNodeTypes; }
bool netNodeExists( const QString & X )
{ return AllNodeTypes.find(X)!=0; }
Name2SystemFile_t & systemFiles( void )
{ return SystemFiles; }
void addSystemFile( SystemFile * SF )
{ SystemFiles.insert( SF->name(), SF ); }
ANetNodeInstance * createNodeInstance( const QString & S )
{ ANetNodeInstance * NNI = 0;
NetNode_t * NNT = AllNodeTypes[S];
ANetNode * NN;
if( ! NNT ) {
NN = FakeNode =
( FakeNode ) ? FakeNode : new FakeNetNode();
} else {
NN = NNT->NetNode;
}
NNI = NN->createInstance();
NNI->initialize();
return NNI;
}
Name2Instance_t & netNodeInstances( void )
{ return AllNodes; }
void addNodeInstance( ANetNodeInstance * I )
{ AllNodes.insert( I->nodeName(), I ); }
void removeNodeInstance( const QString & N )
{ AllNodes.remove( N );}
ANetNodeInstance * findNodeInstance( const QString & S )
{ return (AllNodes.find(S)!=0) ? AllNodes[S] : 0; }
const QString & netNode2Name( const char * Type );
const QString & netNode2Description( const char * Type );
void renumberConnections( void );
void addConnection( NodeCollection * NC );
void removeConnection( const QString & N );
NodeCollection * findConnection( const QString & N );
Name2Connection_t & connections( void )
{ return ConnectionsMap; }
+ CurrentQPEUser & currentUser( void )
+ { return CurrentUser; }
+
private :
+ void detectCurrentUser( void );
QString tr( const char * path );
void findAvailableNetNodes( const QString &path );
bool loadNetNode(
const QString &pluginFileName,
const QString &resolveString = "create_plugin");
QMap< QString, QString> NodeTypeNameMap;
QMap< QString, QString> NodeTypeDescriptionMap;
Name2Connection_t ConnectionsMap;
System * TheSystem;
Name2SystemFile_t SystemFiles;
// all node type classes
Name2NetNode_t AllNodeTypes;
// all nodes
Name2Instance_t AllNodes;
+
+ CurrentQPEUser CurrentUser;
};
extern TheNSResources * _NSResources;
#define NSResources _NSResources
#endif
diff --git a/noncore/settings/networksettings2/networksettings2/system.cpp b/noncore/settings/networksettings2/networksettings2/system.cpp
index a68f3c0..2133d34 100644
--- a/noncore/settings/networksettings2/networksettings2/system.cpp
+++ b/noncore/settings/networksettings2/networksettings2/system.cpp
@@ -1,320 +1,355 @@
-#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <qfile.h>
-#include <qtextstream.h>
+
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <qdir.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <qfile.h>
+#include <qtextstream.h>
#include "resources.h"
#include "system.h"
#define PROCNETDEV "/proc/net/dev"
static char Dig2Hex[] = {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'C', 'D', 'E', 'F'
};
// get HIGH nibble of byte
#define HN(x) Dig2Hex[(((x)&0xf0)>>4)]
// get LOW nibble of byte
#define LN(x) Dig2Hex[((x)&0x0f)]
System::System( void ) : ProbedInterfaces() {
probeInterfaces();
}
System::~System( void ) {
if( ProcDevNet )
delete ProcDevNet;
}
-int System::execute( const QString & S ) {
+int System::runAsRoot( const QString & S ) {
QString MyS = S;
char * usr = getenv("USER");
int rv;
if( S.isEmpty() ) {
// loophole to start shell
return 8888;
}
if( usr == 0 || strcmp( usr, "root" ) ) {
// unknown or non-root user -> use SUDO
MyS.prepend( "sudo " );
}
fprintf( stderr, "Executing %s\n", MyS.latin1() );
rv = system( MyS.latin1() ) ;
switch( rv ) {
case -1 :
// cannot fork
return 1;
case 127 :
// cannot start shell
return 2;
default :
if( WEXITSTATUS(rv) != 0 ) {
// error in command
return 3;
}
}
// all is fine
return 0;
}
void System::refreshStatistics( InterfaceInfo & I ) {
if( ! ProcDevNet ) {
return;
}
// cannot seek on dev
ProcDevNet->close();
ProcDevNet->open( IO_ReadOnly );
QString line;
QTextStream procTs(ProcDevNet);
QStringList SL;
int loc = -1;
int version;
procTs.readLine();
line = procTs.readLine();
// get version
if( line.find("compressed") )
version = 3;
else if( line.find( "bytes" ) )
version = 2;
else
version = 1;
while((line = procTs.readLine().simplifyWhiteSpace()) != QString::null) {
if( (loc = line.find(":") ) == -1) {
continue;
}
if( I.Name != line.left(loc) )
continue;
// tokenize
SL = QStringList::split( ' ', line, FALSE );
// update data
switch( version ) {
case 1 :
I.RcvBytes = SL[1];
I.RcvErrors = SL[3];
I.RcvDropped = SL[4];
I.SndBytes = SL[6];
I.SndErrors = SL[8];
I.SndDropped = SL[9];
I.Collisions = SL[11];
break;
case 2 :
I.RcvBytes = SL[1];
I.RcvErrors = SL[3];
I.RcvDropped = SL[4];
I.SndBytes = SL[7];
I.SndErrors = SL[9];
I.SndDropped = SL[10];
I.Collisions = SL[12];
break;
case 3 :
I.RcvBytes = SL[1];
I.RcvErrors = SL[3];
I.RcvDropped = SL[4];
I.SndBytes = SL[9];
I.SndErrors = SL[11];
I.SndDropped = SL[12];
I.Collisions = SL[14];
break;
}
break;
}
}
//
// THIS UPDATES THE LIST -> INTERFACES ARE NOT DELETED BUT
// FLAGGED AS ! 'IsUp' IF NO LONGER PRESENT
//
void System::probeInterfaces( void ) {
// probe interfaces
int sockfd;
// get list of all interfaces
struct ifreq ifrs;
InterfaceInfo * IFI;
// flag all as 'down'
for( QDictIterator<InterfaceInfo> it( ProbedInterfaces );
it.current();
++it ) {
it.current()->IsUp = 0;
}
sockfd = socket(PF_INET, SOCK_DGRAM, 0);
if(sockfd == -1)
return;
// read interfaces from /proc/dev/net
// SIOCGIFCONF does not return ALL interfaces ???!?
ProcDevNet = new QFile(PROCNETDEV);
if( ! ProcDevNet->open(IO_ReadOnly) ) {
delete ProcDevNet;
ProcDevNet =0;
return;
}
QString line;
QString NicName;
QTextStream procTs(ProcDevNet);
int loc = -1;
procTs.readLine(); // eat a line
procTs.readLine(); // eat a line
while((line = procTs.readLine().simplifyWhiteSpace()) != QString::null) {
if((loc = line.find(":")) == -1) {
continue;
}
NicName = line.left(loc);
// set name for ioctl
strcpy( ifrs.ifr_name, NicName.latin1() );
if ( ! ( IFI = ProbedInterfaces.find( NicName ) ) ) {
// new nic
fprintf( stderr, "NEWNIC %s\n", NicName.latin1());
IFI = new InterfaceInfo;
IFI->Name = line.left(loc);
IFI->NetNode = 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 {
IFI->IsPointToPoint = 0;
}
// settings that never change
IFI->DstAddress = "";
if( IFI->IsPointToPoint ) {
if( ioctl(sockfd, SIOCGIFDSTADDR, &ifrs) >= 0 ) {
IFI->DstAddress =
inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_dstaddr)->sin_addr);
}
}
IFI->CardType = 999999;
IFI->MACAddress = "";
if( ioctl(sockfd, SIOCGIFHWADDR, &ifrs) >= 0 ) {
fprintf( stderr, "%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
// length = 6 bytes = 12 DIGITS -> 6 :
IFI->MACAddress.sprintf(
"%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
HN( ifrs.ifr_hwaddr.sa_data[0] ),
LN( ifrs.ifr_hwaddr.sa_data[0] ),
HN( ifrs.ifr_hwaddr.sa_data[1] ),
LN( ifrs.ifr_hwaddr.sa_data[1] ),
HN( ifrs.ifr_hwaddr.sa_data[2] ),
LN( ifrs.ifr_hwaddr.sa_data[2] ),
HN( ifrs.ifr_hwaddr.sa_data[3] ),
LN( ifrs.ifr_hwaddr.sa_data[3] ),
HN( ifrs.ifr_hwaddr.sa_data[4] ),
LN( ifrs.ifr_hwaddr.sa_data[4] ),
HN( ifrs.ifr_hwaddr.sa_data[5] ),
LN( ifrs.ifr_hwaddr.sa_data[5] )
);
break;
#ifdef ARPHRD_IEEE1394
case ARPHRD_IEEE1394 : // Firewire Eth address
IFI->MACAddress.sprintf(
"%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-00-00",
HN( ifrs.ifr_hwaddr.sa_data[0] ),
LN( ifrs.ifr_hwaddr.sa_data[0] ),
HN( ifrs.ifr_hwaddr.sa_data[1] ),
LN( ifrs.ifr_hwaddr.sa_data[1] ),
HN( ifrs.ifr_hwaddr.sa_data[2] ),
LN( ifrs.ifr_hwaddr.sa_data[2] ),
HN( ifrs.ifr_hwaddr.sa_data[3] ),
LN( ifrs.ifr_hwaddr.sa_data[3] ),
HN( ifrs.ifr_hwaddr.sa_data[4] ),
LN( ifrs.ifr_hwaddr.sa_data[4] ),
HN( ifrs.ifr_hwaddr.sa_data[5] ),
LN( ifrs.ifr_hwaddr.sa_data[5] ),
HN( ifrs.ifr_hwaddr.sa_data[6] ),
LN( ifrs.ifr_hwaddr.sa_data[6] ),
HN( ifrs.ifr_hwaddr.sa_data[7] ),
LN( ifrs.ifr_hwaddr.sa_data[7] ),
HN( ifrs.ifr_hwaddr.sa_data[8] ),
LN( ifrs.ifr_hwaddr.sa_data[8] ),
HN( ifrs.ifr_hwaddr.sa_data[9] ),
LN( ifrs.ifr_hwaddr.sa_data[9] ),
HN( ifrs.ifr_hwaddr.sa_data[10] ),
LN( ifrs.ifr_hwaddr.sa_data[10] ),
HN( ifrs.ifr_hwaddr.sa_data[11] ),
LN( ifrs.ifr_hwaddr.sa_data[11] ),
HN( ifrs.ifr_hwaddr.sa_data[12] ),
LN( ifrs.ifr_hwaddr.sa_data[12] ),
HN( ifrs.ifr_hwaddr.sa_data[13] ),
LN( ifrs.ifr_hwaddr.sa_data[13] )
);
break;
#endif
case ARPHRD_PPP : // PPP
break;
case ARPHRD_IEEE80211 : // WLAN
break;
case ARPHRD_IRDA : // IRDA
break;
}
}
} else // else already probed before -> just update
fprintf( stderr, "OLDNIC %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 {
IFI->IsUp = 0;
IFI->HasMulticast = 0;
}
if( ioctl(sockfd, SIOCGIFADDR, &ifrs) >= 0 ) {
IFI->Address =
inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_addr)->sin_addr);
} else {
IFI->Address = "";
IFI->IsUp = 0;
}
if( ioctl(sockfd, SIOCGIFBRDADDR, &ifrs) >= 0 ) {
IFI->BCastAddress =
inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_broadaddr)->sin_addr);
} else {
IFI->BCastAddress = "";
}
if( ioctl(sockfd, SIOCGIFNETMASK, &ifrs) >= 0 ) {
IFI->Netmask =
inet_ntoa(((struct sockaddr_in*)&ifrs.ifr_netmask)->sin_addr);
} else {
IFI->Netmask = "";
}
fprintf( stderr, "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
+ fprintf( stderr, "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) );
+
+ for( unsigned int i = 0 ; i < CU.EnvList.count() ; i ++ ) {
+ *(envp+i) = CU.EnvList[i];
+ }
+ envp[CU.EnvList.count()]=NULL;
+
+ execve( Cmd.latin1(), argv, envp );
+
+ // if we come here, the exec was not successfull
+ fprintf( stderr, "Could not exec : %d\n", errno );
+}
diff --git a/noncore/settings/networksettings2/networksettings2/system.h b/noncore/settings/networksettings2/networksettings2/system.h
index f89fe5d..96ee9bd 100644
--- a/noncore/settings/networksettings2/networksettings2/system.h
+++ b/noncore/settings/networksettings2/networksettings2/system.h
@@ -1,76 +1,81 @@
#ifndef __SYSTEM__H
#define __SYSTEM__H
// for hardware types
#include <net/if_arp.h>
#include <qdict.h>
class ANetNodeInstance;
class QFile;
class InterfaceInfo {
public :
InterfaceInfo() :
Name(),
MACAddress(),
BCastAddress(),
Netmask(),
DstAddress() {
}
ANetNodeInstance * assignedNode()
{ return NetNode; }
void assignNode( ANetNodeInstance * NNI )
{ NetNode = NNI; }
ANetNodeInstance * NetNode; // netnode 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
QString DstAddress; // Peer address (if P-t-P)
bool IsUp; // interface is UP
bool HasMulticast; // Supports Multicast
bool IsPointToPoint; // IsPointToPoint card
QString RcvBytes;
QString SndBytes;
QString RcvErrors;
QString SndErrors;
QString RcvDropped;
QString SndDropped;
QString Collisions;
};
class System {
public :
System( void );
~System( void );
QDict<InterfaceInfo> & interfaces( void )
{ return ProbedInterfaces; }
InterfaceInfo * interface( const QString& N )
{ return ProbedInterfaces[N]; }
- int execute( const QString & S );
+ // exec command as root
+ int runAsRoot( const QString & S );
+
+ // exec command as user
+ void execAsUser( QString & Cmd, char * argv[] );
+
// refresh stats for this interface
void refreshStatistics( InterfaceInfo & );
// reloads interfaces
void probeInterfaces( void );
private :
QDict<InterfaceInfo> ProbedInterfaces;
QFile * ProcDevNet;
};
#endif
diff --git a/noncore/settings/networksettings2/nsdata.cpp b/noncore/settings/networksettings2/nsdata.cpp
index eb63e02..b4d9aaa 100644
--- a/noncore/settings/networksettings2/nsdata.cpp
+++ b/noncore/settings/networksettings2/nsdata.cpp
@@ -1,540 +1,544 @@
#include <stdlib.h>
#include <qpe/qpeapplication.h>
#include <qtextstream.h>
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
#include "nsdata.h"
#include <asdevice.h>
#include <resources.h>
static QString CfgFile;
NetworkSettingsData::NetworkSettingsData( void ) {
// init global resources structure
new TheNSResources();
- CfgFile.sprintf( "%s/NETCONFIG", getenv("HOME") );
+ CfgFile.sprintf( "%s/NETCONFIG",
+ NSResources->currentUser().HomeDir.latin1() );
+ fprintf( stderr, "Cfg from %s\n", CfgFile.latin1() );
// load settings
Force = 0;
IsModified = 0;
loadSettings();
}
// saving is done by caller
NetworkSettingsData::~NetworkSettingsData( void ) {
delete NSResources;
}
void NetworkSettingsData::loadSettings( void ) {
QString S;
ANetNodeInstance* NNI;
QString Attr, Value;
long idx;
QFile F( CfgFile );
QTextStream TS( &F );
do {
if( ! F.open(IO_ReadOnly) )
break;
/* load the file ->
FORMAT :
[NETNODETYPE]
Entries ...
<EMPTYLINE>
[connection]
Name=Name
Node=Name
<EMPTYLINE>
*/
while( ! TS.atEnd() ) {
S = TS.readLine();
if ( S.isEmpty() || S[0] != '[' )
continue;
S = S.mid( 1, S.length()-2 );
if( ! NSResources ) {
continue;
}
if( S == "connection" ) {
// load connections -> collections of nodes
NodeCollection * NC = new NodeCollection( TS );
NSResources->addConnection( NC );
} else {
// load nodes
NNI = NSResources->createNodeInstance( S );
if( ! NNI ) {
printf( "SKIPPING %s\n", S.latin1() );
}
do {
S = TS.readLine();
if( S.isEmpty() ) {
// empty line
break;
}
// node found ?
if( NNI ) {
idx = S.find( '=' );
if( idx > 0 ) {
Attr = S.left( idx );
Value = S.mid( idx+1, S.length() );
} else {
Value="";
Attr = S;
}
Value.stripWhiteSpace();
Attr.stripWhiteSpace();
Attr.lower();
// dequote Attr
Value = deQuote(Value);
// set the attribute
NNI->setAttribute( Attr, Value );
}
} while( 1 );
if( NNI ) {
// loading from file -> exists
NNI->setNew( FALSE );
NSResources->addNodeInstance( NNI );
}
}
}
} while( 0 );
}
QString NetworkSettingsData::saveSettings( void ) {
QString ErrS = "";
if( ! isModified() )
return ErrS;
QString S;
QFile F( CfgFile + ".bup" );
printf( "Saving settings to %s\n", CfgFile.latin1() );
if( ! F.open( IO_WriteOnly | IO_Truncate ) ) {
ErrS = qApp->translate( "NetworkSettings",
"<p>Could not save setup to \"%1\" !</p>" ).
arg(CfgFile);
// problem
return ErrS;
}
QTextStream TS( &F );
{ Name2Connection_t & M = NSResources->connections();
ANetNodeInstance * NNI;
// for all connections
for( QDictIterator<NodeCollection> it(M);
it.current();
++it ) {
// all nodes in those connections
for( QListIterator<ANetNodeInstance> nit(*(it.current()));
nit.current();
++nit ) {
// header
NNI = nit.current();
TS << '[' <<NNI->nodeClass()->nodeName() << ']' << endl;
NNI->saveAttributes( TS );
TS << endl;
}
TS << "[connection]" << endl;
it.current()->save(TS);
}
}
QDir D(".");
D.rename( CfgFile + ".bup", CfgFile );
//
// proper files AND system files regenerated
//
setModified( 0 );
return ErrS;
}
QString NetworkSettingsData::generateSettings( bool ForceReq ) {
bool ForceIt;
QString S = "";
// include own force flag
ForceIt = (Force) ? 1 : ForceReq;
if( ! ForceIt && ! isModified() )
return S;
// regenerate system files
fprintf( stderr, "Generating settings from %s\n", CfgFile.latin1() );
{ Name2SystemFile_t & SFM = NSResources->systemFiles();
Name2Connection_t & M = NSResources->connections();
NodeCollection * NC;
ANetNodeInstance * NNI;
SystemFile * SF;
AsDevice * CurDev;
ANetNode * CurDevNN;
bool needToRegenerate = ForceIt;
//
// check if we need to generate at least one of the system files
//
if( ! ForceIt ) {
for( QDictIterator<SystemFile> sfit(SFM);
sfit.current();
++sfit ) {
SF = sfit.current();
// check if there are nodes that are modified and require
// data for this system file
// for all connections
for( QDictIterator<NodeCollection> ncit(M);
ncit.current();
++ncit ) {
NC = ncit.current();
if( NC->isModified() ) {
// does this connection 'touch' this system file ?
for( QListIterator<ANetNodeInstance> cncit(*NC);
cncit.current();
++cncit ) {
NNI = cncit.current();
if( ( NNI->nodeClass()->hasDataFor( SF->name() ) ||
NNI->hasDataFor( SF->name() )
) &&
NNI->isModified() ) {
needToRegenerate = 1;
break;
}
}
}
if( needToRegenerate )
break;
}
if( needToRegenerate )
break;
}
}
// we cannot renumber with a FORCE request since
// we probably are NOT going to save the config
// e.g. when using --regen option
if( ! ForceReq && needToRegenerate ) {
NSResources->renumberConnections();
setModified(1);
}
//
// generate files proper to each netnodeinstance
//
{ Name2Instance_t & NNIs = NSResources->netNodeInstances();
for( QDictIterator<ANetNodeInstance> NNIIt(NNIs);
NNIIt.current();
++NNIIt
){
// for all nodes find those that are modified
NNI = NNIIt.current();
if( ForceIt || NNI->isModified() ) {
if( ! NNI->nodeClass()->generateProperFilesFor( NNI ) ) {
// problem generating
S = qApp->translate( "NetworkSettings",
"<p>Cannot generate files proper to \"%1\"</p>" ).
arg(NNI->nodeClass()->nodeName()) ;
return S;
}
}
}
}
//
// generate all system files
//
for( QDictIterator<SystemFile> sfit(SFM);
sfit.current();
++sfit ) {
SF = sfit.current();
fprintf( stderr, "Generating %s\n", SF->name().latin1() );
SF->open();
do { // so we can break;
// global presection for this system file
if( SF->preSection() ) {
S = qApp->translate( "NetworkSettings",
"<p>Error in preSection for file \"%1\"</p>" ).
arg( SF->name() );
return S;
}
// find all netnodes and figure out if
// for that node there are instances
for( QDictIterator<NetNode_t> nnit(
NSResources->netNodes() );
nnit.current();
++nnit ) {
CurDevNN = nnit.current()->NetNode;
// are there instances for this netnode ?
NNI = 0;
for( QDictIterator<ANetNodeInstance> nniit(
NSResources->netNodeInstances() );
nniit.current();
++nniit ) {
if( nniit.current()->nodeClass() == CurDevNN ) {
NNI = nniit.current();
break;
}
}
if( ! NNI )
// no instances -> next netnode type
continue;
// has this node data for this system file ?
if( (CurDev = NNI->runtime()->asDevice() ) ) {
// generate start for this nodetype for all possible devices of this type
for( int i = 0; i < CurDevNN->instanceCount(); i ++ ) {
S = generateSystemFileNode( *SF, CurDev, NNI, i );
if( ! S.isEmpty() )
return S;
}
} else {
S = generateSystemFileNode( *SF, 0, NNI, -1 );
if( ! S.isEmpty() )
return S;
}
}
if( SF->postSection() ) {
S = qApp->translate( "NetworkSettings",
"<p>Error in postSection for file \"%1\"</p>" ).
arg( SF->name() );
return S;
}
} while( 0 );
SF->close();
}
}
Force = 0;
return S;
}
QList<NodeCollection> NetworkSettingsData::collectPossible( const char * Interface ) {
// collect connections that can work on top of this interface
NodeCollection * NC;
QList<NodeCollection> PossibleConnections;
Name2Connection_t & M = NSResources->connections();
// for all connections
for( QDictIterator<NodeCollection> it(M);
it.current();
++it ) {
NC = it.current();
// check if this profile handles the requested interface
+ fprintf( stderr, "check %s\n", NC->name().latin1() );
if( NC->handlesInterface( Interface ) && // if different Intf.
NC->state() != Disabled && // if not enabled
NC->state() != IsUp // if already used
) {
+ fprintf( stderr, "Append %s\n", NC->name().latin1() );
PossibleConnections.append( NC );
}
}
return PossibleConnections;
}
/*
Called by the system to see if interface can be brought UP
if allowed, echo Interface-allowed else Interface-disallowed
*/
-void NetworkSettingsData::canStart( const char * Interface ) {
+bool NetworkSettingsData::canStart( const char * Interface ) {
// load situation
NodeCollection * NC = 0;
QList<NodeCollection> PossibleConnections;
PossibleConnections = collectPossible( Interface );
+ fprintf( stderr, "Possiblilies %d\n",
+ PossibleConnections.count() );
switch( PossibleConnections.count() ) {
case 0 : // no connections
break;
case 1 : // one connection
NC = PossibleConnections.first();
break;
default : // need to ask user ?
- // are we connected to a server
- // system( "su %d networksettings2 --prompt %s\n",
- // "", Interface );
- break;
+ return 1;
}
if( NC ) {
switch( NC->state() ) {
case Unchecked :
case Unknown :
case Unavailable :
case Disabled :
// this profile does not allow interface to be UP
// -> try others
break;
case Off :
// try to UP the device
if( ! NC->setState( Activate ) ) {
// cannot bring device Online -> try other alters
break;
}
// FT
case Available :
case IsUp : // also called for 'ifdown'
// device is ready -> done
printf( "%s-c%d-allowed\n", Interface, NC->number() );
- return;
+ return 0;
}
- } else {
- // if we come here no alternatives are possible
- printf( "%s-cnn-disallowed\n", Interface );
- }
+ }
+
+ // if we come here no alternatives are possible
+ printf( "%s-cnn-disallowed\n", Interface );
+ return 0;
}
/*
Called by the system to regenerate config files
*/
bool NetworkSettingsData::regenerate( void ) {
QString S;
// load situation
S = generateSettings( TRUE );
if( ! S.isEmpty() ) {
fprintf( stdout, "%s\n", S.latin1() );
return 1;
}
return 0;
}
QString NetworkSettingsData::generateSystemFileNode(
SystemFile &SF,
AsDevice * CurDev,
ANetNodeInstance * DevNNI,
long DevInstNr ) {
QString S="";
ANetNode * CurDevNN = DevNNI->nodeClass();
Name2Connection_t & M = NSResources->connections();
if( SF.preDeviceSection( CurDevNN ) ) {
S = qApp->translate( "NetworkSettings",
"<p>Error in preDeviceSection for file \"%1\" and nodetype \"%2\"</p>" ).
arg( SF.name() ).
arg( CurDevNN->nodeName() );
return S;
}
if( CurDevNN->hasDataFor( SF.name() ) ) {
if( CurDevNN->generateDeviceDataForCommonFile( SF, DevInstNr ) ) {
S = qApp->translate( "NetworkSettings",
"<p>Error in node Device part for file \"%1\" and node \"%2\"</p>" ).
arg( SF.name() ).
arg( CurDevNN->nodeName() );
return S;
}
}
if( CurDev )
fprintf( stderr, "Cur %s\n", CurDevNN->nodeName().latin1() );
else
fprintf( stderr, "Cur NO\n" );
// now generate profile specific data for all
// connections working on a device of the current
// netnode type
for( QDictIterator<NodeCollection> ncit(M);
ncit.current();
++ncit ) {
NodeCollection * NC = ncit.current();
// currenly only those connections that work on
// the current device (or on no device if no current)
AsDevice * Dev = NC->device();
fprintf( stderr, "%s\n", Dev->netNode()->nodeName().latin1() );
if( CurDev ) {
if( CurDevNN != Dev->netNode()->nodeClass() ) {
// other device type -> later
fprintf( stderr, "Other Dev type\n" );
continue;
}
} else {
if( Dev ) {
// other
continue;
}
}
// generate 'entry'
if( SF.preNodeSection( DevNNI, DevInstNr ) ) {
S = qApp->translate( "NetworkSettings",
"<p>Error in preNodeSection for file \"%1\" and node \"%2\"</p>" ).
arg( SF.name() ).
arg( CurDevNN->nodeName() );
return S;
}
// ask all nodes in connection
for( QListIterator<ANetNodeInstance> cncit(*NC);
cncit.current();
++cncit ) {
ANetNodeInstance * NNI = cncit.current();
if( NNI->hasDataFor( SF.name() ) ) {
if( NNI->generateDataForCommonFile(SF,DevInstNr) ) {
S = qApp->translate( "NetworkSettings",
"<p>Error in node part for file \"%1\" and node \"%2\"</p>" ).
arg( SF.name() ).
arg( NNI->nodeClass()->nodeName() );
return S;
}
}
}
if( SF.postNodeSection( DevNNI, DevInstNr ) ) {
S = qApp->translate( "NetworkSettings",
"<p>Error in postNodeSection for file \"%1\" and node \"%2\"</p>" ).
arg( SF.name() ).
arg( CurDevNN->nodeName() );
return S;
}
SF << endl;
}
if( SF.postDeviceSection( CurDevNN ) ) {
S = qApp->translate( "NetworkSettings",
"<p>Error in postDeviceSection for file \"%1\" and node \"%2\"</p>" ).
arg( SF.name() ).
arg( CurDevNN->nodeName() );
return S;
}
return S;
}
diff --git a/noncore/settings/networksettings2/nsdata.h b/noncore/settings/networksettings2/nsdata.h
index b54df24..eb96930 100644
--- a/noncore/settings/networksettings2/nsdata.h
+++ b/noncore/settings/networksettings2/nsdata.h
@@ -1,42 +1,43 @@
#ifndef __NSDATA_H
#define __NSDATA_H
#include "netnode.h"
class NetworkSettingsData {
public :
NetworkSettingsData( void );
~NetworkSettingsData( void );
void loadSettings( void );
QString saveSettings( void );
QString generateSettings( bool Force = FALSE );
bool isModified( void )
{ return IsModified; }
void setModified( bool m )
{ IsModified = m; }
QList<NodeCollection> collectPossible( const char * Interface );
- void canStart( const char * Interface );
+ // return TRUE if we need gui to decide
+ bool canStart( const char * Interface );
bool regenerate( void );
void forceGeneration( bool m )
{ Force = m; }
private :
QString NetworkSettingsData::generateSystemFileNode(
SystemFile & SF,
AsDevice * CurDev,
ANetNodeInstance * DevNNI,
long DevInstNr );
bool IsModified;
bool Force;
};
#endif