void NSPluginLoader::scanPlugins() { QRegExp version(";version=[^:]*:"); // open the cache file QFile cachef(locate("data", "nsplugins/cache")); if (!cachef.open(IO_ReadOnly)) { kdDebug() << "Could not load plugin cache file!" << endl; return; } QTextStream cache(&cachef); // read in cache QString line, plugin; while (!cache.atEnd()) { line = cache.readLine(); if (line.isEmpty() || (line.left(1) == "#")) continue; if (line.left(1) == "[") { plugin = line.mid(1,line.length()-2); continue; } QStringList desc = QStringList::split(':', line, TRUE); QString mime = desc[0].stripWhiteSpace(); QStringList suffixes = QStringList::split(',', desc[1].stripWhiteSpace()); if (!mime.isEmpty()) { // insert the mimetype -> plugin mapping _mapping.insert(mime, new QString(plugin)); // insert the suffix -> mimetype mapping QStringList::Iterator suffix; for (suffix = suffixes.begin(); suffix != suffixes.end(); ++suffix) { // strip whitspaces and any preceding '.' QString stripped = (*suffix).stripWhiteSpace(); unsigned p=0; for ( ; p<stripped.length() && stripped[p]=='.'; p++ ); stripped = stripped.right( stripped.length()-p ); // add filetype to list if ( !stripped.isEmpty() && !_filetype.find(stripped) ) _filetype.insert( stripped, new QString(mime)); } } } }
int main( int argc, char **argv ) { KAboutData aboutData( "nspluginscan", "nsplugin", ki18n("nspluginscan"), "0.3", ki18n("nspluginscan"), KAboutData::License_GPL, ki18n("(c) 2000,2001 by Stefan Schimanski") ); KCmdLineArgs::init( argc, argv, &aboutData ); KCmdLineOptions options; options.add("verbose", ki18n("Show progress output for GUI")); KCmdLineArgs::addCmdLineOptions( options ); KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); showProgress = args->isSet("verbose"); if (showProgress) { printf("10\n"); fflush(stdout); } KApplication app(false); // Set up SIGCHLD handler struct sigaction act; act.sa_handler=sigChildHandler; sigemptyset(&(act.sa_mask)); sigaddset(&(act.sa_mask), SIGCHLD); // Make sure we don't block this signal. gdb tends to do that :-( sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0); act.sa_flags = SA_NOCLDSTOP; // CC: take care of SunOS which automatically restarts interrupted system // calls (and thus does not have SA_RESTART) #ifdef SA_RESTART act.sa_flags |= SA_RESTART; #endif struct sigaction oldact; sigaction( SIGCHLD, &act, &oldact ); // set up the paths used to look for plugins QStringList searchPaths = getSearchPaths(); QStringList mimeInfoList; infoConfig = new KConfig( KGlobal::dirs()->saveLocation("data", "nsplugins") + "/pluginsinfo" ); infoConfig->group("<default>").writeEntry( "number", 0 ); // open the cache file for the mime information QString cacheName = KGlobal::dirs()->saveLocation("data", "nsplugins")+"/cache"; kDebug(1433) << "Creating MIME cache file " << cacheName; QFile cachef(cacheName); if (!cachef.open(QIODevice::WriteOnly)) return -1; QTextStream cache(&cachef); if (showProgress) { printf("20\n"); fflush(stdout); } // read in the plugins mime information kDebug(1433) << "Scanning directories" << searchPaths; int count = searchPaths.count(); int i = 0; for ( QStringList::const_iterator it = searchPaths.constBegin(); it != searchPaths.constEnd(); ++it, ++i) { if ((*it).isEmpty()) continue; scanDirectory( *it, mimeInfoList, cache ); if (showProgress) { printf("%d\n", 25 + (50*i) / count ); fflush(stdout); } } if (showProgress) { printf("75\n"); fflush(stdout); } // We're done with forking, // KProcess needs SIGCHLD to be reset to what it was initially sigaction( SIGCHLD, &oldact, 0 ); // delete old mime types kDebug(1433) << "Removing old mimetypes"; const QStringList oldMimes = deletePluginMimeTypes(); bool mimeTypesChanged = !oldMimes.isEmpty(); if (showProgress) { printf("80\n"); fflush(stdout); } // write mimetype files kDebug(1433) << "Creating MIME type descriptions"; QStringList mimeTypes; for ( QStringList::const_iterator it=mimeInfoList.constBegin(); it!=mimeInfoList.constEnd(); ++it) { kDebug(1433) << "Handling MIME type " << *it; QStringList info = (*it).split(':', QString::KeepEmptyParts); if ( info.count()==4 ) { QString pluginName = info[0]; QString type = info[1].toLower(); QString extension = info[2]; QString desc = info[3]; // append to global mime type list if ( !mimeTypes.contains(type) ) { kDebug(1433) << " - mimeType=" << type; mimeTypes.append( type ); // write or update mime type file, if // 1) it doesn't exist in ksycoca (meaning we never heard of it) // 2) or we just deleted it [it's still in ksycoca though] // This prevents noticing that a shared-mime-info upgrade brought // us a mimetype we needed; but doing this right requires launching // kbuildsycoca4 after removing mimetypes above, and that's really slow bool mustWriteMimeType = KMimeType::mimeType(type).isNull(); if (!mustWriteMimeType) mustWriteMimeType = oldMimes.contains(type); if ( mustWriteMimeType ) { kDebug(1433) << " - creating MIME type description"; removeExistingExtensions( extension ); generateMimeType( type, extension, pluginName, desc ); mimeTypesChanged = true; } else { kDebug(1433) << " - already exists"; } } } } // done with new mimetypes, run update-mime-database if (mimeTypesChanged) { MimeTypeWriter::runUpdateMimeDatabase(); // note that we'll run kbuildsycoca below anyway } if (showProgress) { printf("85\n"); fflush(stdout); } // close files kDebug(1433) << "Closing cache file"; cachef.close(); infoConfig->sync(); delete infoConfig; // write plugin lib service file writeServicesFile( mimeTypes ); if (showProgress) { printf("90\n"); fflush(stdout); } if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kded")) { // Tell kded to update sycoca database. QDBusInterface kbuildsycoca("org.kde.kded", "/kbuildsycoca", "org.kde.kded"); kbuildsycoca.call("recreate"); } else { // kded not running? fallback to calling kbuildsycoca directly: KProcess proc; proc << KStandardDirs::findExe(KBUILDSYCOCA_EXENAME); proc.setOutputChannelMode(KProcess::MergedChannels); // silence kbuildsycoca output proc.execute(); } }