summaryrefslogtreecommitdiffstats
path: root/libk3b/core/k3bglobals.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-03 02:15:56 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-03 02:15:56 +0000
commit50b48aec6ddd451a6d1709c0942477b503457663 (patch)
treea9ece53ec06fd0a2819de7a2a6de997193566626 /libk3b/core/k3bglobals.cpp
downloadk3b-50b48aec6ddd451a6d1709c0942477b503457663.tar.gz
k3b-50b48aec6ddd451a6d1709c0942477b503457663.zip
Added abandoned KDE3 version of K3B
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k3b@1084400 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'libk3b/core/k3bglobals.cpp')
-rw-r--r--libk3b/core/k3bglobals.cpp634
1 files changed, 634 insertions, 0 deletions
diff --git a/libk3b/core/k3bglobals.cpp b/libk3b/core/k3bglobals.cpp
new file mode 100644
index 0000000..fc5a4e1
--- /dev/null
+++ b/libk3b/core/k3bglobals.cpp
@@ -0,0 +1,634 @@
+/*
+ *
+ * $Id: k3bglobals.cpp 659634 2007-04-30 14:51:32Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <[email protected]>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]>
+ *
+ * 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 <config.h>
+
+
+#include "k3bglobals.h"
+#include <k3bversion.h>
+#include <k3bdevice.h>
+#include <k3bdevicemanager.h>
+#include <k3bdeviceglobals.h>
+#include <k3bexternalbinmanager.h>
+#include <k3bcore.h>
+#include <k3bhalconnection.h>
+
+#include <kdeversion.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kio/job.h>
+#include <kio/netaccess.h>
+#include <kurl.h>
+#include <dcopref.h>
+#include <kprocess.h>
+
+#include <qdatastream.h>
+#include <qdir.h>
+#include <qfile.h>
+
+#include <cmath>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+# include <sys/param.h>
+# include <sys/mount.h>
+# include <sys/endian.h>
+# define bswap_16(x) bswap16(x)
+# define bswap_32(x) bswap32(x)
+# define bswap_64(x) bswap64(x)
+#else
+# include <byteswap.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+# include <sys/statvfs.h>
+#endif
+#ifdef HAVE_SYS_VFS_H
+# include <sys/vfs.h>
+#endif
+
+
+/*
+struct Sample {
+ unsigned char msbLeft;
+ unsigned char lsbLeft;
+ unsigned char msbRight;
+ unsigned char lsbRight;
+
+ short left() const {
+ return ( msbLeft << 8 ) | lsbLeft;
+ }
+ short right() const {
+ return ( msbRight << 8 ) | lsbRight;
+ }
+ void left( short d ) {
+ msbLeft = d >> 8;
+ lsbLeft = d;
+ }
+ void right( short d ) {
+ msbRight = d >> 8;
+ lsbRight = d;
+ }
+};
+*/
+
+QString K3b::framesToString( int h, bool showFrames )
+{
+ int m = h / 4500;
+ int s = (h % 4500) / 75;
+ int f = h % 75;
+
+ QString str;
+
+ if( showFrames ) {
+ // cdrdao needs the MSF format where 1 second has 75 frames!
+ str.sprintf( "%.2i:%.2i:%.2i", m, s, f );
+ }
+ else
+ str.sprintf( "%.2i:%.2i", m, s );
+
+ return str;
+}
+
+/*QString K3b::sizeToTime(long size)
+{
+ int h = size / sizeof(Sample) / 588;
+ return framesToString(h, false);
+}*/
+
+
+Q_INT16 K3b::swapByteOrder( const Q_INT16& i )
+{
+ return bswap_16( i );
+ //((i << 8) & 0xff00) | ((i >> 8 ) & 0xff);
+}
+
+
+Q_INT32 K3b::swapByteOrder( const Q_INT32& i )
+{
+ //return ((i << 24) & 0xff000000) | ((i << 8) & 0xff0000) | ((i >> 8) & 0xff00) | ((i >> 24) & 0xff );
+ return bswap_32( i );
+}
+
+
+Q_INT64 K3b::swapByteOrder( const Q_INT64& i )
+{
+ return bswap_64( i );
+}
+
+
+int K3b::round( double d )
+{
+ return (int)( floor(d) + 0.5 <= d ? ceil(d) : floor(d) );
+}
+
+
+QString K3b::findUniqueFilePrefix( const QString& _prefix, const QString& path )
+{
+ QString url;
+ if( path.isEmpty() || !QFile::exists(path) )
+ url = defaultTempPath();
+ else
+ url = prepareDir( path );
+
+ QString prefix = _prefix;
+ if( prefix.isEmpty() )
+ prefix = "k3b_";
+
+ // now create the unique prefix
+ QDir dir( url );
+ QStringList entries = dir.entryList( QDir::DefaultFilter, QDir::Name );
+ int i = 0;
+ for( QStringList::iterator it = entries.begin();
+ it != entries.end(); ++it ) {
+ if( (*it).startsWith( prefix + QString::number(i) ) ) {
+ i++;
+ it = entries.begin();
+ }
+ }
+
+ return url + prefix + QString::number(i);
+}
+
+
+QString K3b::findTempFile( const QString& ending, const QString& d )
+{
+ return findUniqueFilePrefix( "k3b_", d ) + ( ending.isEmpty() ? QString::null : (QString::fromLatin1(".") + ending) );
+}
+
+
+QString K3b::defaultTempPath()
+{
+ QString oldGroup = kapp->config()->group();
+ kapp->config()->setGroup( "General Options" );
+ QString url = kapp->config()->readPathEntry( "Temp Dir", KGlobal::dirs()->resourceDirs( "tmp" ).first() );
+ kapp->config()->setGroup( oldGroup );
+ return prepareDir(url);
+}
+
+
+QString K3b::prepareDir( const QString& dir )
+{
+ return (dir + (dir[dir.length()-1] != '/' ? "/" : ""));
+}
+
+
+QString K3b::parentDir( const QString& path )
+{
+ QString parent = path;
+ if( path[path.length()-1] == '/' )
+ parent.truncate( parent.length()-1 );
+
+ int pos = parent.findRev( '/' );
+ if( pos >= 0 )
+ parent.truncate( pos+1 );
+ else // relative path, do anything...
+ parent = "/";
+
+ return parent;
+}
+
+
+QString K3b::fixupPath( const QString& path )
+{
+ QString s;
+ bool lastWasSlash = false;
+ for( unsigned int i = 0; i < path.length(); ++i ) {
+ if( path[i] == '/' ) {
+ if( !lastWasSlash ) {
+ lastWasSlash = true;
+ s.append( "/" );
+ }
+ }
+ else {
+ lastWasSlash = false;
+ s.append( path[i] );
+ }
+ }
+
+ return s;
+}
+
+
+K3bVersion K3b::kernelVersion()
+{
+ // initialize kernel version
+ K3bVersion v;
+ utsname unameinfo;
+ if( ::uname(&unameinfo) == 0 ) {
+ v = QString::fromLocal8Bit( unameinfo.release );
+ kdDebug() << "kernel version: " << v << endl;
+ }
+ else
+ kdError() << "could not determine kernel version." << endl;
+ return v;
+}
+
+
+K3bVersion K3b::simpleKernelVersion()
+{
+ return kernelVersion().simplify();
+}
+
+
+QString K3b::systemName()
+{
+ QString v;
+ utsname unameinfo;
+ if( ::uname(&unameinfo) == 0 ) {
+ v = QString::fromLocal8Bit( unameinfo.sysname );
+ }
+ else
+ kdError() << "could not determine system name." << endl;
+ return v;
+}
+
+
+bool K3b::kbFreeOnFs( const QString& path, unsigned long& size, unsigned long& avail )
+{
+ struct statvfs fs;
+ if( ::statvfs( QFile::encodeName(path), &fs ) == 0 ) {
+ unsigned long kBfak = fs.f_frsize/1024;
+
+ size = fs.f_blocks*kBfak;
+ avail = fs.f_bavail*kBfak;
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
+KIO::filesize_t K3b::filesize( const KURL& url )
+{
+ if( url.isLocalFile() ) {
+ k3b_struct_stat buf;
+ if ( !k3b_stat( QFile::encodeName( url.path() ), &buf ) ) {
+ return (KIO::filesize_t)buf.st_size;
+ }
+ }
+
+ KIO::UDSEntry uds;
+ KIO::NetAccess::stat( url, uds, 0 );
+ for( KIO::UDSEntry::const_iterator it = uds.begin(); it != uds.end(); ++it ) {
+ if( (*it).m_uds == KIO::UDS_SIZE ) {
+ return (*it).m_long;
+ }
+ }
+
+ return ( KIO::filesize_t )0;
+}
+
+
+KIO::filesize_t K3b::imageFilesize( const KURL& url )
+{
+ KIO::filesize_t size = K3b::filesize( url );
+ int cnt = 0;
+ while( KIO::NetAccess::exists( KURL::fromPathOrURL( url.url() + '.' + QString::number(cnt).rightJustify( 3, '0' ) ), true ) )
+ size += K3b::filesize( KURL::fromPathOrURL( url.url() + '.' + QString::number(cnt++).rightJustify( 3, '0' ) ) );
+ return size;
+}
+
+
+QString K3b::cutFilename( const QString& name, unsigned int len )
+{
+ if( name.length() > len ) {
+ QString ret = name;
+
+ // determine extension (we think of an extension to be at most 5 chars in length)
+ int pos = name.find( '.', -6 );
+ if( pos > 0 )
+ len -= (name.length() - pos);
+
+ ret.truncate( len );
+
+ if( pos > 0 )
+ ret.append( name.mid( pos ) );
+
+ return ret;
+ }
+ else
+ return name;
+}
+
+
+QString K3b::removeFilenameExtension( const QString& name )
+{
+ QString v = name;
+ int dotpos = v.findRev( '.' );
+ if( dotpos > 0 )
+ v.truncate( dotpos );
+ return v;
+}
+
+
+QString K3b::appendNumberToFilename( const QString& name, int num, unsigned int maxlen )
+{
+ // determine extension (we think of an extension to be at most 5 chars in length)
+ QString result = name;
+ QString ext;
+ int pos = name.find( '.', -6 );
+ if( pos > 0 ) {
+ ext = name.mid(pos);
+ result.truncate( pos );
+ }
+
+ ext.prepend( QString::number(num) );
+ result.truncate( maxlen - ext.length() );
+
+ return result + ext;
+}
+
+
+bool K3b::plainAtapiSupport()
+{
+ // FIXME: what about BSD?
+ return ( K3b::simpleKernelVersion() >= K3bVersion( 2, 5, 40 ) );
+}
+
+
+bool K3b::hackedAtapiSupport()
+{
+ // IMPROVEME!!!
+ // FIXME: since when does the kernel support this?
+ return ( K3b::simpleKernelVersion() >= K3bVersion( 2, 4, 0 ) );
+}
+
+
+QString K3b::externalBinDeviceParameter( K3bDevice::Device* dev, const K3bExternalBin* bin )
+{
+#ifdef Q_OS_LINUX
+ //
+ // experimental: always use block devices on 2.6 kernels
+ //
+ if( simpleKernelVersion() >= K3bVersion( 2, 6, 0 ) )
+ return dev->blockDeviceName();
+ else
+#endif
+ if( dev->interfaceType() == K3bDevice::SCSI )
+ return dev->busTargetLun();
+ else if( (plainAtapiSupport() && bin->hasFeature("plain-atapi") ) )
+ return dev->blockDeviceName();
+ else
+ return QString("ATAPI:%1").arg(dev->blockDeviceName());
+}
+
+
+int K3b::writingAppFromString( const QString& s )
+{
+ if( s.lower() == "cdrdao" )
+ return K3b::CDRDAO;
+ else if( s.lower() == "cdrecord" )
+ return K3b::CDRECORD;
+ else if( s.lower() == "dvdrecord" )
+ return K3b::DVDRECORD;
+ else if( s.lower() == "growisofs" )
+ return K3b::GROWISOFS;
+ else if( s.lower() == "dvd+rw-format" )
+ return K3b::DVD_RW_FORMAT;
+ else
+ return K3b::DEFAULT;
+}
+
+
+QString K3b::writingModeString( int mode )
+{
+ if( mode == WRITING_MODE_AUTO )
+ return i18n("Auto");
+ else
+ return K3bDevice::writingModeString( mode );
+}
+
+
+QString K3b::resolveLink( const QString& file )
+{
+ QFileInfo f( file );
+ QStringList steps( f.absFilePath() );
+ while( f.isSymLink() ) {
+ QString p = f.readLink();
+ if( !p.startsWith( "/" ) )
+ p.prepend( f.dirPath(true) + "/" );
+ f.setFile( p );
+ if( steps.contains( f.absFilePath() ) ) {
+ kdDebug() << "(K3b) symlink loop detected." << endl;
+ break;
+ }
+ else
+ steps.append( f.absFilePath() );
+ }
+ return f.absFilePath();
+}
+
+
+K3bDevice::Device* K3b::urlToDevice( const KURL& deviceUrl )
+{
+ if( deviceUrl.protocol() == "media" || deviceUrl.protocol() == "system" ) {
+ kdDebug() << "(K3b) Asking mediamanager for " << deviceUrl.fileName() << endl;
+ DCOPRef mediamanager("kded", "mediamanager");
+ DCOPReply reply = mediamanager.call("properties(QString)", deviceUrl.fileName());
+ QStringList properties = reply;
+ if( !reply.isValid() || properties.count() < 6 ) {
+ kdError() << "(K3b) Invalid reply from mediamanager" << endl;
+ return 0;
+ }
+ else {
+ kdDebug() << "(K3b) Reply from mediamanager " << properties[5] << endl;
+ return k3bcore->deviceManager()->findDevice( properties[5] );
+ }
+ }
+
+ return k3bcore->deviceManager()->findDevice( deviceUrl.path() );
+}
+
+
+KURL K3b::convertToLocalUrl( const KURL& url )
+{
+ if( !url.isLocalFile() ) {
+#if KDE_IS_VERSION(3,4,91)
+ return KIO::NetAccess::mostLocalURL( url, 0 );
+#else
+#ifndef UDS_LOCAL_PATH
+#define UDS_LOCAL_PATH (72 | KIO::UDS_STRING)
+#else
+ using namespace KIO;
+#endif
+ KIO::UDSEntry e;
+ if( KIO::NetAccess::stat( url, e, 0 ) ) {
+ const KIO::UDSEntry::ConstIterator end = e.end();
+ for( KIO::UDSEntry::ConstIterator it = e.begin(); it != end; ++it ) {
+ if( (*it).m_uds == UDS_LOCAL_PATH && !(*it).m_str.isEmpty() )
+ return KURL::fromPathOrURL( (*it).m_str );
+ }
+ }
+#endif
+ }
+
+ return url;
+}
+
+
+KURL::List K3b::convertToLocalUrls( const KURL::List& urls )
+{
+ KURL::List r;
+ for( KURL::List::const_iterator it = urls.constBegin(); it != urls.constEnd(); ++it )
+ r.append( convertToLocalUrl( *it ) );
+ return r;
+}
+
+
+Q_INT16 K3b::fromLe16( char* data )
+{
+#ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
+ return swapByteOrder( *((Q_INT16*)data) );
+#else
+ return *((Q_INT16*)data);
+#endif
+}
+
+
+Q_INT32 K3b::fromLe32( char* data )
+{
+#ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
+ return swapByteOrder( *((Q_INT32*)data) );
+#else
+ return *((Q_INT32*)data);
+#endif
+}
+
+
+Q_INT64 K3b::fromLe64( char* data )
+{
+#ifdef WORDS_BIGENDIAN // __BYTE_ORDER == __BIG_ENDIAN
+ return swapByteOrder( *((Q_INT64*)data) );
+#else
+ return *((Q_INT64*)data);
+#endif
+}
+
+
+QString K3b::findExe( const QString& name )
+{
+ // first we search the path
+ QString bin = KStandardDirs::findExe( name );
+
+ // then go on with our own little list
+ if( bin.isEmpty() )
+ bin = KStandardDirs::findExe( name, k3bcore->externalBinManager()->searchPath().join(":") );
+
+ return bin;
+}
+
+
+bool K3b::isMounted( K3bDevice::Device* dev )
+{
+ if( !dev )
+ return false;
+
+ return !KIO::findDeviceMountPoint( dev->blockDeviceName() ).isEmpty();
+}
+
+
+bool K3b::unmount( K3bDevice::Device* dev )
+{
+ if( !dev )
+ return false;
+
+ QString mntDev = dev->blockDeviceName();
+
+#if KDE_IS_VERSION(3,4,0)
+ // first try to unmount it the standard way
+ if( KIO::NetAccess::synchronousRun( KIO::unmount( mntDev, false ), 0 ) )
+ return true;
+#endif
+
+ QString umountBin = K3b::findExe( "umount" );
+ if( !umountBin.isEmpty() ) {
+ KProcess p;
+ p << umountBin;
+ p << "-l"; // lazy unmount
+ p << dev->blockDeviceName();
+ p.start( KProcess::Block );
+ if( !p.exitStatus() )
+ return true;
+ }
+
+ // now try pmount
+ QString pumountBin = K3b::findExe( "pumount" );
+ if( !pumountBin.isEmpty() ) {
+ KProcess p;
+ p << pumountBin;
+ p << "-l"; // lazy unmount
+ p << dev->blockDeviceName();
+ p.start( KProcess::Block );
+ return !p.exitStatus();
+ }
+ else {
+#ifdef HAVE_HAL
+ return !K3bDevice::HalConnection::instance()->unmount( dev );
+#else
+ return false;
+#endif
+ }
+}
+
+
+bool K3b::mount( K3bDevice::Device* dev )
+{
+ if( !dev )
+ return false;
+
+ QString mntDev = dev->blockDeviceName();
+
+#if KDE_IS_VERSION(3,4,0)
+ // first try to mount it the standard way
+ if( KIO::NetAccess::synchronousRun( KIO::mount( true, 0, mntDev, false ), 0 ) )
+ return true;
+#endif
+
+#ifdef HAVE_HAL
+ if( !K3bDevice::HalConnection::instance()->mount( dev ) )
+ return true;
+#endif
+
+ // now try pmount
+ QString pmountBin = K3b::findExe( "pmount" );
+ if( !pmountBin.isEmpty() ) {
+ KProcess p;
+ p << pmountBin;
+ p << mntDev;
+ p.start( KProcess::Block );
+ return !p.exitStatus();
+ }
+ return false;
+}
+
+
+bool K3b::eject( K3bDevice::Device* dev )
+{
+#ifdef HAVE_HAL
+ if( !K3bDevice::HalConnection::instance()->eject( dev ) )
+ return true;
+#endif
+
+ if( K3b::isMounted( dev ) )
+ K3b::unmount( dev );
+
+ return dev->eject();
+}