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,35 +1,36 @@
#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 ++ ) {
@@ -47,65 +48,77 @@ int main( int argc, char * argv[] ) {
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;
}
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
@@ -80,81 +80,102 @@ void ANetwork::saveSpecificAttribute( QTextStream & TS ) {
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;
}
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,36 +1,40 @@
+#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 );
@@ -46,64 +50,66 @@ TheNSResources::TheNSResources( void ) : NodeTypeNameMap(),
// 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()+
@@ -203,32 +209,161 @@ void TheNSResources::addConnection( NodeCollection * NC ) {
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,71 +1,79 @@
-#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;
}
@@ -289,32 +297,59 @@ void System::probeInterfaces( void ) {
// 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
@@ -30,47 +30,52 @@ public :
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,50 +1,52 @@
#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 ...
@@ -324,127 +326,129 @@ QString NetworkSettingsData::generateSettings( bool ForceReq ) {
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() );
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