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.
kdpkg/kdpkg-install/install.cpp

430 lines
12 KiB

/*
* install.cpp
*
* Copyright (c) 2007 Fabian Wuertz
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <kgenericfactory.h>
#include <klocale.h>
#include <kfiledialog.h>
#include <kurlrequester.h>
#include <kaboutapplication.h>
#include <qlistbox.h>
#include <qfile.h>
#include <qpushbutton.h>
#include <qwidgetstack.h>
#include <qlabel.h>
#include <qlistview.h>
#include <qregexp.h>
#include <qradiobutton.h>
#include <qfiledialog.h>
#include <console.h>
#include <install.h>
#include <string>
#include <stdio.h>
using namespace std;
install::install( const QString &url, QWidget *parent, const char *name, const QStringList &)
:InstallDialog(parent, name)
{
if( !url )
path = KFileDialog::getOpenFileName( QString::null, i18n("Debian Package (*.deb)"), this, i18n("Choose a Debian package file to open"));
else
path = url;
this->shell = new Process();
this->shell->setCommand("dpkg -f "+path);
this->shell->start(true);
fields = QStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() );
installPushButton->hide();
nextPushButton1->hide();
// Get KDE prefix
// FIXME Is there a better way to do this???
string prefixcommand="kde-config --prefix";
FILE *pipe_prefix;
char prefix_result[2048];
int i;
if ((pipe_prefix = popen(prefixcommand.c_str(), "r")) == NULL)
{
m_kdePrefix = "/usr";
}
else {
fgets(prefix_result, 2048, pipe_prefix);
pclose(pipe_prefix);
for (i=0;i<2048;i++) {
if (prefix_result[i] == 0) {
prefix_result[i-1]=0;
i=2048;
}
}
m_kdePrefix = QString(prefix_result);
}
if( !checkArchitecture() )
page2x1();
else if( isLocked() )
page2x2();
}
//----------------------------------------------------------------------------//
//--- next -------------------------------------------------------------------//
//----------------------------------------------------------------------------//
void install::next1()
{
if( !isLocked() )
{
nextPushButton1->hide();
nextPushButton2->show();
widgetStack->raiseWidget(0);
}
}
void install::next2()
{
nextPushButton2->hide();
if( syncRadioButton->isChecked() )
page3();
else
page1();
}
//----------------------------------------------------------------------------//
//--- pages ------------------------------------------------------------------//
//----------------------------------------------------------------------------//
// page 0: skip apt-get update?
// page 1: dependencies
// page 2: warnings
// page 3: apt-get update
// page 4: install package
void install::page1()
{
showDependencies();
widgetStack->raiseWidget(1);
installPushButton->show();
closePushButton->show();
titleTextLabel->setText( "<b>"+i18n( "The following packages will be installed, updated or removed:" )+"</b>" );
}
void install::page2x1()
{
errorTextLabel->setText("<b>"+i18n("The architecture of this package does not match that of your system. You will not be able to install this package!")+"</b>");
nextPushButton2->hide();
widgetStack->raiseWidget(2);
}
void install::page2x2()
{
errorTextLabel->setText("<b>"+i18n("The package database is in use by another process (e.g Synaptic). Please terminate this process and select Next to try again.")+"</b>");
nextPushButton1->show();
nextPushButton2->hide();
widgetStack->raiseWidget(2);
}
void install::page3()
{
titleTextLabel->setText( "<b>"+i18n( "Resynchronize Package Index")+"</b>" );
closePushButton->hide();
QStrList run; run.append( m_kdePrefix + "/share/kdpkg/sh/kdpkg-sh" );
run.append( "update" );
QWidget *consoleWidget = new console(this, run );
widgetStack->addWidget(consoleWidget, 3);
widgetStack->raiseWidget(3);
connect( consoleWidget, SIGNAL( finished(bool) ), this, SLOT( page1() ));
}
void install::page4()
{
installPushButton->hide();
closePushButton->hide();
titleTextLabel->setText( "<b>"+i18n( "Install New Package" )+"</b>" );
if( !installPkg )
installPkg = "none";
if( !removePkg )
removePkg = "none";
QStrList run; run.append( m_kdePrefix + "/share/kdpkg/sh/kdpkg-sh" );
run.append( "install" );
run.append( path );
run.append( installPkg );
run.append( removePkg );
QWidget *consoleWidget = new console(this, run );
widgetStack->addWidget(consoleWidget, 4);
widgetStack->raiseWidget(4);
connect( consoleWidget, SIGNAL( finished(bool) ), this, SLOT( close() ));
}
//----------------------------------------------------------------------------//
//--- showDependencies -------------------------------------------------------//
//----------------------------------------------------------------------------//
void install::showDependencies()
{
int start_index;
int stop_index;
// show packages which will be installed
QString tmpString = fields.grep( QRegExp("^Depends:") )[0].mid(9);
tmpString += ", "+fields.grep( "Pre-Depends:" )[0].mid(13);
QStringList allDepends = QStringList::split( ", ", tmpString );
QString missingDepends;
QStringList tmp;
for(uint i = 0; i < allDepends.count(); i++)
{
if( allDepends[i].contains("|") ) {
tmp = QStringList::split( " | ", allDepends[i] );
uint j = 0;
bool exit = FALSE;
while ( !exit && j < tmp.count() ) {
if( isInstalled(tmp[j]) )
exit = TRUE;
j++;
}
if( !exit )
missingDepends += tmp[0]+" ";
}
else
{
if( !isInstalled( allDepends[i] ) )
missingDepends += QStringList::split( " ", allDepends[i] )[0]+" ";
}
}
while (missingDepends.find("(") != -1) {
start_index = missingDepends.find("(");
stop_index = missingDepends.find(")", start_index);
missingDepends.replace(start_index, stop_index-start_index+1, "");
}
this->shell->setCommand("apt-get -s install "+missingDepends);
this->shell->start(true);
QStringList installList = QStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() ).grep("Inst");
for(uint i = 0; i < installList.count(); i++)
{
QString name = QStringList::split( " ", installList[i] )[1];
QString pkgVersion;
QString sysVersion;
if( installList[i].contains("[") )
{
pkgVersion = QStringList::split( " ", installList[i] )[3].mid(1);
sysVersion = QStringList::split( " ", installList[i] )[2].mid(1).replace("]", "");
}
else
pkgVersion = QStringList::split( " ", installList[i] )[2].mid(1);
QListViewItem * item = new QListViewItem( dependenciesListView, 0 );
item->setPixmap( 0, QPixmap( m_kdePrefix + "/share/kdpkg/icons/install.png") );
item->setText( 1, name );
item->setText( 2, pkgVersion );
item->setText( 3, sysVersion );
installPkg += name+",";
}
// find rconflicts
QString pkgName = fields.grep("Package:")[0].mid(9);
QString pkgVersion = fields.grep("Version:")[0].mid(9);
QString rconflicts;
this->shell->setCommand("cat /var/lib/dpkg/status | grep "+pkgName+" -B 16| grep Conflicts -B 16");
this->shell->start(true);
QStringList input1 = QStringList::split( "\n\n", this->shell->getBuffer().stripWhiteSpace() );
for(uint i = 0; i < input1.count(); i++)
{
if( input1[i].contains(pkgName) )
{
QStringList input2 = QStringList::split( "\n", input1[i] );
QString name = QStringList::split( " ", input2.grep("Package:")[0] )[1];
QString cVersion = input2.grep("Conflicts:")[0].mid(11); // conflictVersion
cVersion = QStringList::split( ",", cVersion ).grep(pkgName)[0];
cVersion = QStringList::split( "(", cVersion )[1];
cVersion = cVersion.replace(")", "");
QString op = QStringList::split( " ", cVersion )[0];
cVersion = QStringList::split( " ", cVersion )[1];
if( cVersion == "")
{
rconflicts += name+" ";
printf("1");
}
else
{
printf("2");
this->shell->setCommand("if dpkg --compare-versions "+pkgVersion+" \""+op+"\" "+cVersion+"; then echo \"TRUE\"; fi");
this->shell->start(true);
if( this->shell->getBuffer().stripWhiteSpace() == "TRUE" )
rconflicts += name+" ";
}
}
}
// show packages which will be removed
QString conflicts = fields.grep( "Conflicts" )[0].mid(11);
conflicts = conflicts.replace( ",", "" );
conflicts = conflicts+" "+rconflicts;
while (conflicts.find("(") != -1) {
start_index = conflicts.find("(");
stop_index = conflicts.find(")", start_index);
conflicts.replace(start_index, stop_index-start_index+1, "");
}
this->shell->setCommand("apt-get -s remove "+conflicts);
this->shell->start(true);
QStringList removeList = QStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() ).grep("Remv");
for(uint i = 0; i < removeList.count(); i++)
{
QString name = QStringList::split( " ", removeList[i] )[1];
QString sysVersion = QStringList::split( " [", removeList[i] )[1].replace("]", "");
QListViewItem * item = new QListViewItem( dependenciesListView, 0 );
item->setPixmap( 0, QPixmap( m_kdePrefix + "/share/kdpkg/icons/remove.png") );
item->setText( 1, name );
item->setText( 3, sysVersion );
removePkg += name+",";
}
}
//----------------------------------------------------------------------------//
//--- isInstalled ------------------------------------------------------------//
//----------------------------------------------------------------------------//
bool install::isInstalled(QString input)
{
QString package = QStringList::split( " ", input )[0];
QString version = QStringList::split( " (", input )[1].replace(")", "");
this->shell->setCommand("apt-cache policy "+package);
this->shell->start(true);
QString sysVersion = QStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() )[1];
sysVersion = QStringList::split( ":", sysVersion)[1].replace(" ","");
if( sysVersion.contains("(") || sysVersion == "" )
return FALSE;
else if( version != "" )
{
QString op = QStringList::split( " ", version )[0];
QString pkgVersion = QStringList::split( " ", version )[1];
this->shell->setCommand("if dpkg --compare-versions "+sysVersion+" \""+op+"\" "+pkgVersion+"; then echo \"TRUE\"; fi");
this->shell->start(true);
if( this->shell->getBuffer().stripWhiteSpace() == "TRUE" )
return TRUE;
else
return FALSE;
}
else
return TRUE;
}
//----------------------------------------------------------------------------//
//--- about ------------------------------------------------------------------//
//----------------------------------------------------------------------------//
void install::showAbout()
{
KAboutApplication* about = new KAboutApplication ( this );
about->show();
}
//----------------------------------------------------------------------------//
//--- checks -----------------------------------------------------------------//
//----------------------------------------------------------------------------//
bool install::checkArchitecture()
{
QString arch = fields.grep("Architecture:")[0].mid(14);
if(arch == "all")
return TRUE;
// get architecture
this->shell->setCommand("dpkg --print-architecture");
this->shell->start(true);
if( arch == this->shell->getBuffer().stripWhiteSpace() )
return TRUE;
return FALSE;
}
bool install::isLocked()
{
this->shell->setCommand("apt-get install -s" );
this->shell->start(true);
if( this->shell->getBuffer().stripWhiteSpace().contains("...") )
return FALSE;
else
return TRUE;
}
#include "install.moc"