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

482 lines
14 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 <tqlistbox.h>
#include <tqfile.h>
#include <tqpushbutton.h>
#include <tqwidgetstack.h>
#include <tqlabel.h>
#include <tqlistview.h>
#include <tqregexp.h>
#include <tqradiobutton.h>
#include <tqfiledialog.h>
#include <console.h>
#include <install.h>
#include <string>
#include <stdio.h>
using namespace std;
install::install( const TQString &url, TQWidget *tqparent, const char *name, const TQStringList &)
:InstallDialog(tqparent, name)
{
if( !url )
path = KFileDialog::getOpenFileName( TQString(), TQString("*.deb|") + 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 = TQStringList::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 = TQString(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
// page 5: process complete
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();
TQStrList run; run.append( m_kdePrefix + "/share/kdpkg/sh/kdpkg-sh" );
run.append( "update" );
TQWidget *consoleWidget = new console(this, run );
widgetStack->addWidget(consoleWidget, 4);
widgetStack->raiseWidget(4);
connect( consoleWidget, TQT_SIGNAL( finished(bool) ), this, TQT_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";
TQStrList run; run.append( m_kdePrefix + "/share/kdpkg/sh/kdpkg-sh" );
run.append( "install" );
run.append( path );
run.append( installPkg );
run.append( removePkg );
TQWidget *consoleWidget = new console(this, run );
widgetStack->addWidget(consoleWidget, 5);
widgetStack->raiseWidget(5);
//connect( consoleWidget, TQT_SIGNAL( finished(bool) ), this, TQT_SLOT( close() ));
connect( consoleWidget, TQT_SIGNAL( finished(bool) ), this, TQT_SLOT( page5() ));
}
void install::page5()
{
successTextLabel->setText("<b>"+i18n("Installation process is complete!")+"</b><br>"+i18n("You may now close this window."));
nextPushButton2->hide();
closePushButton->show();
widgetStack->raiseWidget(3);
}
//----------------------------------------------------------------------------//
//--- get --------------------------------------------------------------------//
//----------------------------------------------------------------------------//
TQStringList install::getVersions(TQString package)
{
this->shell->setCommand("apt-cache policy "+package);
this->shell->start(true);
TQStringList input = TQStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() );
TQString sysVersion = input[1];
sysVersion = TQStringList::split( ":", sysVersion)[1].tqreplace(" ","");
if( sysVersion.tqcontains("(") || sysVersion == "" )
sysVersion = i18n("not installed");
TQString repVersion = input[2];
repVersion = TQStringList::split( ":", repVersion)[1].tqreplace(" ","");
if( repVersion.tqcontains("(") || repVersion == "" )
repVersion = i18n("not available");
TQStringList versions;
versions.append(sysVersion);
versions.append(repVersion);
return versions;
}
//----------------------------------------------------------------------------//
//--- showDependencies -------------------------------------------------------//
//----------------------------------------------------------------------------//
void install::showDependencies()
{
int start_index;
int stop_index;
// show packages which will be installed
TQString debianPkgName = fields.grep("Package:")[0].mid(9);
TQString debianPkgVersion = fields.grep("Version:")[0].mid(9);
TQStringList debianVersions = getVersions(fields.grep("Package:")[0].mid(9));
TQString debianSysVersion = debianVersions[0];
TQListViewItem * ditem = new TQListViewItem( dependenciesListView, 0 );
ditem->setPixmap( 0, TQPixmap( m_kdePrefix + "/share/kdpkg/icons/install.png") );
ditem->setText( 1, debianPkgName );
ditem->setText( 2, debianPkgVersion );
ditem->setText( 3, debianSysVersion );
TQString tmpString = fields.grep( TQRegExp("^Depends:") )[0].mid(9);
tmpString += ", "+fields.grep( "Pre-Depends:" )[0].mid(13);
TQStringList allDepends = TQStringList::split( ", ", tmpString );
TQString missingDepends;
TQStringList tmp;
for(uint i = 0; i < allDepends.count(); i++)
{
if( allDepends[i].tqcontains("|") ) {
tmp = TQStringList::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 += TQStringList::split( " ", allDepends[i] )[0]+" ";
}
}
while (missingDepends.tqfind("(") != -1) {
start_index = missingDepends.tqfind("(");
stop_index = missingDepends.tqfind(")", start_index);
missingDepends.tqreplace(start_index, stop_index-start_index+1, "");
}
this->shell->setCommand("apt-get -s install "+missingDepends);
this->shell->start(true);
TQStringList installList = TQStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() ).grep("Inst");
for(uint i = 0; i < installList.count(); i++)
{
TQString name = TQStringList::split( " ", installList[i] )[1];
TQString pkgVersion;
TQString sysVersion;
if( installList[i].tqcontains("[") )
{
pkgVersion = TQStringList::split( " ", installList[i] )[3].mid(1);
sysVersion = TQStringList::split( " ", installList[i] )[2].mid(1).tqreplace("]", "");
}
else
pkgVersion = TQStringList::split( " ", installList[i] )[2].mid(1);
TQListViewItem * item = new TQListViewItem( dependenciesListView, 0 );
item->setPixmap( 0, TQPixmap( m_kdePrefix + "/share/kdpkg/icons/install.png") );
item->setText( 1, name );
item->setText( 2, pkgVersion );
item->setText( 3, sysVersion );
installPkg += name+",";
}
// find rconflicts
TQString pkgName = fields.grep("Package:")[0].mid(9);
TQString pkgVersion = fields.grep("Version:")[0].mid(9);
TQString rconflicts;
this->shell->setCommand("cat /var/lib/dpkg/status | grep "+pkgName+" -B 16| grep Conflicts -B 16");
this->shell->start(true);
TQStringList input1 = TQStringList::split( "\n\n", this->shell->getBuffer().stripWhiteSpace() );
for(uint i = 0; i < input1.count(); i++)
{
if( input1[i].tqcontains(pkgName) )
{
TQStringList input2 = TQStringList::split( "\n", input1[i] );
TQString name = TQStringList::split( " ", input2.grep("Package:")[0] )[1];
TQString cVersion = input2.grep("Conflicts:")[0].mid(11); // conflictVersion
cVersion = TQStringList::split( ",", cVersion ).grep(pkgName)[0];
cVersion = TQStringList::split( "(", cVersion )[1];
cVersion = cVersion.tqreplace(")", "");
TQString op = TQStringList::split( " ", cVersion )[0];
cVersion = TQStringList::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
TQString conflicts = fields.grep( "Conflicts" )[0].mid(11);
conflicts = conflicts.tqreplace( ",", "" );
conflicts = conflicts+" "+rconflicts;
while (conflicts.tqfind("(") != -1) {
start_index = conflicts.tqfind("(");
stop_index = conflicts.tqfind(")", start_index);
conflicts.tqreplace(start_index, stop_index-start_index+1, "");
}
this->shell->setCommand("apt-get -s remove "+conflicts);
this->shell->start(true);
TQStringList removeList = TQStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() ).grep("Remv");
for(uint i = 0; i < removeList.count(); i++)
{
TQString name = TQStringList::split( " ", removeList[i] )[1];
TQString sysVersion = TQStringList::split( " [", removeList[i] )[1].tqreplace("]", "");
TQListViewItem * item = new TQListViewItem( dependenciesListView, 0 );
item->setPixmap( 0, TQPixmap( m_kdePrefix + "/share/kdpkg/icons/remove.png") );
item->setText( 1, name );
item->setText( 3, sysVersion );
removePkg += name+",";
}
}
//----------------------------------------------------------------------------//
//--- isInstalled ------------------------------------------------------------//
//----------------------------------------------------------------------------//
bool install::isInstalled(TQString input)
{
TQString package = TQStringList::split( " ", input )[0];
TQString version = TQStringList::split( " (", input )[1].tqreplace(")", "");
this->shell->setCommand("apt-cache policy "+package);
this->shell->start(true);
TQString sysVersion = TQStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() )[1];
sysVersion = TQStringList::split( ":", sysVersion)[1].tqreplace(" ","");
if( sysVersion.tqcontains("(") || sysVersion == "" )
return FALSE;
else if( version != "" )
{
TQString op = TQStringList::split( " ", version )[0];
TQString pkgVersion = TQStringList::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()
{
TQString 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().tqcontains("...") )
return FALSE;
else
return TRUE;
}
#include "install.moc"