/* OPIE */ #include /* QT */ #include #include #include #include #include #include /* STD */ #include #include //symlink() #include // mkdir() #include #include #include static const char *listDir = "/usr/lib/ipkg/externinfo/"; static void createSymlinks( const QString &location, const QString &package ) { QFile inFile( location + "/usr/lib/ipkg/info/" + package + ".list" ); mkdir( "/usr/lib/ipkg", 0777 ); mkdir( listDir, 0777 ); QFile outFile( listDir + package + ".list"); // odebug << "createSymlinks " << inFile.name().ascii() << " -> " << outFile.name().ascii() << "" << oendl; if ( inFile.open(IO_ReadOnly) && outFile.open(IO_WriteOnly)) { QTextStream in(&inFile); QTextStream out(&outFile); QString s; while ( !in.eof() ) { // until end of file... s = in.readLine(); // line of text excluding '\n' // odebug << "Read: " << s.ascii() << "" << oendl; if (s.find(location,0,true) >= 0){ // odebug << "Found!" << oendl; s = s.replace(location,""); } // odebug << "Read after: " << s.ascii() << "" << oendl; // for s, do link/mkdir. if ( s.right(1) == "/" ) { // odebug << "do mkdir for " << s.ascii() << "" << oendl; mkdir( s.ascii(), 0777 ); //possible optimization: symlink directories //that don't exist already. -- Risky. } else { // odebug << "do symlink for " << s.ascii() << "" << oendl; QFileInfo ffi( s ); //Don't try to symlink if a regular file exists already if ( !ffi.exists() || ffi.isSymLink() ) { if (symlink( (location+s).ascii(), s.ascii() ) != 0){ if (errno == ENOENT){ // perror("Symlink Failed! "); QString e=s.ascii(); e = e.replace(ffi.fileName(),""); // odebug << "DirName : " << e.ascii() << "" << oendl; system ( QString("mkdir -p ")+e.ascii() ); if (symlink( (location+s).ascii(), s.ascii() ) != 0) odebug << "Big problem creating symlink and directory" << oendl; } } // odebug << "Created << s.ascii() << oendl; out << s << "\n"; } else { odebug << "" << s.ascii() << " exists already, not symlinked" << oendl; } } } inFile.close(); outFile.close(); } } static void removeSymlinks( const QString &package ) { QFile inFile( listDir + package + ".list" ); if ( inFile.open(IO_ReadOnly) ) { QTextStream in(&inFile); QString s; while ( !in.eof() ) { // until end of file... s = in.readLine(); // line of text excluding '\n' // odebug << "remove symlink " << s.ascii() << "" << oendl; QFileInfo ffi( s ); //Confirm that it's still a symlink. if ( ffi.isSymLink() ){ unlink( s.ascii() ); // odebug << "Removed " << s.ascii() << oendl; } // else // odebug << "Not removed " << s.ascii() << "" << oendl; } } inFile.close(); inFile.remove(); } } /* Slightly hacky: we can't use StorageInfo, since we don't have a QApplication. We look for filesystems that have the directory /usr/lib/ipkg/info, and assume that they are removable media with packages installed. This is safe even if eg. /usr is on a separate filesystem, since then we would be testing for /usr/usr/lib/ipkg/info, which should not exist. (And if it does they deserve to have it treated as removable.) */ static void updateSymlinks() { QDir lists( listDir ); QStringList knownPackages = lists.entryList( "*.list" ); // No tr struct mntent *me; FILE *mntfp = setmntent( "/etc/mtab", "r" ); if ( mntfp ) { while ( (me = getmntent( mntfp )) != 0 ) { QString root = me->mnt_dir; if ( root == "/" ) continue; QString info = root + "/usr/lib/ipkg/info"; QDir infoDir( info ); // odebug << "looking at " << info.ascii() << "" << oendl; if ( infoDir.isReadable() ) { const QFileInfoList *packages = infoDir.entryInfoList( "*.list" ); // No tr QFileInfoListIterator it( *packages ); QFileInfo *fi; while (( fi = *it )) { ++it; if ( knownPackages.contains( fi->fileName() ) ) { // odebug << "found " << fi->fileName() << " and we've seen it before" << oendl; knownPackages.remove( fi->fileName() ); } else { //it's a new one createSymlinks( root, fi->baseName() ); } } } } endmntent( mntfp ); } for ( QStringList::Iterator it = knownPackages.begin(); it != knownPackages.end(); ++it ) { // strip ".info" off the end. removeSymlinks( (*it).left((*it).length()-5) ); } } int main( int argc, char *argv[] ) { QApplication a( argc, argv, QApplication::Tty ); QString command = argc > 1 ? argv[1] : "update"; // No tr if ( command == "update" ) // No tr updateSymlinks(); else if ( command == "create" && argc > 3 ) // No tr createSymlinks( argv[2], argv[3] ); else if ( command == "remove" && argc > 2 ) // No tr removeSymlinks( argv[2] ); else owarn << "Argument error" << oendl; }