diff options
Diffstat (limited to 'sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.cpp')
-rw-r--r-- | sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.cpp | 541 |
1 files changed, 541 insertions, 0 deletions
diff --git a/sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.cpp b/sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.cpp new file mode 100644 index 000000000000..3f2d5de115e2 --- /dev/null +++ b/sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.cpp @@ -0,0 +1,541 @@ +--- src/core/device/k3bdevicemanager.cpp.orig Sun Nov 2 15:42:06 2003 ++++ src/core/device/k3bdevicemanager.cpp Fri Nov 7 12:35:44 2003 +@@ -33,7 +33,13 @@ + + #include <iostream> + #include <fstab.h> ++#ifndef __FreeBSD__ + #include <mntent.h> ++#else ++#include <sys/param.h> ++#include <sys/ucred.h> ++#include <sys/mount.h> ++#endif + #include <stdio.h> + #include <stdlib.h> + #include <fcntl.h> +@@ -42,6 +48,11 @@ + #include <sys/stat.h> + #include <sys/ioctl.h> + #include <limits.h> ++#ifdef __FreeBSD__ ++#include <osreldate.h> ++#include <ktempfile.h> ++#include <sys/param.h> ++#else + + /* Fix definitions for 2.5 kernels */ + #include <linux/version.h> +@@ -80,6 +91,7 @@ + (SCSI_DISK_MAJOR(M) \ + || (M) == SCSI_CDROM_MAJOR) + #endif /* #ifndef SCSI_BLK_MAJOR */ ++#endif + + class K3bCdDevice::DeviceManager::Private + { +@@ -194,6 +206,22 @@ + { + m_foundDevices = 0; + ++#ifdef __FreeBSD__ ++// What k3b does here is the following: it takes a list of device point, which are good candidates for cd drives ++// and asks their properties. If they are indeed cd drives, they are added to a device list. This does not work ++// on FreeBSD (no corresponding ioctls). Here cdrecord is asked for a list of scsi device, which work as cd ++// drives. The device points of those devices are added to the device list. ++ bsd_scan_devices(false); ++ kdDebug() << "(K3bDeviceManager) analyze found device" << endl; ++ for ( QValueList<BSDDevice>::iterator it = m_devices.begin(); it != m_devices.end(); ++it ) ++ { ++ if( addDevice( (*it).m_name ) ) ++ { ++ kdDebug() << "(K3bDeviceManager) Device " << (*it).m_name << " added" << endl; ++ m_foundDevices++; ++ } ++ } ++#else + QFile info("/proc/sys/dev/cdrom/info"); + QString line,devstring; + info.open(IO_ReadOnly); +@@ -284,6 +312,7 @@ + // m_foundDevices++; + // } + ++#endif + scanFstab(); + + return m_foundDevices; +@@ -426,10 +455,11 @@ + + void K3bCdDevice::DeviceManager::determineCapabilities(K3bDevice *dev) + { ++#ifndef __FreeBSD__ + // we just need to do this for writers since we use it to determine the writing modes + if( !dev->burner() ) + return; +- ++#endif + + // we do not use the user configured cdrecord here since we want to make sure + // to get all the capabilities of the system +@@ -480,9 +510,17 @@ + dev->m_burner = true; + dev->m_writeModes = 0; + QStringList lines = QStringList::split( "\n", m_processOutput ); ++#ifdef __FreeBSD__ ++ bool done = false; ++#endif + for( QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it ) + { + const QString& line = *it; ++#ifdef __FreeBSD__ ++ kdDebug() << "(K3bDeviceManager): " << line << endl; ++ if (done) ++ continue; ++#endif + + // no info in cdrecord <= 1.10 !!!!! + if( line.startsWith( "Supported modes" ) ) +@@ -504,7 +542,11 @@ + dev->m_writeModes |= K3bDevice::RAW_R96R; + if( modes.contains( "RAW/R96P" ) ) + dev->m_writeModes |= K3bDevice::RAW_R96P; ++#ifdef __FreeBSD__ ++ done = true; ++#else + break; ++#endif + } + } + } +@@ -515,12 +557,110 @@ + if( dev->m_writeModes == 0 ) + dev->m_writeModes = K3bDevice::SAO|K3bDevice::TAO; + } ++#ifdef __FreeBSD__ ++// For some unknown reason KDE stdout redirection fails on cdrecord -prcap (FreeBSD) :-( ++// See http://www.FreeBSD.org/cgi/query-pr.cgi?pr=ports/51651 ++// So it is written to a temp file here ++ KTempFile tmpfile; ++ tmpfile.setAutoDelete(true); ++ QString call = cdrecordBin->path + " " + QString("dev=%1").arg(dev->busTargetLun()) + " -prcap > " + tmpfile.name(); ++ kdDebug() << "(K3bDeviceManager) calling: " << call << endl; ++ int result = system(call.latin1()); ++ if (!result) ++ kdDebug() << "(K3bDeviceManager) call failed: " << result << endl; ++ QFile tmp (tmpfile.name()); ++ if ( tmp.open( IO_ReadOnly ) ) ++ { ++ QTextStream stream( &tmp ); ++ while ( !stream.eof() ) ++ { ++ QString line = stream.readLine(); ++ kdDebug() << "(K3bDeviceManager): " << line << endl; ++ if( line.startsWith(" ") ) ++ { ++ if( line.contains("write CD-R media") ) ++ { ++ bool b = !line.contains( "not" ); ++ dev->m_burner = b; ++ kdDebug() << "(K3bDeviceManager) is burner: " << b << endl; ++ if (b) ++ { ++ dev->addDeviceType(K3bDevice::CDR); ++ kdDebug() << "(K3bDeviceManager) device type: CDR" << endl; ++ } ++ } ++ ++ else if( line.contains("write CD-RW media") ) ++ { ++ bool b = !line.contains( "not" ); ++ dev->m_bWritesCdrw = b; ++ kdDebug() << "(K3bDeviceManager) writes cdr: " << b << endl; ++ if (b) ++ { ++ dev->addDeviceType(K3bDevice::CDRW); ++ kdDebug() << "(K3bDeviceManager) device type: CDRW" << endl; ++ } ++ } ++ ++ else if( line.contains("Buffer-Underrun-Free recording") || ++ line.contains("support BURN-Proof") ) ++ { ++ bool b = !line.contains( "not" ); ++ dev->setBurnproof(b); ++ kdDebug() << "(K3bDeviceManager) burn proof: " << b << endl; ++ } ++ ++ else if( line.contains( "Maximum read speed" ) ) //lukas: are there really two spaces? trueg: Yes, there are! ;) ++ dev->m_maxReadSpeed = K3b::round( line.mid( line.find(":")+1 ).toDouble() * 1000.0 / ( 2352.0 * 75.0 ) ); ++ ++ else if( line.contains( "Maximum write speed" ) ) ++{ ++ dev->m_maxWriteSpeed = K3b::round( line.mid( line.find(":")+1 ).toDouble() * 1000.0 / ( 2352.0 * 75.0 ) ); ++} ++ else if( line.contains( "Does read CD-R media" ) ) ++ { ++ dev->addDeviceType(K3bDevice::CDROM); ++ kdDebug() << "(K3bDeviceManager) device type: CDROM" << endl; ++ } ++ else if( line.contains( "Does write DVD-R media" ) ) ++ { ++ dev->addDeviceType(K3bDevice::DVDR); ++ kdDebug() << "(K3bDeviceManager) device type: DVDR" << endl; ++ } ++ else if( line.contains( "Does write DVD-RAM media" ) ) ++ { ++ dev->addDeviceType(K3bDevice::DVDRAM); ++ kdDebug() << "(K3bDeviceManager) device type: DVDRAM" << endl; ++ } ++ else if( line.contains( "Does read DVD-ROM media" ) ) ++ { ++ dev->addDeviceType(K3bDevice::DVD); ++ kdDebug() << "(K3bDeviceManager) device type: DVD" << endl; ++ } ++ else if( line.contains( "Buffer size" ) ) ++ dev->m_bufferSize = line.mid( line.find(":")+1 ).toInt(); ++ } ++ else if( line.startsWith("Vendor_info") ) ++ dev->m_vendor = line.mid( line.find(":")+3, 8 ).stripWhiteSpace(); ++ else if( line.startsWith("Identifikation") ) ++ dev->m_description = line.mid( line.find(":")+3, 16 ).stripWhiteSpace(); ++ else if( line.startsWith("Revision") ) ++ dev->m_version = line.mid( line.find(":")+3, 4 ).stripWhiteSpace(); ++ else ++ kdDebug() << "(K3bDeviceManager) unused cdrecord output: " << line << endl; ++ ++ } ++ tmp.close(); ++ } ++ dev->guessProfiles(); ++#endif + } + + + bool K3bCdDevice::DeviceManager::testForCdrom(const QString& devicename) + { + bool ret = false; ++#ifndef __FreeBSD__ + int cdromfd = K3bCdDevice::openDevice( devicename.ascii() ); + if (cdromfd < 0) { + kdDebug() << "could not open device " << devicename << " (" << strerror(errno) << ")" << endl; +@@ -549,11 +689,51 @@ + } + } + ::close( cdromfd ); ++#endif + return ret; + } + + K3bDevice* K3bCdDevice::DeviceManager::addDevice( const QString& devicename ) + { ++#ifdef __FreeBSD__ ++// this piece of code extracts some device parameter, like scsi or ide device. The whole process ++// fails on FreeBSD. Here the device name is simply looked up in a list of devices found by a ++// call of cdrecord --scanbus. ++ K3bDevice* device = 0; ++ if (!m_lastRefresh.isValid()) ++ bsd_scan_devices(false); ++ bool found = false; ++ for ( QValueList<BSDDevice>::iterator it = m_devices.begin(); it != m_devices.end(); ++it ) ++ { ++ if( (*it).m_name == devicename ) ++ { ++ device = new K3bDevice((*it).m_name.latin1()); ++ device->m_bus = (*it).m_bus; ++ device->m_target = (*it).m_target; ++ device->m_lun = (*it).m_lun; ++ device->m_passDevice = (*it).m_passDevice; ++ device->m_vendor = (*it).m_vendor; ++ device->m_description = (*it).m_product; ++ device->m_version = (*it).m_revision; ++ found = true; ++ break; ++ } ++ } ++ if (!found) ++ { ++ // resolve all symlinks ++ QString resolved = resolveSymLink( devicename ); ++ kdDebug() << "(K3bDeviceManager) " << devicename << " resolved to " << resolved << endl; ++ int bus, target, lun; ++ if( K3bDevice* oldDev = findDevice( bus, target, lun ) ) ++ { ++ kdDebug() << "(K3bDeviceManager) dev already found" << endl; ++ oldDev->addDeviceNode( resolved ); ++ } ++ return 0; ++ } ++ ++#else + K3bDevice* device = 0; + + // resolve all symlinks +@@ -586,6 +766,7 @@ + device->m_lun = lun; + } + ++#endif + if( !device->init() ) { + kdDebug() << "Could not initialize device " << devicename << endl; + delete device; +@@ -623,13 +804,14 @@ + + void K3bCdDevice::DeviceManager::scanFstab() + { ++#ifndef __FreeBSD__ + FILE* fstabFile = setmntent( _PATH_FSTAB, "r" ); + if( !fstabFile ) + { + kdDebug() << "(K3bDeviceManager) could not open " << _PATH_FSTAB << endl; + return; + } +- ++#endif + + // clear all mount-Infos + for( QPtrListIterator<K3bDevice> it( d->allDevices ); it.current(); ++it ) +@@ -639,12 +821,22 @@ + } + + ++#ifndef __FreeBSD__ + struct mntent* mountInfo = 0; + while( (mountInfo = ::getmntent( fstabFile )) ) ++#else ++ struct fstab * mountInfo = 0; ++ while( (mountInfo = ::getfsent()) ) ++#endif + { + // check if the entry corresponds to a device ++#ifndef __FreeBSD__ + QString md = QFile::decodeName( mountInfo->mnt_fsname ); + QString type = QFile::decodeName( mountInfo->mnt_type ); ++#else ++ QString md = QFile::decodeName( mountInfo->fs_spec ); ++ QString type = QFile::decodeName( mountInfo->fs_vfstype ); ++#endif + + bool supermount = false; + +@@ -652,7 +844,11 @@ + supermount = true; + + // parse the device ++#ifndef __FreeBSD__ + QStringList opts = QStringList::split( ",", QString::fromLocal8Bit(mountInfo->mnt_opts) ); ++#else ++ QStringList opts = QStringList::split( ",", QString::fromLocal8Bit(mountInfo->fs_mntops) ); ++#endif + for( QStringList::const_iterator it = opts.begin(); it != opts.end(); ++it ) { + if( (*it).startsWith("dev=") ) { + md = (*it).mid( 4 ); +@@ -668,9 +864,20 @@ + + if( K3bDevice* dev = findDevice( resolveSymLink(md) ) ) + { ++#ifndef __FreeBSD__ + kdDebug() << "(K3bDeviceManager) found device for " << md << ": " << resolveSymLink(md) << endl; + if( dev->mountDevice().isEmpty() ) { + dev->setMountPoint( mountInfo->mnt_dir ); ++#else ++ kdDebug() << "(K3bDeviceManager) found device for " << md << " (" << resolveSymLink(md) << "): " << mountInfo->fs_file << endl; ++// Several mount points for one device might exist. If more than one are found, the one with ++// user permission should have a higher priority. ++ struct stat filestat; ++ if( dev->mountDevice().isEmpty() || (mountInfo->fs_file && !stat(mountInfo->fs_file, &filestat) && filestat.st_uid == geteuid())) ++ { ++ kdDebug() << "(K3bDeviceManager) setting mount point for device " << md << ": " << mountInfo->fs_file << endl; ++ dev->setMountPoint( mountInfo->fs_file ); ++#endif + dev->setMountDevice( md ); + dev->m_supermount = supermount; + } +@@ -679,6 +886,8 @@ + { + // compare bus, id, lun since the same device can for example be + // determined as /dev/srX or /dev/scdX ++#ifndef __FreeBSD__ ++// On FreeBSD scsi parameters can not be extracted from a file handle + int bus = -1, id = -1, lun = -1; + if( determineBusIdLun( mountInfo->mnt_fsname, bus, id, lun ) ) { + if( K3bDevice* dev = findDevice( bus, id, lun ) ) { +@@ -689,12 +898,27 @@ + } + } + } ++#else ++// Therefore they are looked up in the device list. ++ kdDebug() << "(K3bDeviceManager) device: " << mountInfo->fs_spec << endl; ++ if( K3bDevice* dev = findDevice( mountInfo->fs_spec ) ) { ++ kdDebug() << " found! " << endl; ++ if( dev->mountDevice().isEmpty() ) { ++ dev->setMountPoint( mountInfo->fs_file ); ++ dev->setMountDevice( md ); ++ } ++ } ++#endif + + + } + } // while mountInfo + ++#ifndef __FreeBSD__ + endmntent( fstabFile ); ++#else ++ endfsent(); ++#endif + } + + +@@ -707,6 +931,8 @@ + bool K3bCdDevice::DeviceManager::determineBusIdLun( const QString& dev, int& bus, int& id, int& lun ) + { + int ret = false; ++#ifndef __FreeBSD__ ++// On FreeBSD scsi parameters can not be extracted from a file handle + int cdromfd = K3bCdDevice::openDevice( dev.ascii() ); + if (cdromfd < 0) { + kdDebug() << "could not open device " << dev << " (" << strerror(errno) << ")" << endl; +@@ -743,6 +969,7 @@ + + + ::close(cdromfd); ++#endif + return ret; + } + +@@ -750,6 +977,7 @@ + QString K3bCdDevice::DeviceManager::resolveSymLink( const QString& path ) + { + char resolved[PATH_MAX]; ++ kdDebug() << "(K3bDeviceManager) resolveSymLink: \"" << path << "\"" << endl; + if( !realpath( QFile::encodeName(path), resolved ) ) + { + kdDebug() << "Could not resolve " << path << endl; +@@ -784,5 +1012,125 @@ + else + return QString("ATAPI:%1").arg(dev->blockDeviceName()); + } ++ ++#ifdef __FreeBSD__ ++// Calls "camcontrol devlist" to get a list of all available cd devices. ++// The sudo flag indicates, that "camcontrol devlist" should be ++// called. This is tried, if bsd_scan_devices(false) fails. ++// The result of the scan ist stored in m_devices. If within 3 ++// seconds after the last call to bsd_scan_devices this function ++// is called again, the last result is used (prevents to call ++// camcontrol several times within a short time). ++void K3bCdDevice::DeviceManager::bsd_scan_devices(bool sudo) ++{ ++ QDateTime now = QDateTime::currentDateTime(); ++ if (m_lastRefresh.isValid() && m_lastRefresh.secsTo(now) < 3) ++ return; ++ m_lastRefresh = now; ++ m_devices.clear(); ++ kdDebug() << "(K3bDeviceManager) Scanning for devices: " << sudo << endl; ++ KTempFile tmpfile; ++ tmpfile.setAutoDelete(true); ++ ++ // create call ++ QString call = "/bin/sh -c \""; ++ if (sudo) ++ call += "sudo "; ++ call += "camcontrol devlist > " + tmpfile.name() + " 2>&1 \""; ++ kdDebug() << "(K3bDeviceManager) Reading device list : " << call << endl; ++ if (system(call.latin1())) ++ { ++ if (!sudo) ++ { ++ m_lastRefresh = m_lastRefresh.addDays(-1); ++ bsd_scan_devices(true); ++ } ++ return; ++ } ++ ++ // read tmp file line by line ++ QFile tmp (tmpfile.name()); ++ if ( tmp.open( IO_ReadOnly ) ) ++ { ++ QTextStream stream( &tmp ); ++ while ( !stream.eof() ) ++ { ++ QString str = stream.readLine(); ++ if (!str.startsWith("<")) ++ continue; ++ str.remove(0,1); ++ int i = str.find(">"); ++ if (i < 0) ++ continue; ++ QStringList details = QStringList::split(" ", str.left(i)); ++ i = str.find("at scbus", i); ++ if (i < 0) ++ continue; ++ str.remove(0, i+8); ++ i = str.find(" "); ++ if (i < 0) ++ continue; ++ bool ok; ++ int bus = str.left(i).toInt(&ok); ++ if (!ok) ++ continue; ++ i = str.find("target ", i); ++ if (i < 0) ++ continue; ++ str.remove(0, i+7); ++ i = str.find(" "); ++ if (i < 0) ++ continue; ++ int target = str.left(i).toInt(&ok); ++ if (!ok) ++ continue; ++ i = str.find("lun ", i); ++ if (i < 0) ++ continue; ++ str.remove(0, i+4); ++ i = str.find(" "); ++ if (i < 0) ++ continue; ++ int lun = str.left(i).toInt(&ok); ++ if (!ok) ++ continue; ++ i = str.find("(", i); ++ if (i < 0) ++ continue; ++ str.remove(0, i+1); ++ i = str.find(","); ++ if (i < 0) ++ continue; ++ QString name = str.left(i); ++ str.remove(0, i+1); ++ i = str.find(")"); ++ if (i < 0) ++ continue; ++ QString pass = name; ++ if (name.startsWith("pass")) ++ name = str.left(i); ++ else ++ pass = str.left(i); ++ QString vendor, product, revision; ++ if (details.count() > 0) ++ revision = details.last(); ++ details.pop_back(); ++ if (details.count() > 0) ++ product = details.last(); ++ details.pop_back(); ++ if (details.count() > 0) ++ vendor = details.join(" "); ++ kdDebug() << "(K3bDeviceManager) Found device " << name << ", pass = " << pass << ", bus = " << bus << ", target = " << target << ", lun = " << lun << endl; ++ kdDebug() << "(K3bDeviceManager) vendor: " << vendor << ", product: " << product << ", revision: " << revision << ", target = " << target << ", lun = " << lun << endl; ++#if __FreeBSD_version >= 500100 ++ m_devices.push_back(BSDDevice("/dev/" + name, "/dev/" + pass, vendor, product, revision, bus, target, lun)); ++#else ++ m_devices.push_back(BSDDevice("/dev/" + name + "c", "/dev/" + pass, vendor, product, revision, bus, target, lun)); ++#endif ++ } ++ } ++} ++#endif ++ + + #include "k3bdevicemanager.moc" |