/* ** ** Copyright (C) 2004 Richard Lärkäng ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program in a file called COPYING; if not, write to ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, ** MA 02110-1301, USA. */ #include "gentooInterface.h" #include "updateLoc.h" #include "kpackage.h" #include "cache.h" #include "kpTerm.h" #include #include #include #include /* TODO Make it possible to 'emerge sync' Add possibilty for package manager plugins to have own compare version method, and use it here for: (alpha|beta|pre|rc|p) Slots, how to do that in a good way? Should we care about the world-file? Read masked packages from /usr/portage/profiles/package.mask Use flags and CFLAGS? Should read arch from make.conf along with directories etc "~arch" implies "arch" Do something about locateDialog, I don't want it here, but I would like it to be possible to add own configuration, and I don't like the crash when clicking locate ;-) */ Gentoo::Gentoo() : pkgInterface() { head = "Gentoo"; name = i18n("Gentoo"); icon = "gentoo"; pict = UserIcon(icon); updated_pict = UserIcon("kupdated"); new_pict = UserIcon("knew"); packagePattern = "*.ebuild"; //typeID = "/kiss"; queryMsg = i18n("Querying Gentoo package list: "); archesPossible << "~x86" << "x86"; portageDir="/usr/portage/"; TQFile f(portageDir+"profiles/package.mask"); if (f.open(IO_ReadOnly)) { TQTextStream stream( &f ); TQString line; while (!stream.atEnd()) { line = stream.readLine(); if (!line.startsWith("#") && !line.isEmpty()) { // kdDebug() << "Adding: " << line << " to packageMask" << endl; packageMask << line; } } } hasProgram = ifExe("emerge"); } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// Gentoo::~Gentoo() { } ////////////////////////////////////////////////////////////////////////////// bool Gentoo::isType(char * /*buf*/, const TQString &) { return false; } bool Gentoo::parseName(const TQString& name, TQString *n, TQString *v) { // Taken from the portage code, should be correct TQRegExp r("([^/]+)-((\\d+(\\.\\d+)*[a-z]*)(_(alpha|beta|pre|rc|p)\\d*)?(-r(\\d+))?)$"); r.search(name); *n = r.cap(1); *v = r.cap(2); if (n->isEmpty() || v->isEmpty()) return false; else return true; } void Gentoo::listInstalledPackages(TQPtrList *pki) { TQString vb; packageInfo *p; TQString sline = i18n("Looking for Gentoo packages: "); kpackage->setStatus(sline); kpackage->setPercent(0); TQFile f(portageDir+"profiles/categories"); if (!f.open(IO_ReadOnly)) { kdWarning() << "Couldn't open categories file" << endl; return; } TQTextStream stream( &f ); TQStringList categories; while (!stream.atEnd()) { categories.append(stream.readLine()); } int categoriesCount = categories.count(); int categoriesDone = 0; for (TQStringList::Iterator category = categories.begin(); category != categories.end(); ++category) { kpackage->setPercent(categoriesDone/categoriesCount); categoriesDone += 100; if (*category == "packages" || *category == "local" || *category == "virtual") continue; TQDir d("/var/db/pkg/"+*category); TQStringList packages = d.entryList(TQDir::Dirs); for (TQStringList::Iterator it = packages.begin(); it != packages.end(); ++it) { if (*it != "." && *it != "..") { p = collectInstalledInfo(*it, *category); if (p) { if (!p->pkgInsert(pki, typeID, true)) { delete p; } } } } d.setPath("/var/cache/edb/dep/"+*category); packages = d.entryList(TQDir::Files); for (TQStringList::Iterator it = packages.begin(); it != packages.end(); ++it) { if (*it != "." && *it != "..") { bool isMasked = false; TQString version, name; if (!parseName(*it, &name, &version)) { kdDebug() << "Couldn't parse name: " << *it << endl; continue; } for (TQStringList::Iterator maskIt = packageMask.begin(); maskIt != packageMask.end(); ++maskIt) { // FIXME Should all be handled, just not implemented yet if ((*maskIt).startsWith("<") || (*maskIt).startsWith("=") || (*maskIt).startsWith("~") || (*maskIt).startsWith(">")) continue; if (*category+"/"+name == *maskIt) { kdDebug() << "Package: " << name << "-" << version << " is masked" << endl; isMasked = true; break; } } if (isMasked) continue; p = collectUninstalledInfo(name, *category, version); if (p) { if (!p->pkgInsert(pki, typeID, false)) { delete p; } } } } } /* */ kpackage->setPercent(100); } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // mode: i = query installed u = query uninstalled packageInfo *Gentoo::getPackageInfo(char mode, const TQString &name, const TQString &version) { packageInfo *pki = 0; TQString vb,search; switch(mode) { //////////////////////////////////////////////////////////////////////// // query an installed package! case 'i': pki = collectInstalledInfo(name, ""/*FIXME*/); break; //////////////////////////////////////////////////////////////////// // query an uninstalled package case 'u': pki = collectUninstalledInfo(name, ""/*FIXME*/, version); break; } return pki; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// packageInfo *Gentoo::collectInstalledInfo(const TQString& name, const TQString& category) { TQMap a; TQIODevice* iod(KFilterDev::deviceForFile("/var/db/pkg/"+category+"/"+name+"/environment.bz2","application/x-bzip2", true)); TQString line; if (!iod->open(IO_ReadOnly)) return 0; TQTextStream stream( iod ); TQString n, version, description; while (!stream.atEnd()) { line = stream.readLine(); if (line.startsWith("PN=")) { n = line.mid(3); a.insert("name", n); } else if (line.startsWith("PVR=")) { version = line.mid(4); a.insert("version", version); } else if (line.startsWith("DESCRIPTION=")) { description = line.mid(12); a.insert("summary", description); } if (a.count() >= 3) break; } delete iod; a.insert("group", category); // a.insert("file-size", "File-size"); // a.insert("size", "Installed-size"); packageInfo *i = new packageInfo(a,this); i->packageState = packageInfo::INSTALLED; i->fixup(); return i; } ////////////////////////////////////////////////////////////////////////////// packageInfo *Gentoo::collectUninstalledInfo(const TQString& name, const TQString& category, const TQString& version) { TQMap a; a.insert("name", name); a.insert("group", category); a.insert("version", version); a.insert("base", portageDir+category+"/"+name); a.insert("filename", name+"-"+version+".ebuild"); TQFile f("/var/cache/edb/dep/"+category+"/"+name+"-"+version); if (!f.open(IO_ReadOnly)) { kdDebug() << "Couldn't read: " << name << "-" << version << endl; return 0; } // Dep format: // 1: DEPEND? // 2: RDEPEND? // 3: SLOT // 4: SOURCE_URI // 5: FEATURES // 6: HOMEPAGE // 7: LICENSE // 8: DESCRIPTION // 9: KEYWORDS (arch) // 10: ECLASSES (inherited) // 11: IUSE // Skip first 7 lines for now TQTextStream stream( &f ); for (int i=0; i < 7 && !stream.atEnd(); i++) stream.readLine(); if (!stream.atEnd()) a.insert("summary", stream.readLine()); TQStringList keywords = TQStringList::split(' ', stream.readLine()); bool works = false; for (TQStringList::Iterator it = keywords.begin(); it != keywords.end(); ++it) { for (TQStringList::Iterator it2 = archesPossible.begin(); it2 != archesPossible.end(); ++it2) { if (*it == *it2) { works = true; break; } } if (works) break; } if (!works) { // kdDebug() << name << "-" << version << ": Doesn't contain working arch" << endl; return 0; } packageInfo *i = new packageInfo(a,this); i->packageState = packageInfo::AVAILABLE; i->fixup(); return i; } ////////////////////////////////////////////////////////////////////////////// TQStringList Gentoo::getChangeLog(packageInfo *p) { TQStringList clog; TQFile f(portageDir+p->getProperty("group")+"/"+p->getProperty("name")+"/ChangeLog"); if (!f.open(IO_ReadOnly)) return clog; TQTextStream stream(&f); while (!stream.atEnd()) clog.append(stream.readLine()); return clog; } bool Gentoo::filesTab(packageInfo *p) { return p->packageState == packageInfo::INSTALLED; } bool Gentoo::changeTab(packageInfo *) { return true; } ////////////////////////////////////////////////////////////////////////////// TQStringList Gentoo::getFileList(packageInfo *p) { TQStringList filelist; TQFile f("/var/db/pkg/"+p->getProperty("group")+"/"+p->getProperty("name")+"-"+p->getProperty("version")+"/CONTENTS"); if (!f.open(IO_ReadOnly)) return filelist; TQTextStream stream(&f); TQString line; TQRegExp removeEnd("(.*)( [a-f0-9]{32} [0-9]+| -> [^ ] [0-9]+| -> [^\\(]*\\([^\\)]*\\))$"); while (!stream.atEnd()) { line = stream.readLine(); int pos=0; while (line[pos] != ' ') pos++; line = line.mid(pos+1); removeEnd.search(line); TQString cap = removeEnd.cap(1); if (!cap.isEmpty()) line = cap; filelist.append(line); } return filelist; } ////////////////////////////////////////////////////////////////////////////// TQString Gentoo::uninstall(int , TQPtrList *plist, bool &test) { TQString cmd; packageInfo *pk; if (test) cmd = "NOCOLOR=\"true\" emerge unmerge -p "; else cmd = "NOCOLOR=\"true\" emerge unmerge "; for (pk = plist->first(); pk != 0; pk = plist->next()) { cmd += "=" + pk->getProperty("group") + "/" + pk->getProperty("name") + "-" + pk->getProperty("version") + " "; } return cmd; } ////////////////////////////////////////////////////////////////////////////// TQString Gentoo::install(int, TQPtrList *plist, bool &test) { TQString cmd; packageInfo *pk; if (test) cmd = "NOCOLOR=\"true\" emerge -p "; else cmd = "NOCOLOR=\"true\" emerge "; for (pk = plist->first(); pk != 0; pk = plist->next()) { cmd += "=" + pk->getProperty("group") + "/" + pk->getProperty("name") + "-" + pk->getProperty("version") + " "; } return cmd; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// TQStringList Gentoo::FindFile(const TQString &, bool) { return TQStringList(); } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// void Gentoo::setLocation() { } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// void Gentoo::setAvail(LcacheObj *slist) { Q_UNUSED(slist) } #include "gentooInterface.moc"