|
|
|
/*
|
|
|
|
*
|
|
|
|
* $Id: k3bmsinfofetcher.cpp 619556 2007-01-03 17:38:12Z trueg $
|
|
|
|
* Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
|
|
|
|
*
|
|
|
|
* This file is part of the K3b project.
|
|
|
|
* Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
* See the file "COPYING" for the exact licensing terms.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "k3bmsinfofetcher.h"
|
|
|
|
|
|
|
|
#include <k3bexternalbinmanager.h>
|
|
|
|
#include <k3bdevicemanager.h>
|
|
|
|
#include <k3bdevicehandler.h>
|
|
|
|
#include <k3bdevice.h>
|
|
|
|
#include <k3bcore.h>
|
|
|
|
#include <k3bglobals.h>
|
|
|
|
#include <k3biso9660.h>
|
|
|
|
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kprocess.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
|
|
|
|
|
|
|
|
K3bMsInfoFetcher::K3bMsInfoFetcher( K3bJobHandler* jh, TQObject* tqparent, const char* name )
|
|
|
|
: K3bJob( jh, tqparent, name ),
|
|
|
|
m_process(0),
|
|
|
|
m_device(0),
|
|
|
|
m_dvd(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bMsInfoFetcher::~K3bMsInfoFetcher()
|
|
|
|
{
|
|
|
|
delete m_process;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bMsInfoFetcher::start()
|
|
|
|
{
|
|
|
|
jobStarted();
|
|
|
|
|
|
|
|
emit infoMessage( i18n("Searching previous session"), K3bJob::INFO );
|
|
|
|
|
|
|
|
if( !k3bcore->externalBinManager()->foundBin( "cdrecord" ) ) {
|
|
|
|
kdDebug() << "(K3bMsInfoFetcher) could not find cdrecord executable" << endl;
|
|
|
|
emit infoMessage( i18n("Could not tqfind %1 executable.").tqarg("cdrecord"), K3bJob::ERROR );
|
|
|
|
jobFinished(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_device == 0 ) {
|
|
|
|
kdDebug() << "(K3bMsInfoFetcher) internal error: No device set!" << endl;
|
|
|
|
jobFinished(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// first we try to determine if it is a dvd. If so we need to
|
|
|
|
// read the info on our own
|
|
|
|
//
|
|
|
|
|
|
|
|
connect( K3bDevice::sendCommand( K3bDevice::DeviceHandler::NG_DISKINFO, m_device ),
|
|
|
|
TQT_SIGNAL(finished(K3bDevice::DeviceHandler*)),
|
|
|
|
this,
|
|
|
|
TQT_SLOT(slotMediaDetectionFinished(K3bDevice::DeviceHandler*)) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bMsInfoFetcher::getMsInfo()
|
|
|
|
{
|
|
|
|
delete m_process;
|
|
|
|
m_process = new KProcess();
|
|
|
|
|
|
|
|
const K3bExternalBin* bin = 0;
|
|
|
|
if( m_dvd ) {
|
|
|
|
// already handled
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bin = k3bcore->externalBinManager()->binObject( "cdrecord" );
|
|
|
|
|
|
|
|
if( !bin ) {
|
|
|
|
emit infoMessage( i18n("Could not tqfind %1 executable.").tqarg( m_dvd ? "dvdrecord" : "cdrecord" ), ERROR );
|
|
|
|
jobFinished(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*m_process << bin->path;
|
|
|
|
|
|
|
|
// add the device (e.g. /dev/sg1)
|
|
|
|
*m_process << TQString("dev=%1").tqarg( K3b::externalBinDeviceParameter(m_device, bin) );
|
|
|
|
|
|
|
|
*m_process << "-msinfo";
|
|
|
|
|
|
|
|
// additional user parameters from config
|
|
|
|
const TQStringList& params = bin->userParameters();
|
|
|
|
for( TQStringList::const_iterator it = params.begin(); it != params.end(); ++it )
|
|
|
|
*m_process << *it;
|
|
|
|
|
|
|
|
kdDebug() << "***** " << bin->name() << " parameters:\n";
|
|
|
|
const TQValueList<TQCString>& args = m_process->args();
|
|
|
|
TQString s;
|
|
|
|
for( TQValueList<TQCString>::const_iterator it = args.begin(); it != args.end(); ++it ) {
|
|
|
|
s += *it + " ";
|
|
|
|
}
|
|
|
|
kdDebug() << s << flush << endl;
|
|
|
|
emit debuggingOutput( "msinfo command:", s );
|
|
|
|
|
|
|
|
|
|
|
|
// connect( m_process, TQT_SIGNAL(receivedStderr(KProcess*, char*, int)),
|
|
|
|
// this, TQT_SLOT(slotCollectOutput(KProcess*, char*, int)) );
|
|
|
|
connect( m_process, TQT_SIGNAL(receivedStdout(KProcess*, char*, int)),
|
|
|
|
this, TQT_SLOT(slotCollectOutput(KProcess*, char*, int)) );
|
|
|
|
connect( m_process, TQT_SIGNAL(processExited(KProcess*)),
|
|
|
|
this, TQT_SLOT(slotProcessExited()) );
|
|
|
|
|
|
|
|
m_msInfo = TQString();
|
|
|
|
m_collectedOutput = TQString();
|
|
|
|
m_canceled = false;
|
|
|
|
|
|
|
|
if( !m_process->start( KProcess::NotifyOnExit, KProcess::AllOutput ) ) {
|
|
|
|
emit infoMessage( i18n("Could not start %1.").tqarg(bin->name()), K3bJob::ERROR );
|
|
|
|
jobFinished(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bMsInfoFetcher::slotMediaDetectionFinished( K3bDevice::DeviceHandler* h )
|
|
|
|
{
|
|
|
|
if( h->success() ) {
|
|
|
|
m_dvd = h->diskInfo().isDvdMedia();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// for now we just default to cd and go on with the detecting
|
|
|
|
m_dvd = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_dvd ) {
|
|
|
|
if( h->diskInfo().mediaType() & (K3bDevice::MEDIA_DVD_PLUS_RW|K3bDevice::MEDIA_DVD_RW_OVWR) ) {
|
|
|
|
// get info from iso filesystem
|
|
|
|
K3bIso9660 iso( m_device, h->toc().last().firstSector().lba() );
|
|
|
|
if( iso.open() ) {
|
|
|
|
unsigned long long nextSession = iso.primaryDescriptor().volumeSpaceSize;
|
|
|
|
// pad to closest 32K boundary
|
|
|
|
nextSession += 15;
|
|
|
|
nextSession /= 16;
|
|
|
|
nextSession *= 16;
|
|
|
|
m_msInfo.sprintf( "16,%llu", nextSession );
|
|
|
|
|
|
|
|
jobFinished( true );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
emit infoMessage( i18n("Could not open Iso9660 filesystem in %1.")
|
|
|
|
.tqarg( m_device->vendor() + " " + m_device->description() ), ERROR );
|
|
|
|
jobFinished( false );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
unsigned int lastSessionStart, nextWritableAdress;
|
|
|
|
if( m_device->getNextWritableAdress( lastSessionStart, nextWritableAdress ) ) {
|
|
|
|
m_msInfo.sprintf( "%u,%u", lastSessionStart+16, nextWritableAdress );
|
|
|
|
jobFinished( true );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
emit infoMessage( i18n("Could not determine next writable address."), ERROR );
|
|
|
|
jobFinished( false );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // call cdrecord
|
|
|
|
getMsInfo();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bMsInfoFetcher::slotProcessExited()
|
|
|
|
{
|
|
|
|
if( m_canceled )
|
|
|
|
return;
|
|
|
|
|
|
|
|
kdDebug() << "(K3bMsInfoFetcher) msinfo fetched" << endl;
|
|
|
|
|
|
|
|
// now parse the output
|
|
|
|
TQString firstLine = m_collectedOutput.left( m_collectedOutput.tqfind("\n") );
|
|
|
|
TQStringList list = TQStringList::split( ",", firstLine );
|
|
|
|
if( list.count() == 2 ) {
|
|
|
|
bool ok1, ok2;
|
|
|
|
m_lastSessionStart = list.first().toInt( &ok1 );
|
|
|
|
m_nextSessionStart = list[1].toInt( &ok2 );
|
|
|
|
if( ok1 && ok2 )
|
|
|
|
m_msInfo = firstLine.stripWhiteSpace();
|
|
|
|
else
|
|
|
|
m_msInfo = TQString();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_msInfo = TQString();
|
|
|
|
}
|
|
|
|
|
|
|
|
kdDebug() << "(K3bMsInfoFetcher) msinfo parsed: " << m_msInfo << endl;
|
|
|
|
|
|
|
|
if( m_msInfo.isEmpty() ) {
|
|
|
|
emit infoMessage( i18n("Could not retrieve multisession information from disk."), K3bJob::ERROR );
|
|
|
|
emit infoMessage( i18n("The disk is either empty or not appendable."), K3bJob::ERROR );
|
|
|
|
jobFinished(false);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
jobFinished(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bMsInfoFetcher::slotCollectOutput( KProcess*, char* output, int len )
|
|
|
|
{
|
|
|
|
emit debuggingOutput( "msinfo", TQString::fromLocal8Bit( output, len ) );
|
|
|
|
|
|
|
|
m_collectedOutput += TQString::fromLocal8Bit( output, len );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bMsInfoFetcher::cancel()
|
|
|
|
{
|
|
|
|
// FIXME: this does not work if the devicehandler is running
|
|
|
|
|
|
|
|
if( m_process )
|
|
|
|
if( m_process->isRunning() ) {
|
|
|
|
m_canceled = true;
|
|
|
|
m_process->kill();
|
|
|
|
emit canceled();
|
|
|
|
jobFinished(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#include "k3bmsinfofetcher.moc"
|