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.
632 lines
15 KiB
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"
|