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.
259 lines
7.8 KiB
259 lines
7.8 KiB
/** -*- C++ -*-
|
|
@file adept/dpkgpm-gui.cpp
|
|
@author Peter Rockai <me@mornfall.net>
|
|
*/
|
|
|
|
#include <fcntl.h>
|
|
#include <iostream>
|
|
|
|
#include <qstrlist.h>
|
|
#include <kapplication.h>
|
|
#include <klistbox.h>
|
|
#include <klocale.h>
|
|
#include <kparts/part.h>
|
|
|
|
#include <apt-pkg/configuration.h>
|
|
#include <apt-pkg/error.h>
|
|
|
|
#include <apt-front/cache/cache.h>
|
|
#include <apt-front/cache/component/packages.h>
|
|
#include <apt-front/cache/entity/package.h>
|
|
|
|
#include <adept/dpkgpm-gui.h>
|
|
#include <adept/utils.h>
|
|
|
|
using namespace aptFront;
|
|
using namespace cache;
|
|
|
|
namespace adept {
|
|
|
|
PkgSystem::PkgSystem()
|
|
: m_terminalPart( 0 )
|
|
{
|
|
std::cerr << "kapture::PkgSystem::PkgSystem()" << std::endl;
|
|
Label = "adeptDPkgSystem";
|
|
}
|
|
|
|
void PkgSystem::setTerminal( KParts::Part *t )
|
|
{
|
|
m_terminalPart = t;
|
|
}
|
|
|
|
pkgPackageManager *PkgSystem::CreatePM( pkgDepCache *c ) const
|
|
{
|
|
std::cerr << "kapture::PkgSystem::CreatePM()" << std::endl;
|
|
adept::DPkgPM *pm = new adept::DPkgPM( c, m_terminalPart );
|
|
connect( pm, SIGNAL( statusChanged( int, QString ) ),
|
|
this, SIGNAL( statusChanged( int, QString ) ) );
|
|
return pm;
|
|
}
|
|
|
|
DPkgPM::DPkgPM( pkgDepCache *cache, KParts::Part *t )
|
|
: aptFront::DPkgPM (cache), m_terminalPart (t)
|
|
{
|
|
}
|
|
|
|
bool DPkgPM::forkDpkg( char *const argv[] )
|
|
{
|
|
bool ok = true;
|
|
std::cerr << "adept::DPkgPM::forkDpkg ()" << std::endl;
|
|
QStrList l;
|
|
for (int i = 0; argv[i]; i ++)
|
|
l.append( argv[i] );
|
|
|
|
m_processRunning = true;
|
|
connect( m_terminalPart, SIGNAL( processExited( KProcess * ) ),
|
|
this, SLOT( processExit( KProcess * ) ) );
|
|
connect( m_terminalPart, SIGNAL( processExited( const KProcess * ) ),
|
|
this, SLOT( processExitC( const KProcess * ) ) );
|
|
connect( m_terminalPart, SIGNAL( forkedChild() ),
|
|
this, SLOT( setupDpkgChild() ) );
|
|
|
|
terminal()->startProgram( u8( argv[0] ), l );
|
|
|
|
::close( m_dpkgPipe[1] );
|
|
::fcntl( m_dpkgPipe[0], F_SETFL, O_NONBLOCK );
|
|
|
|
while (m_processRunning) {
|
|
dpkgMonitor();
|
|
usleep( 50000 );
|
|
}
|
|
|
|
if (m_exitedProcess->normalExit()) {
|
|
if (m_exitedProcess->exitStatus() != 0) {
|
|
ok = _error->Error( "Child for %s exited with error %d",
|
|
argv [0], m_exitedProcess->exitStatus());
|
|
}
|
|
} else {
|
|
ok = _error->Error( "Child for %s was killed by signal %d",
|
|
argv [0], m_exitedProcess->exitSignal());
|
|
}
|
|
|
|
if (ok) // do we run scripts in case dpkg died???
|
|
ok = runScripts ("DPkg::Post-Invoke", false);
|
|
|
|
return ok;
|
|
}
|
|
|
|
ExtTerminalInterface *DPkgPM::terminal() {
|
|
return static_cast<ExtTerminalInterface *>(
|
|
m_terminalPart->qt_cast( "ExtTerminalInterface" ) );
|
|
}
|
|
|
|
bool DPkgPM::forkScript (const char *cmd, bool fP)
|
|
{
|
|
std::cerr << "adept::DPkgPM::forkScript(\"" << cmd << "\")" << std::endl;
|
|
if (fP) {
|
|
if (pipe( m_scriptPipe ) != 0)
|
|
return _error->Errno(
|
|
"pipe","Failed to create IPC pipe to subprocess");
|
|
SetCloseExec (m_scriptPipe[0], true);
|
|
SetCloseExec (m_scriptPipe[1], true);
|
|
}
|
|
QStrList l;
|
|
l.append ("/bin/sh");
|
|
l.append ("-c");
|
|
l.append (cmd);
|
|
if (fP) {
|
|
connect( m_terminalPart, SIGNAL( forkedChild() ),
|
|
this, SLOT( setupScriptPipe() ) );
|
|
}
|
|
|
|
connect( m_terminalPart, SIGNAL( processExited( KProcess * ) ),
|
|
this, SLOT( processExit( KProcess * ) ) );
|
|
connect( m_terminalPart, SIGNAL( processExited( const KProcess * ) ),
|
|
this, SLOT( processExitC( const KProcess * ) ) );
|
|
|
|
m_processRunning = true;
|
|
terminal()->startProgram( u8( "/bin/sh" ), l);
|
|
|
|
if (fP) {
|
|
if (!feedPackages())
|
|
return _error->Error("Failed feeding packages to script");
|
|
}
|
|
|
|
while (m_processRunning) {
|
|
kapp->processEvents();
|
|
usleep(50000);
|
|
}
|
|
|
|
std::cerr << "END: adept::DPkgPM::forkScript(\""
|
|
<< cmd << "\")" << std::endl;
|
|
|
|
if (m_exitedProcess->normalExit()) {
|
|
if (m_exitedProcess->exitStatus() != 0) {
|
|
return _error -> Error("Child for %s exited with error %d",
|
|
cmd, m_exitedProcess->exitStatus());
|
|
} else {
|
|
return true;
|
|
}
|
|
} else {
|
|
return _error->Error("Child for %s was killed by signal %d",
|
|
cmd, m_exitedProcess->exitSignal());
|
|
}
|
|
}
|
|
|
|
void DPkgPM::processExit(KProcess *p) {
|
|
processExitC( p );
|
|
}
|
|
|
|
void DPkgPM::processExitC(const KProcess *p)
|
|
{
|
|
std::cerr << "a process exited!" << std::endl;
|
|
m_processRunning = false;
|
|
m_exitedProcess = p;
|
|
}
|
|
|
|
void DPkgPM::setupScriptPipe()
|
|
{
|
|
// setupScript();
|
|
// std::cerr << "setupScriptPipe()" << std::endl;
|
|
dup2 (m_scriptPipe[0], STDIN_FILENO);
|
|
}
|
|
|
|
void DPkgPM::setupDpkgChild()
|
|
{
|
|
// setupScript();
|
|
// std::cerr << "setupDpkgChild()" << std::endl;
|
|
setupChild();
|
|
}
|
|
|
|
bool DPkgPM::Go( int )
|
|
{
|
|
std::cerr << "kapture::DPkgPM::Go ()" << std::endl;
|
|
statusChanged( 0, i18n( "Preparing..." ) );
|
|
bool ret = aptFront::DPkgPM::Go(-1);
|
|
QStrList l;
|
|
l.append("echo");
|
|
l.append("dpkg run finished!");
|
|
terminal()->startProgram( u8( "echo" ), l );
|
|
statusChanged( 100, i18n( "Done" ) );
|
|
return ret;
|
|
}
|
|
|
|
void DPkgPM::dpkgMonitor ()
|
|
{
|
|
aptFront::DPkgPM::dpkgMonitor();
|
|
kapp->processEvents();
|
|
}
|
|
|
|
void DPkgPM::updateStatus( std::string pkg, std::string ev, std::string r )
|
|
{
|
|
std::string op, msg;
|
|
aptFront::DPkgPM::updateStatus( pkg, ev, r );
|
|
entity::Package p = cache::Global::get().packages().packageByName( pkg );
|
|
|
|
if ( m_currentOp == OInstall ) {
|
|
if ( p.markedNewInstall() ) {
|
|
if ( ev == "half-installed" )
|
|
msg = u8( i18n( "Preparing installation of %1..." ) );
|
|
else if ( ev == "unpacked" )
|
|
msg = u8( i18n( "Unpacking %1..." ) );
|
|
} else if ( p.markedUpgrade() ) {
|
|
if ( ev == "half-installed" )
|
|
msg = u8( i18n( "Preparing upgrade of %1..." ) );
|
|
else if ( ev == "unpacked" || ev == "half-configured" )
|
|
msg = u8( i18n( "Replacing %1 with new version..." ) );
|
|
}
|
|
} else if ( m_currentOp == OConfigure ) {
|
|
if ( p.markedNewInstall() ) {
|
|
if ( ev == "unpacked" )
|
|
msg = u8( i18n( "Preparing to configure %1..." ) );
|
|
else if ( ev == "half-configured" )
|
|
msg = u8( i18n( "Configuring %1..." ) );
|
|
else if ( ev == "installed" )
|
|
msg = u8( i18n( "Installed %1" ) );
|
|
} else if ( p.markedUpgrade() ) {
|
|
if ( ev == "unpacked" )
|
|
msg = u8( i18n( "Preparing to configure new version of %1..." ) );
|
|
else if ( ev == "half-configured" )
|
|
msg = u8( i18n( "Configuring new version of %1..." ) );
|
|
else if ( ev == "installed" )
|
|
msg = u8( i18n( "Upgraded %1" ) );
|
|
}
|
|
} else if ( m_currentOp == ORemove ) {
|
|
if ( ev == "installed" )
|
|
msg = u8( i18n( "Preparing to remove %1..." ) );
|
|
else if ( ev == "half-configured" || ev == "half-installed" )
|
|
msg = u8( i18n( "Removing %1..." ) );
|
|
else if ( ev == "config-files" || ev == "not-installed" )
|
|
msg = u8( i18n( "Removed %1" ) );
|
|
} else if ( m_currentOp == OPurge ) {
|
|
if ( ev == "config-files" )
|
|
msg = u8( i18n( "Preparing to purge %1..." ) );
|
|
else if ( ev == "not-installed" )
|
|
msg = u8( i18n( "Purged %1" ) );
|
|
}
|
|
|
|
std::cerr << "updateStatus( " << pkg << ", " << ev << ", " << r << ")" << std::endl;
|
|
std::cerr << "updateStatus: msg = " << msg << std::endl;
|
|
std::cerr << "updateStatus: seen = " << m_seenOpCount
|
|
<< ", total = " << m_totalOpCount << std::endl;
|
|
statusChanged( ( m_seenOpCount * 100 ) / m_totalOpCount,
|
|
u8( msg ).arg( pkg ) + ( ( r == "") ? "" : (" (" + r + ")") ) );
|
|
}
|
|
|
|
}
|
|
|
|
#include "dpkgpm-gui.moc"
|