Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

resources.cpp

Go to the documentation of this file.
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 // single resources instance
00025 TheNSResources * _NSResources = 0;
00026 
00027 TheNSResources::TheNSResources( void ) : NodeTypeNameMap(),
00028         NetworkSetupsMap(), DanglingNetworkSetupsMap() {
00029 
00030     _NSResources = this;
00031 
00032     detectCurrentUser();
00033 
00034     // load available netnodes
00035 
00036     Plugins = 0;
00037     findAvailableNetNodes();
00038 
00039     // compile provides and needs lists
00040     { const char ** NeedsRun;
00041       QDictIterator<ANetNode> OuterIt( AllNodeTypes );
00042       bool Done;
00043 
00044       for ( ; OuterIt.current(); ++OuterIt ) {
00045         // find needs list
00046         ANetNode::NetNodeList * NNLP = new ANetNode::NetNodeList;
00047         ANetNode::NetNodeList & NNL = *(NNLP);
00048 
00049         // must iterate this way to avoid duplication pointers
00050         for ( QDictIterator<ANetNode> InnerIt( AllNodeTypes );
00051               InnerIt.current(); ++InnerIt ) {
00052 
00053           if( InnerIt.current() == OuterIt.current() )
00054             // avoid recursive 
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                 // inner provides what outer needs
00066                 NNL.resize( NNL.size() + 1 );
00067                 NNL[NNL.size()-1] = InnerIt.current();
00068                 Done = 1; // break from 2 loops
00069                 break;
00070               }
00071             }
00072           }
00073         }
00074         OuterIt.current()->setAlternatives( NNLP );
00075       }
00076     }
00077 
00078     // define built in Node types to Description map
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     // get access to the system
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       // new system file
00119       SystemFiles.insert( ID, new SystemFile( ID, P, KDI ) ); 
00120     } // else existed
00121 }
00122 
00123 void TheNSResources::busy( bool ) {
00124 /*
00125       if( B ) {
00126         ShowWait->show();
00127         qApp->process
00128       } else {
00129         ShowWait->hide();
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     // Get All Plugins
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       // check if this plugin supports the proper interface
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       // add the nodes in this plugin to the dictionary
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         // merge this node with global node
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       // load the translation 
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 // used to find unique NetworkSetup number
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       // add (new) nodes to NodeList
00261       for( QListIterator<ANetNodeInstance> it(*NC);
00262            it.current();
00263            ++it ) {
00264         NNI = it.current();
00265         if( findNodeInstance( NNI->name() ) == 0 ) {
00266           // new item
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       // delete netnodes in this NetworkSetup
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 // dangling NetworkSetups are filtered out
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 void TheNSResources::renumberNetworkSetups( void ) {
00307       Name2NetworkSetup_t & M = NSResources->NetworkSetups();
00308       NetworkSetup * NC;
00309 
00310       // for all NetworkSetups
00311       NetworkSetup::resetMaxNr();
00312       for( QDictIterator<NetworkSetup> it(M);
00313            it.current();
00314            ++it ) {
00315         NC = it.current();
00316         NC->setNumber( NC->maxNetworkSetupNumber()+1 );
00317         NC->setModified( 1 );
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     // find current running qpe
00343     QString QPEEnvFile = "";
00344 
00345     CurrentUser.UserName = "";
00346     CurrentUser.HomeDir = "";
00347 
00348     if( getenv( "OPIEDIR" ) == 0 ) {
00349       // nothing known 
00350       { // open proc dir and find all dirs in it
00351         QRegExp R("[0-9]+");
00352         QDir ProcDir( "/proc" );
00353         QFileInfo FI;
00354         QStringList EL = ProcDir.entryList( QDir::Dirs );
00355 
00356         // print it out
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             // get the link
00365             S = FI.readLink();
00366             if( S.right( 8 ) == "/bin/qpe" ) {
00367               // found running qpe
00368               QPEEnvFile.sprintf( ProcDir.path()+ "/" + (*it) + "/environ" );
00369               break;
00370             }
00371           }
00372         }
00373       }
00374 
00375       if( QPEEnvFile.isEmpty() ) {
00376         // could not find qpe
00377         Log(("Could not find qpe\n" ));
00378         return;
00379       }
00380 
00381       // FI now contains path ProcDir to the cmd dir
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         // get env items out of list
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                 // put OPIEDIR in env
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           // find user info
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           } // regulare env var
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 }

Generated on Sat Nov 5 16:17:54 2005 for OPIE by  doxygen 1.4.2