/* ** Copyright (C) 1999,2000 Toivo Pedaste ** */ /* ** 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. */ /* ** Bug reports and questions can be sent to kde-devel@kde.org */ ////////////////////////////////////////////////////////////////////////////// /// /// RPM Program version /// ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "kpPty.h" #include "kpackage.h" #include "rpmInterface.h" #include "updateLoc.h" #include "cache.h" RPM::RPM():pkgInterface() { head = "RPM"; name = i18n("RPM"); icon = "application-x-rpm"; pict = UserIcon(icon); updated_pict = UserIcon("rupdated"); new_pict = UserIcon("rnew"); packagePattern = "*.rpm"; typeID = "/rpm"; locatedialog = new Locations(i18n("Location of RPM Package Archives")); locatedialog->dLocations(7,6, this, i18n("Folder","F"), "Rpm","*.rpm", i18n("Location of Folders Containing RPM Packages")); connect(locatedialog,TQT_SIGNAL(returnVal(LcacheObj *)), this,TQT_SLOT(setAvail(LcacheObj *))); locatedialog->apply_slot(); paramsInst.append(new param(i18n("Upgrade"),TRUE,FALSE,"-U","-i")); paramsInst.append(new param(i18n("Replace Files"),FALSE,FALSE,"--replacefiles")); paramsInst.append(new param(i18n("Replace Packages"),TRUE,FALSE,"--replacepkgs")); paramsInst.append(new param(i18n("Check Dependencies"),TRUE,TRUE,"--nodeps")); paramsInst.append(new param(i18n("Test (do not install)"),FALSE,FALSE,"--test")); paramsUninst.append(new param(i18n("Remove all versions"),FALSE,FALSE,"--allmatches")); paramsUninst.append(new param(i18n("Use Scripts"),TRUE,TRUE,"--noscripts")); paramsUninst.append(new param(i18n("Check Dependencies"),TRUE,TRUE,"--nodeps")); paramsUninst.append(new param(i18n("Test (do not uninstall)"),FALSE,FALSE,"--test")); queryMsg = i18n("Querying RPM package list: "); TQDict provides(1433,false); infoList.append("name/%{NAME}"); infoList.append("version/%{VERSION}"); infoList.append("release/%{RELEASE}"); infoList.append("summary/%{SUMMARY}"); infoList.append("url/%{URL}"); infoList.append("architecture/%{ARCH}"); infoList.append("group/%{GROUP}"); infoList.append("distribution/%{DISTRIBUTION}"); infoList.append("vendor/%{VENDOR}"); infoList.append("packager/%{PACKAGER}"); infoList.append("installtime/%{INSTALLTIME:date}"); infoList.append("buildtime/%{BUILDTIME:date}"); infoList.append("size/%{SIZE}"); infoList.append("provides/[%{PROVIDES}, ]"); infoList.append("requires/[%{REQUIRENAME} (%{REQUIREFLAGS:depflags} %{REQUIREVERSION}), ]"); infoList.append("description/[%{DESCRIPTION}]"); hasProgram = ifExe("rpm"); } RPM::~RPM(){} bool RPM::isType(char *buf, const TQString & /* fname */) { if (hasProgram) { if ((unsigned char)buf[0] == 0355 && (unsigned char)buf[1] == 0253 && (unsigned char)buf[2] == 0356 && (unsigned char)buf[3] == 0333 ) { return true; } else return false; } else { return false; } } bool RPM::parseName(const TQString &name, TQString *n, TQString *v) { int d1, d2, s1, s2; s2 = name.findRev('.'); if (s2 > 0) { s1 = name.findRev('.',s2-1); if (s1 > 0) { d2 = name.findRev('-',s1-1); if (d2 > 0) { d1 = name.findRev('-',d2-1); if (d1 < 0) d1 = d2; *n = name.left(d1); *v = name.mid(d1+1,s1-d1-1); return TRUE; } } } return FALSE; } TQString RPM::packageQuery() { TQString cmd = " --queryformat '"; for ( TQStringList::Iterator it = infoList.begin(); it != infoList.end(); ++it ) { TQStringList s = TQStringList::split("/",*it); cmd += "=="; cmd += s[0]; cmd += "\\n"; cmd += s[1]; cmd += "\\n"; } cmd += "==\\n'"; return cmd; } void RPM::listInstalledPackages(TQPtrList *pki) { int NLINES = 70000; packageInfo *p; TQStringList plist; TQString cmd = "rpm -q -a"; cmd += packageQuery(); kpackage->setStatus(i18n("Querying RPM package list")); kpackage->setPercent(0); TQStringList list = kpty->run(cmd); kpackage->setStatus(i18n("Processing RPM package list")); // kdDebug() << "P=" << list.count() <<"\n"; kpackage->setPercent(50); if (list.count() > 0) { TQString s; kpackage->setPercent(0 ); int cnt = 0; for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) { cnt++; if (cnt % (NLINES/20) == 0) { kpackage->setPercent((cnt * 100)/ NLINES ); } if (*it != "==") { s = *it; // kdDebug() << s.length() << "<" << s << ">\n"; plist << s; } else { p = collectInfo(plist); if (p) { if (!p->pkgInsert(pki, typeID, TRUE)) { delete p; } } plist.clear(); } } } list.clear(); kpackage->setStatus(i18n("DEB APT")); kpackage->setPercent(100); } packageInfo* RPM::collectInfo(TQStringList &ln) { bool haveName = FALSE; TQMap a; TQString name, value; for ( TQStringList::Iterator it = ln.begin(); it != ln.end(); ++it ) { if ((*it).left(2) == "==" && (*it).length() >= 2) { name = (*it).right((*it).length() - 2); } value = ""; it++; while (it != ln.end() && (*it).left(2) != "==") { value += *it; value += " "; it++; } it--; // kdDebug() << "name=" << name << " value='" << value << "'\n"; if (name == "installtime") { a.insert("install time", value); } else if (name == "name") { if (!value.isEmpty()) haveName = TRUE; a.insert("name", value.stripWhiteSpace()); } else if (name == "buildtime") { a.insert("build-time", value); } else if (name == "requires") { value = value.replace(TQRegExp("\\(\\)"),""); value = value.replace(TQRegExp("\\( \\)"),""); value = value.stripWhiteSpace(); if (value.endsWith(",")) { value.truncate(value.length()-1); } a.insert("depends", value); } else if (name == "provides") { int s = 0, n; TQString t; if (!(*a.find("name")).isEmpty()) { while ((n = value.find(",",s)) > 0) { t = value.mid(s,n-s); t = t.stripWhiteSpace(); if (!t.isEmpty()) provides.insert(t,new TQString(*a.find("name"))); s = n+1; } t = value.mid(s); t = t.stripWhiteSpace(); if (!t.isEmpty()) provides.insert(t,new TQString(*a.find("name"))); value = value.stripWhiteSpace(); if (value.endsWith(",")) { value.truncate(value.length()-1); } a.insert("provides", value); } } else { if (!name.isEmpty()) a.insert(name, value.stripWhiteSpace()); } } TQString vers = a["version"]; TQString rel = a["release"]; if (!vers.isEmpty() && !rel.isEmpty()) { vers += "-"; vers += rel; a["version"] = vers; a.remove("release"); } if (haveName) { packageInfo *i = new packageInfo(a,this); i->packageState = packageInfo::INSTALLED; i->fixup(); return i; } else { return 0; } } ////////////////////////////////////////////////////////////////////////////// TQStringList RPM::getChangeLog(packageInfo *p) { TQStringList clog; TQString fn( p->getFilename()); if(!fn.isEmpty()) return getUChangeLog(fn); else return getIChangeLog(p); return clog; } // query an installed package TQStringList RPM::getIChangeLog(packageInfo *p) { TQString name = p->getProperty("name"); TQString cmd = "rpm -q --changelog "; cmd += name; TQStringList filelist = kpty->run(cmd); return filelist; } // query an uninstalled package TQStringList RPM::getUChangeLog(const TQString &fn) { TQString cmd = "rpm -q --changelog -p "; cmd += quotePath(fn); TQStringList filelist = kpty->run(cmd); return filelist; } bool RPM::filesTab(packageInfo *p) { if (p->packageState == packageInfo::INSTALLED) { return true; } else if (p->isFileLocal()) { return true; } return false; } bool RPM::changeTab(packageInfo *p) { if (p->packageState == packageInfo::INSTALLED) { return true; } else if (p->isFileLocal()) { return true; } return false; } ////////////////////////////////////////////////////////////////////////////// TQStringList RPM::getFileList(packageInfo *p) { TQStringList filelist; TQString fn( p->getFilename()); if(!fn.isEmpty()) return getUFileList(fn); else return getIFileList(p); return filelist; } // query an installed package TQStringList RPM::getIFileList(packageInfo *p) { TQString name = p->getProperty("name"); TQString cmd = "rpm -q -l "; cmd += name; TQStringList filelist = kpty->run(cmd); return filelist; } // query an uninstalled package TQStringList RPM::getUFileList(const TQString &fn) { TQString cmd = "rpm -q -l -p "; cmd += quotePath(fn); TQStringList filelist = kpty->run(cmd); return filelist; } ////////////////////////////////////////////////////////////////////////////// packageInfo *RPM::getPackageInfo(char mode, const TQString &name, const TQString &) { if (mode == 'i') { return getIPackageInfo(name); } else return getUPackageInfo(name); } packageInfo *RPM::getIPackageInfo( const TQString &name ) { // query an installed package! TQString cmd = "rpm -q"; cmd += packageQuery(); cmd += " "; cmd += name; TQStringList infoList = kpty->run(cmd); packageInfo *pki = collectInfo(infoList); if (pki) { pki->packageState = packageInfo::INSTALLED; collectDepends(pki,name,0); } return pki; } packageInfo *RPM::getUPackageInfo( const TQString &name ) { // query an uninstalled package TQString cmd = "rpm -q"; cmd += packageQuery(); cmd += " -p "; cmd += quotePath(name); TQStringList infoList = kpty->run(cmd); packageInfo *pki = collectInfo(infoList); if (pki) { pki->updated = TRUE; pki->packageState = packageInfo::AVAILABLE; if (pki->hasProperty("install time")) pki->info.remove("install time"); collectDepends(pki,name,1); } return pki; } TQString RPM::provMap( const TQString &p ) { TQString *r = provides[p]; if (r) { TQString s = *r; // printf("%s=>%s\n",p.data(),s.data()); return s; } else { return p; } } ////////////////////////////////////////////////////////////////////////////// void RPM::collectDepends(packageInfo *p, const TQString &name, int src) { TQString cmd = "rpm -V --nofiles "; if (src) { cmd += "-p "; } cmd += quotePath(name); // cmd = "cat /home/toivo/rpm.deps"; TQStringList list = kpty->run(cmd); if (list.count() > 0) { TQStringList::Iterator it = list.begin(); int pt = (*it).find(":"); if (pt > 0) { TQString s = (*it).mid(pt+1); if (!s.isEmpty()) { // kdDebug() << "S=" << s << "\n"; p->info.insert("unsatisfied dependencies", s); } } } } ////////////////////////////////////////////////////////////////////////////// void RPM::setLocation() { locatedialog->restore(); } void RPM::setAvail(LcacheObj *slist) { if (packageLoc) delete packageLoc; packageLoc = slist; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// TQString RPM::uninstall(int uninstallFlags, TQPtrList *plist, bool &test) { TQStringList files; packageInfo *pk; for (pk = plist->first(); pk != 0; pk = plist->next()) { files.append( pk->getProperty("name") ); } if (getuid() == 0) { return doUninst(uninstallFlags,files, test); } else { return doUninstP(uninstallFlags,files, test); } } TQString RPM::uninstall(int uninstallFlags, packageInfo *p, bool &test) { TQStringList files; files.append( p->getProperty("name") ); if (getuid() == 0) { return doUninstP(uninstallFlags,files, test); } else { return doUninstP(uninstallFlags,files, test); } } TQString RPM::doUninstP(int uninstallFlags, const TQStringList &files, bool &test) { TQString s = "rpm -e "; s += setOptions(uninstallFlags, paramsUninst); for (TQStringList::ConstIterator it = files.begin(); it != files.end(); ++it ) { s += " "; s += *it; } if (uninstallFlags>>3 & 1) test = TRUE; kdDebug() << "uCMD=" << s << " test=" << test << "\n"; return s; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// TQString RPM::install(int installFlags, TQPtrList *plist, bool &test) { TQStringList files; for (packageInfo *pk = plist->first(); pk != 0; pk = plist->next()) { TQString fname( pk->fetchFilename() ); if (!fname.isEmpty()) { files.append(quotePath(fname)); } } if (getuid() == 0) { return doinstP(installFlags,files,test); } else { return doinstP(installFlags,files,test); } } TQString RPM::install(int installFlags, packageInfo *p, bool &test) { TQStringList files; files.append(quotePath(p->fetchFilename())); if (getuid() == 0) { return doinstP(installFlags,files,test); } else { return doinstP(installFlags,files,test); } } TQString RPM::doinstP(int installFlags, const TQStringList &files, bool &test) { TQString s = "rpm "; s += setOptions(installFlags, paramsInst); for (TQStringList::ConstIterator it = files.begin(); it != files.end(); ++it ) { s += " "; s += (*it).utf8(); } if (installFlags>>4 & 1) test = TRUE; kdDebug() << "iCMD=" << s << " test=" << test << "\n"; return s; } TQStringList RPM::verify(packageInfo *p, const TQStringList &files){ return pkgInterface::verify(p,files);} ////////////////////////////////////////////////////////////////////////////// TQStringList RPM::FindFile(const TQString &name, bool) { TQString cmd = "rpm -q -a --filesbypkg"; TQStringList list = kpty->run(cmd); TQStringList retlist; if (kpty->Result > 0) { list.clear(); } else { for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) { int p = (*it).find(" "); int nm = (*it).find(name,p); if (nm >= 0) { (*it).replace(p, 1, "\t"); retlist.append(*it); } } } return retlist; } ////////////////////////////////////////////////////////////////////////////// TQString RPM::quotePath( const TQString &path) { TQString s = path; s = s.replace(" ","\\ "); return ( "'" + s + "'" ); } ////////////////////////////////////////////////////////////////////////////// TQStringList RPM::depends(const TQString &, int){return 0;} TQString RPM::doUninst(int, const TQStringList &, bool &){return "0=";} TQString RPM::doinst(int, const TQStringList &, bool &){return "0=";} #include "rpmInterface.moc"