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.
430 lines
12 KiB
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"
|