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.
adept/adept/adept/dpkgpm-gui.cpp

258 lines
7.9 KiB

/** -*- C++ -*-
@file adept/dpkgpm-gui.cpp
@author Peter Rockai <me@mornfall.net>
*/
#include <fcntl.h>
#include <iostream>
#include <tqstrlist.h>
#include <tdeapplication.h>
#include <tdelistbox.h>
#include <tdelocale.h>
#include <tdeparts/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;
}
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, TQT_SIGNAL( statusChanged( int, TQString ) ),
this, TQT_SIGNAL( statusChanged( int, TQString ) ) );
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;
TQStrList l;
for (int i = 0; argv[i]; i ++)
l.append( argv[i] );
m_processRunning = true;
connect( m_terminalPart, TQT_SIGNAL( processExited( TDEProcess * ) ),
this, TQT_SLOT( processExit( TDEProcess * ) ) );
connect( m_terminalPart, TQT_SIGNAL( processExited( const TDEProcess * ) ),
this, TQT_SLOT( processExitC( const TDEProcess * ) ) );
connect( m_terminalPart, TQT_SIGNAL( forkedChild() ),
this, TQT_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->tqt_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);
}
TQStrList l;
l.append ("/bin/sh");
l.append ("-c");
l.append (cmd);
if (fP) {
connect( m_terminalPart, TQT_SIGNAL( forkedChild() ),
this, TQT_SLOT( setupScriptPipe() ) );
}
connect( m_terminalPart, TQT_SIGNAL( processExited( TDEProcess * ) ),
this, TQT_SLOT( processExit( TDEProcess * ) ) );
connect( m_terminalPart, TQT_SIGNAL( processExited( const TDEProcess * ) ),
this, TQT_SLOT( processExitC( const TDEProcess * ) ) );
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(TDEProcess *p) {
processExitC( p );
}
void DPkgPM::processExitC(const TDEProcess *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);
TQStrList 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"