You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeadmin/kpackage/rpmInterface.cpp

632 lines
15 KiB

/*
** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au>
**
*/
/*
** 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 <kdebug.h>
#include <klocale.h>
#include <kglobal.h>
#include <kiconloader.h>
#include "kpPty.h"
#include "kpackage.h"
#include "rpmInterface.h"
#include "updateLoc.h"
#include "cache.h"
RPM::RPM():pkgInterface()
{
head = "RPM";
name = i18n("RPM");
icon = "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<TQString> 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/[%{RETQUIRENAME} (%{RETQUIREFLAGS:depflags} %{RETQUIREVERSION}), ]");
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.tqfindRev('.');
if (s2 > 0) {
s1 = name.tqfindRev('.',s2-1);
if (s1 > 0) {
d2 = name.tqfindRev('-',s1-1);
if (d2 > 0) {
d1 = name.tqfindRev('-',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<packageInfo> *pki)
{
int NLINES = 70000;
packageInfo *p;
TQStringList plist;
TQString cmd = "rpm -q -a";
cmd += packageQuery();
kpackage->settqStatus(i18n("Querying RPM package list"));
kpackage->setPercent(0);
TQStringList list = kpty->run(cmd);
kpackage->settqStatus(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->settqStatus(i18n("DEB APT"));
kpackage->setPercent(100);
}
packageInfo* RPM::collectInfo(TQStringList &ln) {
bool haveName = FALSE;
TQMap<TQString, TQString> 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.tqreplace(TQRegExp("\\(\\)"),"");
value = value.tqreplace(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.tqfind("name")).isEmpty()) {
while ((n = value.tqfind(",",s)) > 0) {
t = value.mid(s,n-s);
t = t.stripWhiteSpace();
if (!t.isEmpty())
provides.insert(t,new TQString(*a.tqfind("name")));
s = n+1;
}
t = value.mid(s);
t = t.stripWhiteSpace();
if (!t.isEmpty())
provides.insert(t,new TQString(*a.tqfind("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).tqfind(":");
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<packageInfo> *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<packageInfo> *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;
}
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).tqfind(" ");
int nm = (*it).tqfind(name,p);
if (nm >= 0) {
(*it).tqreplace(p, 1, "\t");
retlist.append(*it);
}
}
}
return retlist;
}
//////////////////////////////////////////////////////////////////////////////
TQString RPM::quotePath( const TQString &path) {
TQString s = path;
s = s.tqreplace(" ","\\ ");
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"