Logo Search packages:      
Sourcecode: adept version File versions  Download package

dpkgpm-gui.cpp

/** -*- 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"

Generated by  Doxygen 1.6.0   Back to index