|
|
|
/*
|
|
|
|
*
|
|
|
|
* $Id: k3bdefaultexternalprograms.cpp 731898 2007-11-02 08:22:18Z trueg $
|
|
|
|
* Copyright (C) 2003-2007 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 "k3bdefaultexternalprograms.h"
|
|
|
|
#include "k3bexternalbinmanager.h"
|
|
|
|
#include <k3bglobals.h>
|
|
|
|
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqfileinfo.h>
|
|
|
|
#include <tqobject.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
|
|
|
|
#include <k3bprocess.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void K3b::addDefaultPrograms( K3bExternalBinManager* m )
|
|
|
|
{
|
|
|
|
m->addProgram( new K3bCdrecordProgram(false) );
|
|
|
|
m->addProgram( new K3bMkisofsProgram() );
|
|
|
|
m->addProgram( new K3bReadcdProgram() );
|
|
|
|
m->addProgram( new K3bCdrdaoProgram() );
|
|
|
|
m->addProgram( new K3bGrowisofsProgram() );
|
|
|
|
m->addProgram( new K3bDvdformatProgram() );
|
|
|
|
// m->addProgram( new K3bDvdBooktypeProgram() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3b::addTranscodePrograms( K3bExternalBinManager* m )
|
|
|
|
{
|
|
|
|
static const char* transcodeTools[] = { "transcode",
|
|
|
|
0, // K3b 1.0 only uses the transcode binary
|
|
|
|
"tcprobe",
|
|
|
|
"tccat",
|
|
|
|
"tcscan",
|
|
|
|
"tcextract",
|
|
|
|
"tcdecode",
|
|
|
|
0 };
|
|
|
|
|
|
|
|
for( int i = 0; transcodeTools[i]; ++i )
|
|
|
|
m->addProgram( new K3bTranscodeProgram( transcodeTools[i] ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3b::addVcdimagerPrograms( K3bExternalBinManager* m )
|
|
|
|
{
|
|
|
|
// don't know if we need more vcdTools in the future (vcdxrip)
|
|
|
|
static const char* vcdTools[] = { "vcdxbuild",
|
|
|
|
"vcdxminfo",
|
|
|
|
"vcdxrip",
|
|
|
|
0 };
|
|
|
|
|
|
|
|
for( int i = 0; vcdTools[i]; ++i )
|
|
|
|
m->addProgram( new K3bVcdbuilderProgram( vcdTools[i] ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bCdrecordProgram::K3bCdrecordProgram( bool dvdPro )
|
|
|
|
: K3bExternalProgram( dvdPro ? "cdrecord-prodvd" : "cdrecord" ),
|
|
|
|
m_dvdPro(dvdPro)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// This is a hack for Debian based systems which use
|
|
|
|
// a wrapper cdrecord script to call cdrecord.mmap or cdrecord.shm
|
|
|
|
// depending on the kernel version.
|
|
|
|
// For 2.0.x and 2.2.x kernels the shm version is used. In all
|
|
|
|
// other cases it's the mmap version.
|
|
|
|
//
|
|
|
|
// But since it may be that someone manually installed cdrecord
|
|
|
|
// replacing the wrapper we check if cdrecord is a script.
|
|
|
|
//
|
|
|
|
static TQString& debianWeirdnessHack( TQString& path )
|
|
|
|
{
|
|
|
|
if( TQFile::exists( path + ".mmap" ) ) {
|
|
|
|
kdDebug() << "(K3bCdrecordProgram) checking for Debian cdrecord wrapper script." << endl;
|
|
|
|
if( TQFileInfo( path ).size() < 1024 ) {
|
|
|
|
kdDebug() << "(K3bCdrecordProgram) Debian Wrapper script size fits. Checking file." << endl;
|
|
|
|
TQFile f( path );
|
|
|
|
f.open( IO_ReadOnly );
|
|
|
|
TQString s = TQTextStream( &f ).read();
|
|
|
|
if( s.contains( "cdrecord.mmap" ) && s.contains( "cdrecord.shm" ) ) {
|
|
|
|
kdDebug() << "(K3bCdrecordProgram) Found Debian Wrapper script." << endl;
|
|
|
|
TQString ext;
|
|
|
|
if( K3b::kernelVersion().versionString().left(3) > "2.2" )
|
|
|
|
ext = ".mmap";
|
|
|
|
else
|
|
|
|
ext = ".shm";
|
|
|
|
|
|
|
|
kdDebug() << "(K3bCdrecordProgram) Using cdrecord" << ext << endl;
|
|
|
|
|
|
|
|
path += ext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool K3bCdrecordProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bool wodim = false;
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
|
|
|
|
if( TQFile::exists( path + "wodim" ) ) {
|
|
|
|
wodim = true;
|
|
|
|
path += "wodim";
|
|
|
|
}
|
|
|
|
else if( TQFile::exists( path + "cdrecord" ) ) {
|
|
|
|
path += "cdrecord";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
debianWeirdnessHack( path );
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
|
|
|
|
vp << path << "-version";
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = -1;
|
|
|
|
if( wodim ) {
|
|
|
|
pos = out.output().find( "Wodim" );
|
|
|
|
}
|
|
|
|
else if( m_dvdPro ) {
|
|
|
|
pos = out.output().find( "Cdrecord-ProDVD" );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pos = out.output().find( "Cdrecord" );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos = out.output().find( TQRegExp("[0-9]"), pos );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int endPos = out.output().find( TQRegExp("\\s"), pos+1 );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos );
|
|
|
|
|
|
|
|
if( wodim )
|
|
|
|
bin->addFeature( "wodim" );
|
|
|
|
|
|
|
|
pos = out.output().find( "Copyright") + 14;
|
|
|
|
endPos = out.output().find( "\n", pos );
|
|
|
|
|
|
|
|
// cdrecord does not use local encoding for the copyright statement but plain latin1
|
|
|
|
bin->copyright = TQString::fromLatin1( out.output().mid( pos, endPos-pos ).local8Bit() ).stripWhiteSpace();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bCdrecordProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !m_dvdPro && bin->version.suffix().endsWith( "-dvd" ) ) {
|
|
|
|
bin->addFeature( "dvd-patch" );
|
|
|
|
bin->version = TQString(bin->version.versionString()).remove("-dvd");
|
|
|
|
}
|
|
|
|
|
|
|
|
// probe features
|
|
|
|
TDEProcess fp;
|
|
|
|
out.setProcess( &fp );
|
|
|
|
fp << path << "-help";
|
|
|
|
if( fp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
if( out.output().contains( "gracetime" ) )
|
|
|
|
bin->addFeature( "gracetime" );
|
|
|
|
if( out.output().contains( "-overburn" ) )
|
|
|
|
bin->addFeature( "overburn" );
|
|
|
|
if( out.output().contains( "-text" ) )
|
|
|
|
bin->addFeature( "cdtext" );
|
|
|
|
if( out.output().contains( "-clone" ) )
|
|
|
|
bin->addFeature( "clone" );
|
|
|
|
if( out.output().contains( "-tao" ) )
|
|
|
|
bin->addFeature( "tao" );
|
|
|
|
if( out.output().contains( "cuefile=" ) &&
|
|
|
|
( wodim || bin->version > K3bVersion( 2, 1, -1, "a14") ) ) // cuefile handling was still buggy in a14
|
|
|
|
bin->addFeature( "cuefile" );
|
|
|
|
|
|
|
|
// new mode 2 options since cdrecord 2.01a12
|
|
|
|
// we use both checks here since the help was not updated in 2.01a12 yet (well, I
|
|
|
|
// just double-checked and the help page is proper but there is no harm in having
|
|
|
|
// two checks)
|
|
|
|
// and the version check does not handle versions like 2.01-dvd properly
|
|
|
|
if( out.output().contains( "-xamix" ) ||
|
|
|
|
bin->version >= K3bVersion( 2, 1, -1, "a12" ) ||
|
|
|
|
wodim )
|
|
|
|
bin->addFeature( "xamix" );
|
|
|
|
|
|
|
|
// check if we run cdrecord as root
|
|
|
|
struct stat s;
|
|
|
|
if( !::stat( TQFile::encodeName(path), &s ) ) {
|
|
|
|
if( (s.st_mode & S_ISUID) && s.st_uid == 0 )
|
|
|
|
bin->addFeature( "suidroot" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bCdrecordProgram) could not start " << bin->path << endl;
|
|
|
|
delete bin;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bin->version < K3bVersion( 2, 0 ) && !wodim )
|
|
|
|
bin->addFeature( "outdated" );
|
|
|
|
|
|
|
|
// FIXME: are these version correct?
|
|
|
|
if( bin->version >= K3bVersion("1.11a38") || wodim )
|
|
|
|
bin->addFeature( "plain-atapi" );
|
|
|
|
if( bin->version > K3bVersion("1.11a17") || wodim )
|
|
|
|
bin->addFeature( "hacked-atapi" );
|
|
|
|
|
|
|
|
if( bin->version >= K3bVersion( 2, 1, 1, "a02" ) || wodim )
|
|
|
|
bin->addFeature( "short-track-raw" );
|
|
|
|
|
|
|
|
if( bin->version >= K3bVersion( 2, 1, -1, "a13" ) || wodim )
|
|
|
|
bin->addFeature( "audio-stdin" );
|
|
|
|
|
|
|
|
if( bin->version >= K3bVersion( "1.11a02" ) || wodim )
|
|
|
|
bin->addFeature( "burnfree" );
|
|
|
|
else
|
|
|
|
bin->addFeature( "burnproof" );
|
|
|
|
|
|
|
|
addBin( bin );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
K3bMkisofsProgram::K3bMkisofsProgram()
|
|
|
|
: K3bExternalProgram( "mkisofs" )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool K3bMkisofsProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bool genisoimage = false;
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
|
|
|
|
if( TQFile::exists( path + "genisoimage" ) ) {
|
|
|
|
genisoimage = true;
|
|
|
|
path += "genisoimage";
|
|
|
|
}
|
|
|
|
else if( TQFile::exists( path + "mkisofs" ) ) {
|
|
|
|
path += "mkisofs";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
vp << path << "-version";
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = -1;
|
|
|
|
if( genisoimage )
|
|
|
|
pos = out.output().find( "genisoimage" );
|
|
|
|
else
|
|
|
|
pos = out.output().find( "mkisofs" );
|
|
|
|
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos = out.output().find( TQRegExp("[0-9]"), pos );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int endPos = out.output().find( ' ', pos+1 );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos );
|
|
|
|
|
|
|
|
if( genisoimage )
|
|
|
|
bin->addFeature( "genisoimage" );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bMkisofsProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// probe features
|
|
|
|
TDEProcess fp;
|
|
|
|
fp << path << "-help";
|
|
|
|
out.setProcess( &fp );
|
|
|
|
if( fp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
if( out.output().contains( "-udf" ) )
|
|
|
|
bin->addFeature( "udf" );
|
|
|
|
if( out.output().contains( "-dvd-video" ) )
|
|
|
|
bin->addFeature( "dvd-video" );
|
|
|
|
if( out.output().contains( "-joliet-long" ) )
|
|
|
|
bin->addFeature( "joliet-long" );
|
|
|
|
if( out.output().contains( "-xa" ) )
|
|
|
|
bin->addFeature( "xa" );
|
|
|
|
if( out.output().contains( "-sectype" ) )
|
|
|
|
bin->addFeature( "sectype" );
|
|
|
|
|
|
|
|
// check if we run mkisofs as root
|
|
|
|
struct stat s;
|
|
|
|
if( !::stat( TQFile::encodeName(path), &s ) ) {
|
|
|
|
if( (s.st_mode & S_ISUID) && s.st_uid == 0 )
|
|
|
|
bin->addFeature( "suidroot" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bMkisofsProgram) could not start " << bin->path << endl;
|
|
|
|
delete bin;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bin->version < K3bVersion( 1, 14) && !genisoimage )
|
|
|
|
bin->addFeature( "outdated" );
|
|
|
|
|
|
|
|
if( bin->version >= K3bVersion( 1, 15, -1, "a40" ) || genisoimage )
|
|
|
|
bin->addFeature( "backslashed_filenames" );
|
|
|
|
|
|
|
|
if ( genisoimage && bin->version >= K3bVersion( 1, 1, 4 ) )
|
|
|
|
bin->addFeature( "no-4gb-limit" );
|
|
|
|
|
|
|
|
if ( !genisoimage && bin->version >= K3bVersion( 2, 1, 1, "a32" ) )
|
|
|
|
bin->addFeature( "no-4gb-limit" );
|
|
|
|
|
|
|
|
addBin(bin);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bReadcdProgram::K3bReadcdProgram()
|
|
|
|
: K3bExternalProgram( "readcd" )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool K3bReadcdProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bool readom = false;
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
|
|
|
|
if( TQFile::exists( path + "readom" ) ) {
|
|
|
|
readom = true;
|
|
|
|
path += "readom";
|
|
|
|
}
|
|
|
|
else if( TQFile::exists( path + "readcd" ) ) {
|
|
|
|
path += "readcd";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !TQFile::exists( path ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
vp << path << "-version";
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = -1;
|
|
|
|
if( readom )
|
|
|
|
pos = out.output().find( "readom" );
|
|
|
|
else
|
|
|
|
pos = out.output().find( "readcd" );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos = out.output().find( TQRegExp("[0-9]"), pos );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int endPos = out.output().find( ' ', pos+1 );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos );
|
|
|
|
|
|
|
|
if( readom )
|
|
|
|
bin->addFeature( "readom" );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bMkisofsProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// probe features
|
|
|
|
TDEProcess fp;
|
|
|
|
fp << path << "-help";
|
|
|
|
out.setProcess( &fp );
|
|
|
|
if( fp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
if( out.output().contains( "-clone" ) )
|
|
|
|
bin->addFeature( "clone" );
|
|
|
|
|
|
|
|
// check if we run mkisofs as root
|
|
|
|
struct stat s;
|
|
|
|
if( !::stat( TQFile::encodeName(path), &s ) ) {
|
|
|
|
if( (s.st_mode & S_ISUID) && s.st_uid == 0 )
|
|
|
|
bin->addFeature( "suidroot" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bReadcdProgram) could not start " << bin->path << endl;
|
|
|
|
delete bin;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME: are these version correct?
|
|
|
|
if( bin->version >= K3bVersion("1.11a38") || readom )
|
|
|
|
bin->addFeature( "plain-atapi" );
|
|
|
|
if( bin->version > K3bVersion("1.11a17") || readom )
|
|
|
|
bin->addFeature( "hacked-atapi" );
|
|
|
|
|
|
|
|
addBin(bin);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bCdrdaoProgram::K3bCdrdaoProgram()
|
|
|
|
: K3bExternalProgram( "cdrdao" )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool K3bCdrdaoProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
path.append("cdrdao");
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !TQFile::exists( path ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
vp << path ;
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = out.output().find( "Cdrdao version" );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos = out.output().find( TQRegExp("[0-9]"), pos );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int endPos = out.output().find( ' ', pos+1 );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos );
|
|
|
|
|
|
|
|
pos = out.output().find( "(C)", endPos+1 ) + 4;
|
|
|
|
endPos = out.output().find( '\n', pos );
|
|
|
|
bin->copyright = out.output().mid( pos, endPos-pos );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bCdrdaoProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// probe features
|
|
|
|
TDEProcess fp;
|
|
|
|
fp << path << "write" << "-h";
|
|
|
|
out.setProcess( &fp );
|
|
|
|
if( fp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
if( out.output().contains( "--overburn" ) )
|
|
|
|
bin->addFeature( "overburn" );
|
|
|
|
if( out.output().contains( "--multi" ) )
|
|
|
|
bin->addFeature( "multisession" );
|
|
|
|
|
|
|
|
if( out.output().contains( "--buffer-under-run-protection" ) )
|
|
|
|
bin->addFeature( "disable-burnproof" );
|
|
|
|
|
|
|
|
// check if we run cdrdao as root
|
|
|
|
struct stat s;
|
|
|
|
if( !::stat( TQFile::encodeName(path), &s ) ) {
|
|
|
|
if( (s.st_mode & S_ISUID) && s.st_uid == 0 )
|
|
|
|
bin->addFeature( "suidroot" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bCdrdaoProgram) could not start " << bin->path << endl;
|
|
|
|
delete bin;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SuSE 9.0 ships with a patched cdrdao 1.1.7 which contains an updated libschily
|
|
|
|
// Gentoo ships with a patched cdrdao 1.1.7 which contains scglib support
|
|
|
|
if( bin->version > K3bVersion( 1, 1, 7 ) ||
|
|
|
|
bin->version == K3bVersion( 1, 1, 7, "-gentoo" ) ||
|
|
|
|
bin->version == K3bVersion( 1, 1, 7, "-suse" ) ) {
|
|
|
|
// bin->addFeature( "plain-atapi" );
|
|
|
|
bin->addFeature( "hacked-atapi" );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bin->version >= K3bVersion( 1, 1, 8 ) )
|
|
|
|
bin->addFeature( "plain-atapi" );
|
|
|
|
|
|
|
|
addBin(bin);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bTranscodeProgram::K3bTranscodeProgram( const TQString& transcodeProgram )
|
|
|
|
: K3bExternalProgram( transcodeProgram ),
|
|
|
|
m_transcodeProgram( transcodeProgram )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool K3bTranscodeProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQString path = p;
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
|
|
|
|
TQString appPath = path + m_transcodeProgram;
|
|
|
|
|
|
|
|
if( !TQFile::exists( appPath ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
vp << appPath << "-v";
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = out.output().find( "transcode v" );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos += 11;
|
|
|
|
|
|
|
|
int endPos = out.output().find( TQRegExp("[\\s\\)]"), pos+1 );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = appPath;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bTranscodeProgram) could not start " << appPath << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Check features
|
|
|
|
//
|
|
|
|
TQString modInfoBin = path + "tcmodinfo";
|
|
|
|
TDEProcess modp;
|
|
|
|
modp << modInfoBin << "-p";
|
|
|
|
out.setProcess( &modp );
|
|
|
|
if( modp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
TQString modPath = out.output().stripWhiteSpace();
|
|
|
|
TQDir modDir( modPath );
|
|
|
|
if( !modDir.entryList( "*export_xvid*", TQDir::Files ).isEmpty() )
|
|
|
|
bin->addFeature( "xvid" );
|
|
|
|
if( !modDir.entryList( "*export_lame*", TQDir::Files ).isEmpty() )
|
|
|
|
bin->addFeature( "lame" );
|
|
|
|
if( !modDir.entryList( "*export_ffmpeg*", TQDir::Files ).isEmpty() )
|
|
|
|
bin->addFeature( "ffmpeg" );
|
|
|
|
if( !modDir.entryList( "*export_ac3*", TQDir::Files ).isEmpty() )
|
|
|
|
bin->addFeature( "ac3" );
|
|
|
|
}
|
|
|
|
|
|
|
|
addBin(bin);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
K3bVcdbuilderProgram::K3bVcdbuilderProgram( const TQString& p )
|
|
|
|
: K3bExternalProgram( p ),
|
|
|
|
m_vcdbuilderProgram( p )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool K3bVcdbuilderProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
path.append(m_vcdbuilderProgram);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !TQFile::exists( path ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
vp << path << "-V";
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = out.output().find( "GNU VCDImager" );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos += 14;
|
|
|
|
|
|
|
|
int endPos = out.output().find( TQRegExp("[\\n\\)]"), pos+1 );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos ).stripWhiteSpace();
|
|
|
|
|
|
|
|
pos = out.output().find( "Copyright" ) + 14;
|
|
|
|
endPos = out.output().find( "\n", pos );
|
|
|
|
bin->copyright = out.output().mid( pos, endPos-pos ).stripWhiteSpace();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bVcdbuilderProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
addBin(bin);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bNormalizeProgram::K3bNormalizeProgram()
|
|
|
|
: K3bExternalProgram( "normalize-audio" )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool K3bNormalizeProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
path.append("normalize-audio");
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !TQFile::exists( path ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
|
|
|
|
vp << path << "--version";
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = out.output().find( "normalize" );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos = out.output().find( TQRegExp("\\d"), pos );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int endPos = out.output().find( TQRegExp("\\s"), pos+1 );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos );
|
|
|
|
|
|
|
|
pos = out.output().find( "Copyright" )+14;
|
|
|
|
endPos = out.output().find( "\n", pos );
|
|
|
|
bin->copyright = out.output().mid( pos, endPos-pos ).stripWhiteSpace();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bCdrecordProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
addBin( bin );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bGrowisofsProgram::K3bGrowisofsProgram()
|
|
|
|
: K3bExternalProgram( "growisofs" )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool K3bGrowisofsProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
path.append("growisofs");
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !TQFile::exists( path ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
|
|
|
|
vp << path << "-version";
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = out.output().find( "growisofs" );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos = out.output().find( TQRegExp("\\d"), pos );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int endPos = out.output().find( ",", pos+1 );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bGrowisofsProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// fixed Copyright:
|
|
|
|
bin->copyright = "Andy Polyakov <appro@fy.chalmers.se>";
|
|
|
|
|
|
|
|
// check if we run growisofs as root
|
|
|
|
struct stat s;
|
|
|
|
if( !::stat( TQFile::encodeName(path), &s ) ) {
|
|
|
|
if( (s.st_mode & S_ISUID) && s.st_uid == 0 )
|
|
|
|
bin->addFeature( "suidroot" );
|
|
|
|
}
|
|
|
|
|
|
|
|
addBin( bin );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bDvdformatProgram::K3bDvdformatProgram()
|
|
|
|
: K3bExternalProgram( "dvd+rw-format" )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool K3bDvdformatProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
path.append("dvd+rw-format");
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !TQFile::exists( path ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
|
|
|
|
vp << path;
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
// different locales make searching for the +- char difficult
|
|
|
|
// so we simply ignore it.
|
|
|
|
int pos = out.output().find( TQRegExp("DVD.*RAM format utility") );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos = out.output().find( "version", pos );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos += 8;
|
|
|
|
|
|
|
|
// the version ends in a dot.
|
|
|
|
int endPos = out.output().find( TQRegExp("\\.\\D"), pos );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bDvdformatProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// fixed Copyright:
|
|
|
|
bin->copyright = "Andy Polyakov <appro@fy.chalmers.se>";
|
|
|
|
|
|
|
|
// check if we run dvd+rw-format as root
|
|
|
|
struct stat s;
|
|
|
|
if( !::stat( TQFile::encodeName(path), &s ) ) {
|
|
|
|
if( (s.st_mode & S_ISUID) && s.st_uid == 0 )
|
|
|
|
bin->addFeature( "suidroot" );
|
|
|
|
}
|
|
|
|
|
|
|
|
addBin( bin );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bDvdBooktypeProgram::K3bDvdBooktypeProgram()
|
|
|
|
: K3bExternalProgram( "dvd+rw-booktype" )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool K3bDvdBooktypeProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
path.append("dvd+rw-booktype");
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !TQFile::exists( path ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
|
|
|
|
vp << path;
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = out.output().find( "dvd+rw-booktype" );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
// No version information. Create dummy version
|
|
|
|
bin->version = K3bVersion( 1, 0, 0 );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bDvdBooktypeProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
addBin( bin );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
K3bCdda2wavProgram::K3bCdda2wavProgram()
|
|
|
|
: K3bExternalProgram( "cdda2wav" )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool K3bCdda2wavProgram::scan( const TQString& p )
|
|
|
|
{
|
|
|
|
if( p.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQString path = p;
|
|
|
|
TQFileInfo fi( path );
|
|
|
|
if( fi.isDir() ) {
|
|
|
|
if( path[path.length()-1] != '/' )
|
|
|
|
path.append("/");
|
|
|
|
path.append("cdda2wav");
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !TQFile::exists( path ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
K3bExternalBin* bin = 0;
|
|
|
|
|
|
|
|
// probe version
|
|
|
|
TDEProcess vp;
|
|
|
|
K3bProcessOutputCollector out( &vp );
|
|
|
|
|
|
|
|
vp << path << "-h";
|
|
|
|
if( vp.start( TDEProcess::Block, TDEProcess::AllOutput ) ) {
|
|
|
|
int pos = out.output().find( "cdda2wav" );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos = out.output().find( "Version", pos );
|
|
|
|
if( pos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pos += 8;
|
|
|
|
|
|
|
|
// the version does not end in a space but the kernel info
|
|
|
|
int endPos = out.output().find( TQRegExp("[^\\d\\.]"), pos );
|
|
|
|
if( endPos < 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bin = new K3bExternalBin( this );
|
|
|
|
bin->path = path;
|
|
|
|
bin->version = out.output().mid( pos, endPos-pos );
|
|
|
|
|
|
|
|
// features (we do this since the cdda2wav help says that the short
|
|
|
|
// options will disappear soon)
|
|
|
|
if( out.output().find( "-info-only" ) )
|
|
|
|
bin->addFeature( "info-only" ); // otherwise use the -J option
|
|
|
|
if( out.output().find( "-no-infofile" ) )
|
|
|
|
bin->addFeature( "no-infofile" ); // otherwise use the -H option
|
|
|
|
if( out.output().find( "-gui" ) )
|
|
|
|
bin->addFeature( "gui" ); // otherwise use the -g option
|
|
|
|
if( out.output().find( "-bulk" ) )
|
|
|
|
bin->addFeature( "bulk" ); // otherwise use the -B option
|
|
|
|
if( out.output().find( "dev=" ) )
|
|
|
|
bin->addFeature( "dev" ); // otherwise use the -B option
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kdDebug() << "(K3bCdda2wavProgram) could not start " << path << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if we run as root
|
|
|
|
struct stat s;
|
|
|
|
if( !::stat( TQFile::encodeName(path), &s ) ) {
|
|
|
|
if( (s.st_mode & S_ISUID) && s.st_uid == 0 )
|
|
|
|
bin->addFeature( "suidroot" );
|
|
|
|
}
|
|
|
|
|
|
|
|
addBin( bin );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|