📄 kconfig.cpp
字号:
data()->aLocalAppFile.sprintf("%s/share/config/%s",KApplication::localkdedir().data(),tmp.data()); aConfigFile.close(); aConfigFile.setName(data()->aLocalAppFile.data()); aConfigFile.open(IO_ReadOnly); } parseOneConfigFile( aConfigFile, 0L, false ); aConfigFile.close(); }}bool KConfig::writeConfigFile( QFile& rConfigFile, bool bGlobal ){ bool bEntriesLeft = false; QTextStream* pStream = new QTextStream( &rConfigFile ); // create a temporary dictionary that represents the file to be written QDict<KEntryDict> aTempDict( 37, FALSE ); aTempDict.setAutoDelete( true ); // setup a group entry for the default group KEntryDict* pDefGroup = new KEntryDict( 37, false ); pDefGroup->setAutoDelete( true ); aTempDict.insert( "<default>", pDefGroup ); // fill the temporary structure with entries from the file parseOneConfigFile( rConfigFile, &aTempDict, bGlobal ); // augment this structure with the dirty entries from the normal structure QDictIterator<KEntryDict> aIt( data()->aGroupDict ); // loop over all the groups const char* pCurrentGroup; while( (pCurrentGroup = aIt.currentKey()) ) { QDictIterator<KEntryDictEntry> aInnerIt( *aIt.current() ); // loop over all the entries KEntryDictEntry* pCurrentEntry; while( (pCurrentEntry = aInnerIt.current()) ) { if( pCurrentEntry->bDirty ) { // only write back entries that have the same // "globality" as the file if( pCurrentEntry->bGlobal == bGlobal ) { // enter the // *aInnerIt.currentKey()/pCurrentEntry->aValue pair // into group *pCurrentGroup in aTempDict KEntryDict* pTempGroup; if( !( pTempGroup = aTempDict[ pCurrentGroup ] ) ) { // group does not exist in aTempDict pTempGroup = new KEntryDict( 37, false ); pTempGroup->setAutoDelete( true ); aTempDict.insert( pCurrentGroup, pTempGroup ); } KEntryDictEntry* pNewEntry = new KEntryDictEntry(); pNewEntry->aValue = pCurrentEntry->aValue; pNewEntry->bDirty = false; pNewEntry->bGlobal = pCurrentEntry->bGlobal; pNewEntry->bNLS = pCurrentEntry->bNLS; pTempGroup->replace( aInnerIt.currentKey(), pNewEntry ); } else // wrong "globality" - might have to be saved later bEntriesLeft = true; } ++aInnerIt; } ++aIt; } // truncate file delete pStream; rConfigFile.close(); /* Does program run SUID and user would not be allowed to write * to the file, if it doesn't run SUID? */ if( ! checkAccess( rConfigFile.name(), W_OK ) ) // write not allowed return false; // can't allow to write config data. rConfigFile.open( IO_Truncate | IO_WriteOnly ); // Set uid/gid (neccesary for SUID programs) chown(rConfigFile.name(), getuid(), getgid()); pStream = new QTextStream( &rConfigFile ); // write a magic cookie for Fritz' mime magic *pStream << "# KDE Config File\n"; // write back -- start with the default group KEntryDict* pDefWriteGroup = aTempDict[ "<default>" ]; if( pDefWriteGroup ) { QDictIterator<KEntryDictEntry> aWriteInnerIt( *pDefWriteGroup ); while( aWriteInnerIt.current() ) { if( aWriteInnerIt.current()->bNLS && QString( aWriteInnerIt.currentKey() ).right( 1 ) != "]" ) // not yet localized, but should be *pStream << aWriteInnerIt.currentKey() << '[' << data()->aLocaleString << ']' << "=" << stringToPrintable(aWriteInnerIt.current()->aValue) << '\n'; else // need not be localized or already is *pStream << aWriteInnerIt.currentKey() << "=" << stringToPrintable(aWriteInnerIt.current()->aValue) << '\n'; ++aWriteInnerIt; } } QDictIterator<KEntryDict> aWriteIt( aTempDict ); while( aWriteIt.current() ) { // check if it's not the default group (which has already been written) if( strcmp (aWriteIt.currentKey(), "<default>" ) ) { *pStream << '[' << aWriteIt.currentKey() << ']' << '\n'; QDictIterator<KEntryDictEntry> aWriteInnerIt( *aWriteIt.current() ); while( aWriteInnerIt.current() ) { if( aWriteInnerIt.current()->bNLS && QString( aWriteInnerIt.currentKey() ).right( 1 ) != "]" ) // not yet localized, but should be *pStream << aWriteInnerIt.currentKey() << '[' << data()->aLocaleString << ']' << "=" << stringToPrintable(aWriteInnerIt.current()->aValue) << '\n'; else // need not be localized or already is *pStream << aWriteInnerIt.currentKey() << "=" << stringToPrintable(aWriteInnerIt.current()->aValue) << '\n'; ++aWriteInnerIt; } } ++aWriteIt; } // clean up delete pStream; rConfigFile.close(); // Reopen the config file. // Can we allow the write? (see above) if( checkAccess( rConfigFile.name(), W_OK ) ) // Yes, write OK rConfigFile.open( IO_ReadWrite ); else rConfigFile.open( IO_ReadOnly ); return bEntriesLeft;}void KConfig::sync(){ // write-sync is only necessary if there are dirty entries if( data()->bDirty ) { bool bEntriesLeft = true; bool bLocalGood = false; // find out the file to write to (most specific writable file) // try local app-specific file first if( !data()->aLocalAppFile.isEmpty() ) { // Can we allow the write? We can, if the program // doesn't run SUID. But if it runs SUID, we must // check if the user would be allowed to write if // it wasn't SUID. if( checkAccess( data()->aLocalAppFile, W_OK ) ) // we would be allowed anyhow { // is it writable? QFile aConfigFile( data()->aLocalAppFile ); aConfigFile.open( IO_ReadWrite ); // Set uid/gid (neccesary for SUID programs) chown(aConfigFile.name(), getuid(), getgid()); if ( aConfigFile.isWritable() ) { bEntriesLeft = writeConfigFile( aConfigFile, false ); bLocalGood = true; } aConfigFile.close(); } } // If we could not write to the local app-specific config file, // we can try the global app-specific one. This will only work // as root, but is worth a try. if( !bLocalGood && !data()->aGlobalAppFile.isEmpty() ) { // Can we allow the write? (see above) if( checkAccess( data()->aGlobalAppFile, W_OK ) ) { // is it writable? QFile aConfigFile( data()->aGlobalAppFile ); aConfigFile.open( IO_ReadWrite ); if ( aConfigFile.isWritable() ) { bEntriesLeft = writeConfigFile( aConfigFile, false ); bLocalGood = true; } aConfigFile.close(); } } if( bEntriesLeft ) // If there are entries left, either something went wrong with // the app-specific files or there were global entries to write. { // try other files for( int i = CONFIGFILECOUNT-1; i >= 0; i-- ) { QString aFileName = aConfigFileName[i]; // replace a leading tilde with the home directory // is there a more portable way to find out the home directory? char* pHome = getenv( "HOME" ); if( (aFileName[0] == '~') && pHome ) aFileName.replace( 0, 1, pHome ); QFile aConfigFile( aFileName ); QFileInfo aInfo( aConfigFile ); // can we allow the write? (see above) if( checkAccess ( aFileName, W_OK ) ) { if( ( aInfo.exists() && aInfo.isWritable() ) || ( !aInfo.exists() && QFileInfo( aInfo.dirPath( true ) ).isWritable() ) ) { aConfigFile.open( IO_ReadWrite ); // Set uid/gid (neccesary for SUID programs) chown(aConfigFile.name(), getuid(), getgid()); writeConfigFile( aConfigFile, true ); break; } } } } } // no more dirty entries rollback();}#include "kconfig.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -