00001 #include <unistd.h>
00002 #include <errno.h>
00003 #include <fcntl.h>
00004 #include <pwd.h>
00005 #include <qpixmap.h>
00006 #include <qdir.h>
00007 #include <qmessagebox.h>
00008
00009 #include <qpe/qlibrary.h>
00010 #include <qpe/qpeapplication.h>
00011
00012 #include <opie2/odebug.h>
00013 #include <opie2/opluginloader.h>
00014
00015 #include <qtopia/resource.h>
00016
00017 #include "netnode.h"
00018 #include "resources.h"
00019 #include "netnodeinterface.h"
00020
00021 #define PLUGINDIR "plugins/networksettings2"
00022 #define ICONDIR "/pics/networksettings2/"
00023
00024
00025 TheNSResources * _NSResources = 0;
00026
00027 TheNSResources::TheNSResources( void ) : NodeTypeNameMap(),
00028 NetworkSetupsMap(), DanglingNetworkSetupsMap() {
00029
00030 _NSResources = this;
00031
00032 detectCurrentUser();
00033
00034
00035
00036 Plugins = 0;
00037 findAvailableNetNodes();
00038
00039
00040 { const char ** NeedsRun;
00041 QDictIterator<ANetNode> OuterIt( AllNodeTypes );
00042 bool Done;
00043
00044 for ( ; OuterIt.current(); ++OuterIt ) {
00045
00046 ANetNode::NetNodeList * NNLP = new ANetNode::NetNodeList;
00047 ANetNode::NetNodeList & NNL = *(NNLP);
00048
00049
00050 for ( QDictIterator<ANetNode> InnerIt( AllNodeTypes );
00051 InnerIt.current(); ++InnerIt ) {
00052
00053 if( InnerIt.current() == OuterIt.current() )
00054
00055 continue;
00056
00057 const char ** Provides = InnerIt.current()->provides();
00058 NeedsRun = OuterIt.current()->needs();
00059
00060 for( ; *NeedsRun; NeedsRun ++ ) {
00061 const char ** PRun;
00062 PRun = Provides;
00063 for( ; *PRun; PRun ++ ) {
00064 if( strcmp( *PRun, *NeedsRun ) == 0 ) {
00065
00066 NNL.resize( NNL.size() + 1 );
00067 NNL[NNL.size()-1] = InnerIt.current();
00068 Done = 1;
00069 break;
00070 }
00071 }
00072 }
00073 }
00074 OuterIt.current()->setAlternatives( NNLP );
00075 }
00076 }
00077
00078
00079 addNodeType( "device", tr( "Network Device" ),
00080 tr( "<p>Devices that can handle IP packets</p>" ) );
00081 addNodeType( "line", tr( "Character device" ),
00082 tr( "<p>Devices that can handle single bytes</p>" ) );
00083 addNodeType( "connection", tr( "IP Connection" ),
00084 tr( "<p>Nodes that provide working IP connection</p>" ) );
00085 addNodeType( "fullsetup", tr( "Connection Profile" ),
00086 tr( "<p>Fully configured network profile</p>" ) );
00087 addNodeType( "GPRS", tr( "Connection to GPRS device" ),
00088 tr( "<p>Connection to a GPRS capable device</p>" ) );
00089
00090
00091 TheSystem = new System();
00092
00093 }
00094
00095 TheNSResources::~TheNSResources( void ) {
00096
00097 if( Plugins ) {
00098 delete Plugins;
00099 delete PluginManager;
00100 }
00101 delete TheSystem;
00102
00103 }
00104
00105 void TheNSResources::addNodeType( const QString & ID,
00106 const QString & Name,
00107 const QString & Descr ) {
00108 if( NodeTypeNameMap[ID].isEmpty() ) {
00109 NodeTypeNameMap.insert( ID, Name );
00110 NodeTypeDescriptionMap.insert( ID, Descr );
00111 }
00112 }
00113
00114 void TheNSResources::addSystemFile( const QString & ID,
00115 const QString & P,
00116 bool KDI ) {
00117 if( ! SystemFiles.find( ID ) ) {
00118
00119 SystemFiles.insert( ID, new SystemFile( ID, P, KDI ) );
00120 }
00121 }
00122
00123 void TheNSResources::busy( bool ) {
00124
00125
00126
00127
00128
00129
00130
00131
00132 }
00133
00134 void TheNSResources::findAvailableNetNodes( void ){
00135
00136 Plugins = new OPluginLoader( "networksettings2" );
00137 Plugins->setAutoDelete( true );
00138
00139 PluginManager = new OPluginManager( Plugins );
00140 PluginManager->load();
00141
00142 if( Plugins->isInSafeMode() ) {
00143 QMessageBox::information(
00144 0,
00145 tr( "Today Error"),
00146 tr( "<qt>The plugin '%1' caused Today to crash."
00147 " It could be that the plugin is not properly"
00148 " installed.<br>Today tries to continue loading"
00149 " plugins.</qt>" )
00150 .arg( PluginManager->crashedPlugin().name()));
00151 }
00152
00153
00154 OPluginLoader::List allplugins = Plugins->filtered();
00155 QString lang = ::getenv("LANG");
00156
00157 for( OPluginLoader::List::Iterator it = allplugins.begin();
00158 it != allplugins.end();
00159 ++it ) {
00160
00161
00162 NetNodeInterface * interface =
00163 Plugins->load<NetNodeInterface>( *it, IID_NetworkSettings2 );
00164
00165 if( ! interface ) {
00166 Log(( "Plugin %s from %s does not support proper interface\n",
00167 (*it).name().latin1(), (*it).path().latin1() ));
00168 continue;
00169 }
00170
00171
00172 { QList<ANetNode> PNN;
00173
00174 interface->create_plugin( PNN );
00175
00176 if( PNN.isEmpty() ) {
00177 Log(( "Plugin %s from %s does offer any nodes\n",
00178 (*it).name().latin1(), (*it).path().latin1() ));
00179 delete interface;
00180 continue;
00181 }
00182
00183
00184 for( QListIterator<ANetNode> nnit(PNN);
00185 nnit.current();
00186 ++nnit ) {
00187 Log(( "Found node type %s in plugin %s\n",
00188 nnit.current()->name(), (*it).name().latin1() ));
00189 AllNodeTypes.insert( nnit.current()->name(), nnit.current() );
00190 }
00191 }
00192
00193
00194 QTranslator *trans = new QTranslator(qApp);
00195 QString fn = QPEApplication::qpeDir()+
00196 "/i18n/"+lang+"/"+ (*it).name() + ".qm";
00197
00198 if( trans->load( fn ) )
00199 qApp->installTranslator( trans );
00200 else
00201 delete trans;
00202 }
00203
00204 }
00205
00206
00207 int TheNSResources::assignNetworkSetupNumber( void ) {
00208 bool found = 1;
00209 for( int trial = 0; ; trial ++ ) {
00210 found = 1;
00211 for( QDictIterator<NetworkSetup> it(NetworkSetupsMap);
00212 it.current();
00213 ++it ) {
00214 if( it.current()->number() == trial ) {
00215 found = 0;
00216 break;
00217 }
00218 }
00219
00220 if( found ) {
00221 Log(("Assign profile number %d\n", trial ));
00222 return trial;
00223 }
00224 }
00225 }
00226
00227 QPixmap TheNSResources::getPixmap( const QString & QS ) {
00228 QPixmap P;
00229 QString S("networksettings2/");
00230 S += QS;
00231 P = Resource::loadPixmap( S );
00232 if( P.isNull() ) {
00233 Log(( "Cannot load %s\n", S.latin1() ));
00234 }
00235 return ( P.isNull() ) ? QPixmap() : P;
00236 }
00237
00238 QString TheNSResources::tr( const char * s ) {
00239 return qApp->translate( "resource", s );
00240 }
00241
00242 const QString & TheNSResources::netNode2Name( const char * s ) {
00243 return NodeTypeNameMap[s];
00244 }
00245
00246 const QString & TheNSResources::netNode2Description( const char * s ) {
00247 return NodeTypeDescriptionMap[s];
00248 }
00249
00250 void TheNSResources::addNetworkSetup( NetworkSetup * NC, bool Dangling ) {
00251 ANetNodeInstance * NNI;
00252 Log(( "Add NetworkSetup %s, Dangling %d\n",
00253 NC->name().latin1(), Dangling ));
00254 if( Dangling ) {
00255 DanglingNetworkSetupsMap.insert( NC->name(), NC );
00256 } else {
00257 NetworkSetupsMap.insert( NC->name(), NC );
00258 }
00259
00260
00261 for( QListIterator<ANetNodeInstance> it(*NC);
00262 it.current();
00263 ++it ) {
00264 NNI = it.current();
00265 if( findNodeInstance( NNI->name() ) == 0 ) {
00266
00267 addNodeInstance( NNI );
00268 }
00269 }
00270 }
00271
00272 void TheNSResources::removeNetworkSetup( const QString & N ) {
00273 NetworkSetup * NC = findNetworkSetup( N );
00274 if( ! NC )
00275 return;
00276
00277
00278 ANetNodeInstance * NNI;
00279 for( NNI = NC->first(); NNI != 0; NNI = NC->next() ) {
00280 removeNodeInstance( NNI->name() );
00281 }
00282 if( NetworkSetupsMap.find( N ) ) {
00283 NetworkSetupsMap.remove( N );
00284 } else {
00285 DanglingNetworkSetupsMap.remove( N );
00286 }
00287
00288 }
00289
00290
00291 NetworkSetup * TheNSResources::findNetworkSetup( const QString & S ) {
00292 return NetworkSetupsMap[ S ];
00293 }
00294
00295 NetworkSetup * TheNSResources::getNetworkSetup( int nr ) {
00296 for( QDictIterator<NetworkSetup> it(NetworkSetupsMap);
00297 it.current();
00298 ++it ) {
00299 if( it.current()->number() == nr ) {
00300 return it.current();
00301 }
00302 }
00303 return 0;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 typedef struct EnvVars {
00323 char * Name;
00324 int Len;
00325 } EnvVar_t;
00326
00327 #define AnEV(x) x, sizeof(x)-1
00328
00329 static EnvVar_t EV[] = {
00330 AnEV( "HOME" ),
00331 AnEV( "LOGNAME" ),
00332 AnEV( "USER" ),
00333 AnEV( "LD_LIBRARY_PATH" ),
00334 AnEV( "PATH" ),
00335 AnEV( "QTDIR" ),
00336 AnEV( "OPIEDIR" ),
00337 AnEV( "SHELL" ),
00338 { NULL, 0 }
00339 };
00340
00341 void TheNSResources::detectCurrentUser( void ) {
00342
00343 QString QPEEnvFile = "";
00344
00345 CurrentUser.UserName = "";
00346 CurrentUser.HomeDir = "";
00347
00348 if( getenv( "OPIEDIR" ) == 0 ) {
00349
00350 {
00351 QRegExp R("[0-9]+");
00352 QDir ProcDir( "/proc" );
00353 QFileInfo FI;
00354 QStringList EL = ProcDir.entryList( QDir::Dirs );
00355
00356
00357 for ( QStringList::Iterator it = EL.begin();
00358 it != EL.end();
00359 ++it ) {
00360 if( R.match( (*it) ) >= 0 ) {
00361 QString S = ProcDir.path()+"/"+ (*it);
00362 S.append( "/exe" );
00363 FI.setFile( S );
00364
00365 S = FI.readLink();
00366 if( S.right( 8 ) == "/bin/qpe" ) {
00367
00368 QPEEnvFile.sprintf( ProcDir.path()+ "/" + (*it) + "/environ" );
00369 break;
00370 }
00371 }
00372 }
00373 }
00374
00375 if( QPEEnvFile.isEmpty() ) {
00376
00377 Log(("Could not find qpe\n" ));
00378 return;
00379 }
00380
00381
00382 { char * Buf = 0;
00383 char TB[1024];
00384 long BufSize = 0;
00385 int fd;
00386 int rd;
00387
00388 fd = open( QPEEnvFile.latin1(), O_RDONLY );
00389 if( fd < 0 ) {
00390 Log(("Could not open %s : %d\n",
00391 QPEEnvFile.latin1(), errno ));
00392 return;
00393 }
00394
00395 while( (rd = read( fd, TB, sizeof(TB) ) ) > 0 ) {
00396 Buf = (char *)realloc( Buf, BufSize+rd );
00397 memcpy( Buf+BufSize, TB, rd );
00398 BufSize += rd;
00399 }
00400
00401 char * Data = Buf;
00402 char * DataEnd = Data+BufSize-1;
00403
00404
00405 while( Data < DataEnd ) {
00406
00407 EnvVar_t * Run = EV;
00408 while( Run->Name ) {
00409 if( strncmp( Data, Run->Name, Run->Len ) == 0 &&
00410 Data[Run->Len] == '='
00411 ) {
00412 CurrentUser.EnvList.resize( CurrentUser.EnvList.size()+1 );
00413 CurrentUser.EnvList[CurrentUser.EnvList.size()-1] =
00414 strdup( Data );
00415
00416 if( strcmp( Run->Name, "OPIEDIR" ) == 0 ) {
00417
00418 putenv( CurrentUser.EnvList[CurrentUser.EnvList.size()-1] );
00419 } else if( strcmp( Run->Name, "HOME" ) == 0 ) {
00420 CurrentUser.HomeDir = Data+5;
00421 } else if( strcmp( Run->Name, "LOGNAME" ) == 0 ) {
00422 CurrentUser.UserName = Data+8;
00423 }
00424 break;
00425 }
00426 Run ++;
00427 }
00428
00429 Data += strlen( Data )+1;
00430 }
00431
00432 free( Buf );
00433
00434 if( ! CurrentUser.UserName.isEmpty() ) {
00435
00436 struct passwd pwd;
00437 struct passwd * pwdres;
00438
00439 if( getpwnam_r( CurrentUser.UserName.latin1(),
00440 &pwd, TB, sizeof(TB), &pwdres ) ||
00441 pwdres == 0 ) {
00442 Log(("Could not determine user %s : %d\n",
00443 CurrentUser.UserName.latin1(), errno ));
00444 return;
00445 }
00446 CurrentUser.Uid = pwd.pw_uid;
00447 CurrentUser.Gid = pwd.pw_gid;
00448 } else{
00449 CurrentUser.Uid =
00450 CurrentUser.Gid = -1;
00451 }
00452 }
00453
00454 } else {
00455 char * X;
00456 QString S;
00457
00458 EnvVar_t * Run = EV;
00459 while( Run->Name ) {
00460
00461 if( ( X = getenv( Run->Name ) ) ) {
00462 Log(( "Env : %s = %s\n", Run->Name, X ));
00463
00464 S.sprintf( "%s=%s", Run->Name, X );
00465 CurrentUser.EnvList.resize( CurrentUser.EnvList.size()+1 );
00466 CurrentUser.EnvList[CurrentUser.EnvList.size()-1] =
00467 strdup( S.latin1() );
00468
00469 if( strcmp( Run->Name, "LOGNAME" ) == 0 ) {
00470 CurrentUser.UserName = X;
00471 } else if( strcmp( Run->Name, "HOME" ) == 0 ) {
00472 CurrentUser.HomeDir = X;
00473 }
00474 } else {
00475 Log(("Could not determine %s\n", Run->Name ));
00476 }
00477 Run ++;
00478 }
00479
00480 CurrentUser.Uid = getuid();
00481 CurrentUser.Gid = getgid();
00482 }
00483 }