/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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( ""+i18n( "The following packages will be installed, updated or removed:" )+"" ); } void install::page2x1() { errorTextLabel->setText(""+i18n("The architecture of this package does not match that of your system. You will not be able to install this package!")+""); nextPushButton2->hide(); widgetStack->raiseWidget(2); } void install::page2x2() { errorTextLabel->setText(""+i18n("The package database is in use by another process (e.g Synaptic). Please terminate this process and select Next to try again.")+""); nextPushButton1->show(); nextPushButton2->hide(); widgetStack->raiseWidget(2); } void install::page3() { titleTextLabel->setText( ""+i18n( "Resynchronize Package Index")+"" ); 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( ""+i18n( "Install New Package" )+"" ); 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(""+i18n("Installation process is complete!")+"
"+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"