aboutsummaryrefslogtreecommitdiff
path: root/sysutils/k3b/files
diff options
context:
space:
mode:
authorWill Andrews <will@FreeBSD.org>2003-11-20 13:03:02 +0000
committerWill Andrews <will@FreeBSD.org>2003-11-20 13:03:02 +0000
commit2a59b4a154397f193d575b43f9a6e59086c2ba92 (patch)
treeb76e7bf8d3f8c8bdc4e7ab64718d2d56663880d3 /sysutils/k3b/files
parentfe5a380496f966d43386d8a817e13a9b0f867e62 (diff)
downloadports-2a59b4a154397f193d575b43f9a6e59086c2ba92.tar.gz
ports-2a59b4a154397f193d575b43f9a6e59086c2ba92.zip
Notes
Diffstat (limited to 'sysutils/k3b/files')
-rw-r--r--sysutils/k3b/files/patch-src-Makefile.in11
-rw-r--r--sysutils/k3b/files/patch-src-audiodecoding-mp3-k3bmaddecoder.cpp124
-rw-r--r--sysutils/k3b/files/patch-src-core-device-k3bdevice.cpp912
-rw-r--r--sysutils/k3b/files/patch-src-core-device-k3bdevice.h50
-rw-r--r--sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.cpp541
-rw-r--r--sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.h43
-rw-r--r--sysutils/k3b/files/patch-src-core-device-k3bscsicommand.cpp127
-rw-r--r--sysutils/k3b/files/patch-src-core-device-k3bscsicommand.h51
-rw-r--r--sysutils/k3b/files/patch-src-core-k3bdefaultexternalprograms.cpp173
-rw-r--r--sysutils/k3b/files/patch-src-core-k3bglobals.cpp16
-rw-r--r--sysutils/k3b/files/patch-src-core-k3bprocess.cpp63
-rw-r--r--sysutils/k3b/files/patch-src-core-k3bprocess.h25
-rw-r--r--sysutils/k3b/files/patch-src-rip-k3bmovieview.cpp14
-rw-r--r--sysutils/k3b/files/patch-src-rip-k3btcwrapper.cpp35
14 files changed, 2185 insertions, 0 deletions
diff --git a/sysutils/k3b/files/patch-src-Makefile.in b/sysutils/k3b/files/patch-src-Makefile.in
new file mode 100644
index 000000000000..42e55ed1de9d
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-Makefile.in
@@ -0,0 +1,11 @@
+--- src/Makefile.in.orig Thu Nov 6 09:01:00 2003
++++ src/Makefile.in Fri Nov 7 12:35:44 2003
+@@ -281,7 +281,7 @@
+ #>+ 1
+ k3b_SOURCES=k3bwelcomewidget.cpp k3bapplication.cpp k3bdiroperator.cpp kdndfileview.cpp k3bfiletreeview.cpp k3bcddbmultientriesdialog.cpp k3baudioplayer.cpp k3bprojecttabbar.cpp k3bprojecttabwidget.cpp k3bsplash.cpp k3bblankingdialog.cpp k3bfileview.cpp k3bdirview.cpp k3btoolbox.cpp k3b.cpp main.cpp k3bstatusbarmanager.cpp k3bfiletreecombobox.cpp k3breadcdreader.cpp k3binterface.cpp k3bprojectinterface.cpp k3bsystemproblemdialog.cpp k3binterface_skel.cpp k3bprojectinterface_skel.cpp
+
+-k3b_LDADD = ./cdinfo/libcdinfo.la ./option/liboption.la ./rip/librip.la ./cdcopy/libcdcopy.la ./dvdcopy/libdvdcopy.la ./cdclone/libcdclone.la ./videoEncoding/libvideoEncoding.la ./plugin/libk3bplugin.la $(ARTS_LIBS) -lkio -lkparts ./core/libk3bcore.la ./tools/libk3btools.la ./projects/libk3bproject.la ./images/libimagewriting.la
++k3b_LDADD = ./cdinfo/libcdinfo.la ./option/liboption.la ./rip/librip.la ./cdcopy/libcdcopy.la ./dvdcopy/libdvdcopy.la ./cdclone/libcdclone.la ./videoEncoding/libvideoEncoding.la ./plugin/libk3bplugin.la $(ARTS_LIBS) -lkio -lkparts -lcam ./core/libk3bcore.la ./tools/libk3btools.la ./projects/libk3bproject.la ./images/libimagewriting.la
+
+ SUBDIRS = core tools plugin projects cddb cdinfo option rip cdcopy cdclone images dvdcopy videoEncoding pics icons konqi mimetypes tests audiodecoding audioencoding sounds $(K3BSETUP1_BUILD)
+
diff --git a/sysutils/k3b/files/patch-src-audiodecoding-mp3-k3bmaddecoder.cpp b/sysutils/k3b/files/patch-src-audiodecoding-mp3-k3bmaddecoder.cpp
new file mode 100644
index 000000000000..ab64d2773e8c
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-audiodecoding-mp3-k3bmaddecoder.cpp
@@ -0,0 +1,124 @@
+--- src/audiodecoding/mp3/k3bmaddecoder.cpp.orig Mon Sep 1 12:14:10 2003
++++ src/audiodecoding/mp3/k3bmaddecoder.cpp Fri Nov 7 12:35:44 2003
+@@ -37,6 +37,8 @@
+ #include <stdlib.h>
+ #include <cmath>
+ #include <cstdlib>
++#include <sys/types.h>
++#include <sys/mman.h>
+
+ #include <config.h>
+
+@@ -716,23 +718,24 @@
+ return false;
+ }
+
+- // there seem to be mp3 files starting with a lot of zeros
+- // we try to skip these.
+- // there might still be files with more than bufLen zeros...
+- const int bufLen = 4096;
+- char buf[bufLen];
+- if( f.readBlock( buf, bufLen ) < bufLen ) {
+- kdDebug() << "(K3bMadDecoder) unable to read " << bufLen << " bytes from " << url.path() << endl;
++ // EXPERIMENTAL!!!!!!!!
++
++ const int bufLen = f.size();
++ const char * buf = (const char *)mmap(0, bufLen, PROT_READ, MAP_SHARED, f.handle(), 0);
++ if (buf == MAP_FAILED)
++ {
++ kdDebug() << "(K3bMp3Module) unable to read from " << url.path() << endl;
+ f.close();
+ return false;
+ }
+- f.close();
+
+ // skip any 0
+ int i = 0;
+ while( i < bufLen && buf[i] == '\0' ) i++;
+ if( i == bufLen ) {
+ kdDebug() << "(K3bMadDecoder) only zeros found in the beginning of " << url.path() << endl;
++ munmap((void *)buf, bufLen);
++ f.close();
+ return false;
+ }
+
+@@ -744,6 +747,8 @@
+ ( (unsigned short)buf[i+3] < 0xff && (unsigned short)buf[i+4] < 0xff ) ) {
+ kdDebug() << "(K3bMadDecoder) found id3 magic: ID3 "
+ << (unsigned short)buf[i+3] << "." << (unsigned short)buf[i+4] << endl;
++ munmap((void *)buf, bufLen);
++ f.close();
+ return true;
+ }
+
+@@ -756,15 +761,22 @@
+ short m = (short)( buf[i+20] | (buf[i+21]<<8) );
+ if( m == 80 ) {
+ kdDebug() << "(K3bMadDecoder) found RIFF MPEG magic." << endl;
++ munmap((void *)buf, bufLen);
++ f.close();
+ return true;
+ }
+ else if( m == 85 ) {
+ kdDebug() << "(K3bMadDecoder) found RIFF MPEG III magic." << endl;
++ munmap((void *)buf, bufLen);
++ f.close();
+ return true;
+ }
+- else
++ else {
++ munmap((void *)buf, bufLen);
++ f.close();
+ return false;
+ }
++ }
+
+
+
+@@ -775,16 +787,41 @@
+ mad_stream_init( &stream );
+ mad_header_init( &header );
+
+- mad_stream_buffer( &stream, (unsigned char*)&buf[i], bufLen-i );
+- stream.error = MAD_ERROR_NONE;
++ mad_stream_buffer( &stream, (unsigned char*)buf, bufLen );
++ unsigned long bitrate, kbps, count;
++ int vbr;
++ bitrate = kbps = count = vbr = 0;
++ mad_timer_t duration = mad_timer_zero;
+ bool success = true;
+- if( mad_header_decode( &header, &stream ) ) {
++ while (1) {
++ if (mad_header_decode(&header, &stream) == -1) {
++ if (MAD_RECOVERABLE(stream.error))
++ continue;
++ else
++ {
++ break;
++ }
++ }
++ if (bitrate && header.bitrate != bitrate)
++ vbr = 1;
++
++ bitrate = header.bitrate;
++
++ kbps += bitrate / 1000;
++ ++count;
++
++ mad_timer_add(&duration, header.duration);
++ }
++ kbps = count?((kbps * 2) / count + 1) / 2 * (vbr ? -1 : 1):0;
++ kdDebug() << "(K3bMp3Module) File: " << url.path() << ", bitrate: " << kbps << ", duration: " << duration.seconds << "." << duration.fraction << endl;
++ if (duration.seconds == 0 || kbps == 0)
++ {
+ kdDebug() << "(K3bMadDecoder) could not find mpeg header." << endl;
+ success = false;
+ }
+
+- mad_header_finish( &header );
+- mad_stream_finish( &stream );
++ munmap((void *)buf, bufLen);
++ f.close();
+
+ return success;
+ }
diff --git a/sysutils/k3b/files/patch-src-core-device-k3bdevice.cpp b/sysutils/k3b/files/patch-src-core-device-k3bdevice.cpp
new file mode 100644
index 000000000000..449a87e89484
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-core-device-k3bdevice.cpp
@@ -0,0 +1,912 @@
+--- src/core/device/k3bdevice.cpp.orig Thu Oct 30 11:53:35 2003
++++ src/core/device/k3bdevice.cpp Sat Nov 8 12:15:01 2003
+@@ -32,7 +32,9 @@
+ #include <sys/ioctl.h>
+
+ #include <fstab.h>
++#ifndef __FreeBSD__
+ #include <mntent.h>
++#endif
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <fcntl.h>
+@@ -40,6 +42,7 @@
+ #include <errno.h>
+ #include <sys/stat.h>
+
++#ifndef __FreeBSD__
+ #include <linux/version.h>
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,70)
+ typedef unsigned char u8;
+@@ -48,6 +51,18 @@
+ #include <linux/cdrom.h>
+ #define __STRICT_ANSI__
+ #include <linux/major.h>
++#else
++#include <sys/cdio.h>
++#include <sys/dvdio.h>
++#include <ktempfile.h>
++#define __BYTE_ORDER BYTE_ORDER
++#define __BIG_ENDIAN BIG_ENDIAN
++//#define CDROMEJECT CDIOCEJECT
++//#define CDROMCLOSETRAY CDIOCCLOSE
++#define CD_FRAMESIZE_RAW 2352
++#include <cam/scsi/scsi_message.h>
++int bsd_open_close_device(int bus, int target, int lun, bool eject);
++#endif
+
+
+
+@@ -167,6 +182,7 @@
+ {
+ kdDebug() << "(K3bCdDevice) " << blockDeviceName() << ": init()" << endl;
+
++#ifndef __FreeBSD__
+ if(open() < 0)
+ return false;
+
+@@ -175,10 +191,18 @@
+ // we also query the mode page 2A and use the cdrom.h stuff to get as much information as possible
+ //
+
++ // On BSD the device capabilities are already set by the devicemanager. So this code may
++ // find more capabilities -- if it works
+ d->deviceType = 0;
++#endif
+ d->supportedProfiles = 0;
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++ d->deviceType |= CDROM;
++#endif
+ unsigned char header[8];
+ ::memset( header, 0, 8 );
+ cmd[0] = 0x46; // GET CONFIGURATION
+@@ -580,8 +604,16 @@
+ int mm_cap_len = 0;
+ if( modeSense( &mm_cap_buffer, mm_cap_len, 0x2A ) ) {
+ mm_cap_page_2A* mm_p = (mm_cap_page_2A*)(mm_cap_buffer+8);
+- if( mm_p->BUF ) d->burnfree = true;
+- if( mm_p->cd_rw_write ) d->deviceType |= CDRW;
++ if( mm_p->BUF )
++ {
++ kdDebug() << "(K3bCdDevice) ModeSense: burnfree." << endl;
++ d->burnfree = true;
++ }
++ if( mm_p->cd_rw_write )
++ {
++ kdDebug() << "(K3bCdDevice) ModeSense: CDRW." << endl;
++ d->deviceType |= CDRW;
++ }
+ m_maxWriteSpeed = (int)( from2Byte(mm_p->max_write_speed) * 1024.0 / ( 2352.0 * 75.0 ) );
+ m_maxReadSpeed = (int)( from2Byte(mm_p->max_read_speed) * 1024.0 / ( 2352.0 * 75.0 ) );
+
+@@ -592,6 +624,7 @@
+ }
+
+
++#ifndef __FreeBSD__
+
+ //
+ // This is the backup if the drive does not support the GET CONFIGURATION command
+@@ -619,6 +652,7 @@
+ if (drivetype & CDC_DVD)
+ d->deviceType |= DVD;
+
++#endif
+
+ if( writesCd() )
+ checkWriteModes();
+@@ -642,10 +676,11 @@
+ m_version = QString::fromLocal8Bit( (char*)(inq+32), 4 ).stripWhiteSpace();
+ }
+
++#ifndef __FreeBSD__
+ close();
++#endif
+
+ d->interfaceType = interfaceType();
+-
+ return furtherInit();
+ }
+
+@@ -649,6 +684,23 @@
+ return furtherInit();
+ }
+
++void K3bCdDevice::CdDevice::guessProfiles()
++{
++ if (!d->supportedProfiles)
++ {
++ kdDebug() << "(K3bCdDevice): no profiles found; setting them from device type = " << d->deviceType << endl;
++ if (d->deviceType & CDROM) d->supportedProfiles |= MEDIA_CD_ROM;
++ if (d->deviceType & CDR) d->supportedProfiles |= MEDIA_CD_R;
++ if (d->deviceType & CDRW) d->supportedProfiles |= MEDIA_CD_RW;
++ if (d->deviceType & DVDR) d->supportedProfiles |= MEDIA_DVD_R_SEQ;
++ if (d->deviceType & DVDRAM) d->supportedProfiles |= MEDIA_DVD_RAM;
++ if (d->deviceType & DVD) d->supportedProfiles |= MEDIA_DVD_ROM;
++ if (d->deviceType & DVDRW) d->supportedProfiles |= MEDIA_DVD_RW_OVWR | MEDIA_DVD_RW_SEQ;// ???
++ if (d->deviceType & DVDPR) d->supportedProfiles |= MEDIA_DVD_PLUS_R;
++ if (d->deviceType & DVDPRW) d->supportedProfiles |= MEDIA_DVD_PLUS_RW;
++ }
++// case 0x11: d->supportedProfiles |= MEDIA_DVD_R_SEQ;
++}
+
+ bool K3bCdDevice::CdDevice::furtherInit()
+ {
+@@ -658,6 +710,7 @@
+
+ K3bCdDevice::CdDevice::interface K3bCdDevice::CdDevice::interfaceType()
+ {
++#ifndef __FreeBSD__
+ if (d->interfaceType == OTHER)
+ {
+ // if the device is already opened we do not close it
+@@ -680,6 +733,9 @@
+ if( needToClose )
+ close();
+ }
++#else
++ d->interfaceType = SCSI;
++#endif
+ return d->interfaceType;
+ }
+
+@@ -826,7 +882,11 @@
+
+ unsigned char dvdheader[20];
+ ::memset( dvdheader, 0, 20 );
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0xad; // GPCMD_READ_DVD_STRUCTURE;
+ cmd[9] = 20;
+ if( cmd.transport( TR_DIR_READ, dvdheader, 20 ) ) {
+@@ -846,6 +906,7 @@
+
+ int K3bCdDevice::CdDevice::isReady() const
+ {
++#ifndef __FreeBSD__
+ // if the device is already opened we do not close it
+ // to allow fast multible method calls in a row
+ bool needToClose = !isOpen();
+@@ -905,6 +966,10 @@
+ }
+ else
+ return 2;
++#else
++ ((CdDevice *)this)->refreshDeviceData();
++ return m_driveReady;
++#endif
+ }
+
+
+@@ -941,6 +1006,7 @@
+ delete [] data;
+ }
+ else {
++#ifndef __FreeBSD__
+ kdDebug() << "(K3bCdDevice::CdDevice) " << blockDeviceName()
+ << ": READ DISC INFORMATION failed. falling back to cdrom.h" << endl;
+ int drive_status = ::ioctl(d->deviceFd,CDROM_DRIVE_STATUS);
+@@ -953,6 +1019,10 @@
+ kdDebug() << "(K3bCdDevice::CdDevice) " << blockDeviceName() << ": No disk in drive" << endl;
+ ret = NO_DISK;
+ }
++#else
++ ((CdDevice *)this)->refreshDeviceData();
++ ret = m_deviceStatus;
++#endif
+ }
+
+ if( needToClose )
+@@ -1013,7 +1083,11 @@
+ unsigned char header[2];
+ ::memset( header, 0, 2 );
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x51; // READ DISC INFORMATION
+ cmd[8] = 2;
+
+@@ -1199,6 +1273,7 @@
+ bool readSuccess = true;
+
+ if( !readSectorsRaw( data, lba, 1 ) ) {
++#ifndef __FreeBSD__
+ kdDebug() << "(K3bCdDevice::CdDevice) " << blockDeviceName()
+ << ": MMC RAW READ failed. falling back to cdrom.h." << endl;
+
+@@ -1209,8 +1284,11 @@
+ if( ::ioctl(d->deviceFd,CDROMREADRAW,data) == -1 ) {
+ kdDebug() << "(K3bCdDevice::CdDevice) " << blockDeviceName()
+ << ": could not get track header, (lba " << lba << ") ! " << strerror(errno) << endl;
++#endif
+ readSuccess = false;
++#ifndef __FreeBSD__
+ }
++#endif
+ }
+
+ if( readSuccess ) {
+@@ -1556,7 +1634,7 @@
+ bool success = true;
+
+ toc.clear();
+-
++#ifndef __FreeBSD__
+ struct cdrom_tochdr tochdr;
+ struct cdrom_tocentry tocentry;
+
+@@ -1642,6 +1720,10 @@
+ else
+ success = false;
+
++#else
++ ((CdDevice *)this)->refreshDeviceData();
++ toc = m_toc;
++#endif
+ return success;
+ }
+
+@@ -1653,7 +1735,7 @@
+ bool needToClose = !isOpen();
+
+ bool success = false;
+-
++#ifndef __FreeBSD__
+ if( open() != -1 ) {
+ //
+ // we probaly need to fixup the toc for multisession mixed-mode cds
+@@ -1681,7 +1763,7 @@
+ kdDebug() << "(K3bCdDevice::CdDevice) CDROMMULTISESSION failed." << endl;
+ }
+ }
+-
++#endif
+ if( needToClose )
+ close();
+
+@@ -1692,17 +1774,25 @@
+ bool K3bCdDevice::CdDevice::block( bool b ) const
+ {
+ if( open() != -1 ) {
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x1E; // ALLOW MEDIA REMOVAL
+ cmd[4] = b ? 0x1 : 0x0;
+ int r = cmd.transport();
+ if( r ) {
+ kdDebug() << "(K3bCdDevice::CdDevice) MMC ALLOW MEDIA REMOVAL failed. Falling back to cdrom.h." << endl;
++#ifndef __FreeBSD__
+ r = ::ioctl(d->deviceFd,CDROM_LOCKDOOR, b ? 1 : 0 );
++#else
++ r = ::ioctl(d->deviceFd,b ? CDIOCPREVENT : CDIOCALLOW);
++#endif
+ }
+
+ if( r )
+- kdDebug() << "(K3bCdDevice) Cannot block/unblock device " << devicename() << endl;
++ kdDebug() << "(K3bCdDevice) Cannot block/unblock device " << devicename() << ", errno: " << errno << endl;
+
+ close();
+ return ( r == 0 );
+@@ -1724,22 +1814,36 @@
+
+ return e;
+ }
++#ifndef __FreeBSD__
+ else
+ return false;
++#else
++ ((CdDevice *)this)->refreshDeviceData();
++ return m_rewritableCd;
++#endif
+ }
+
+ bool K3bCdDevice::CdDevice::eject() const
+ {
+ block(false);
+
++#ifndef __FreeBSD__
+ if( open() != -1 ) {
+ ScsiCommand cmd( open() );
++#else
++ if( true ) {
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x1B; // START/STOP UNIT
+ cmd[4] = 0x2; // LoEj = 1, Start = 0
+ int r = cmd.transport();
+ if( r ) {
+ kdDebug() << "(K3bCdDevice::CdDevice) MMC START/STOP UNIT failed. Falling back to cdrom.h." << endl;
++#ifndef __FreeBSD__
+ r = ::ioctl( d->deviceFd, CDROMEJECT );
++#else
++ r = bsd_open_close_device(m_bus, m_target, m_lun, true);
++#endif
+ }
+
+ close();
+@@ -1752,14 +1856,23 @@
+
+ bool K3bCdDevice::CdDevice::load() const
+ {
++#ifndef __FreeBSD__
+ if( open() != -1 ) {
+ ScsiCommand cmd( open() );
++#else
++ if( true ) {
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x1B; // START/STOP UNIT
+ cmd[4] = 0x3; // LoEj = 1, Start = 1
+ int r = cmd.transport();
+ if( r ) {
+ kdDebug() << "(K3bCdDevice::CdDevice) MMC START/STOP UNIT failed. Falling back to cdrom.h." << endl;
++#ifndef __FreeBSD__
+ r = ::ioctl( d->deviceFd, CDROMCLOSETRAY );
++#else
++ r = bsd_open_close_device(m_bus, m_target, m_lun, false);
++#endif
+ }
+ close();
+ return (r == 0);
+@@ -1793,7 +1906,7 @@
+ d->deviceFd = openDevice( QFile::encodeName(devicename()) );
+ if (d->deviceFd < 0)
+ {
+- kdDebug() << "(K3bCdDevice) Error: could not open device." << endl;
++ kdDebug() << "(K3bCdDevice) Error: could not open device: " << QFile::encodeName(devicename()) << endl;
+ d->deviceFd = -1;
+ }
+
+@@ -1915,7 +2028,11 @@
+ unsigned char profileBuf[8];
+ ::memset( profileBuf, 0, 8 );
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x46; // GET CONFIGURATION
+ cmd[1] = 1;
+ cmd[8] = 8;
+@@ -1974,7 +2091,11 @@
+ }
+ inf.m_currentProfile = profile;
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+
+ if( inf.diskState() != STATE_NO_MEDIA ) {
+
+@@ -2037,6 +2158,33 @@
+
+ delete [] data;
+ }
++#ifdef __FreeBSD__
++ else
++ {
++ ((CdDevice *)this)->refreshDeviceData();
++ inf.m_rewritable = m_rewritableCd;
++ inf.m_numSessions = m_toc.size();
++ inf.m_capacity = m_discSize;
++ inf.m_remaining = m_remainingSize;
++ inf.m_diskState = STATE_UNKNOWN;
++ inf.m_lastSessionState = STATE_UNKNOWN;
++ if (m_deviceStatus == EMPTY)
++ {
++ inf.m_diskState = STATE_EMPTY;
++ inf.m_lastSessionState = STATE_EMPTY;
++ }
++ else if (m_deviceStatus == APPENDABLE)
++ {
++ inf.m_diskState = STATE_INCOMPLETE;
++ inf.m_lastSessionState = STATE_INCOMPLETE;
++ }
++ else if (m_deviceStatus == COMPLETE)
++ {
++ inf.m_diskState = STATE_COMPLETE;
++ inf.m_lastSessionState = STATE_COMPLETE;
++ }
++ }
++#endif
+
+ //
+ // Now we determine the size:
+@@ -2085,7 +2233,7 @@
+ if( cmd.transport( TR_DIR_READ, trackHeader, 32 ) ) {
+ kdDebug() << "(K3bCdDevice) READ_TRACK_INFORMATION failed." << endl;
+ kdDebug() << "(K3bCdDevice) getting disk size via toc." << endl;
+-
++#ifndef __FreeBSD__
+ // TODO: use readToc!
+
+ struct cdrom_tocentry tocentry;
+@@ -2097,6 +2245,11 @@
+ inf.m_capacity = tocentry.cdte_addr.lba;
+ inf.m_capacity -= 1; // we need the last sector of the last track, not the first from the lead-out
+ }
++#else
++ ((CdDevice *)this)->refreshDeviceData();
++ inf.m_capacity = m_discSize;
++ inf.m_capacity -= 1;
++#endif
+ }
+ else {
+ // not sure about this....
+@@ -2160,7 +2313,11 @@
+
+ unsigned char dvdheader[20];
+ ::memset( dvdheader, 0, 20 );
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0xad; // GPCMD_READ_DVD_STRUCTURE;
+ cmd[9] = 20;
+ if( cmd.transport( TR_DIR_READ, dvdheader, 20 ) ) {
+@@ -2199,7 +2356,11 @@
+
+ bool success = true;
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x25; // READ CAPACITY
+ unsigned char buf[8];
+ ::memset( buf, 0, 8 );
+@@ -2236,7 +2397,11 @@
+ unsigned char header[4]; // for reading the size of the returned data
+ ::memset( header, 0, 4 );
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x23; // GPCMD_READ_FORMAT_CAPACITIES;
+ cmd[8] = 4;
+ if( cmd.transport( TR_DIR_READ, header, 4 ) == 0 ) {
+@@ -2324,7 +2489,11 @@
+ unsigned char header[8];
+ ::memset( header, 0, 8 );
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x5A; // MODE SENSE
+ cmd[1] = 0x08; // Disable Block Descriptors
+ cmd[2] = page;
+@@ -2362,7 +2531,11 @@
+
+ bool ret = false;
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x55; // MODE SELECT
+ cmd[1] = ( sp ? 1 : 0 ) | ( pf ? 0x10 : 0 );
+ cmd[7] = pageLen>>8;
+@@ -2486,7 +2659,11 @@
+ unsigned char header[2];
+ ::memset( header, 0, 2 );
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0x43; // READ TOC/PMA/ATIP
+ cmd[1] = ( time ? 0x2 : 0x0 );
+ cmd[2] = format & 0x0F;
+@@ -2536,7 +2713,11 @@
+ unsigned char header[8];
+ ::memset( header, 0, 8 );
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0xbd; // MECHANISM STATUS
+ cmd[8] = 8; // first we read the header
+ if( cmd.transport( TR_DIR_READ, header, 8 ) == 0 ) {
+@@ -2640,7 +2821,11 @@
+
+ ::memset( data, 0, dataLen );
+
++#ifndef __FreeBSD__
+ ScsiCommand cmd( open() );
++#else
++ ScsiCommand cmd(m_passDevice);
++#endif
+ cmd[0] = 0xbe; // READ CD
+ cmd[1] = (sectorType<<2 & 0x1c) | ( dap ? 0x2 : 0x0 );
+ cmd[2] = startAdress>>24;
+@@ -2668,3 +2853,363 @@
+
+ return ret;
+ }
++#ifdef __FreeBSD__
++void K3bDevice::CdDevice::refreshDeviceData()
++{
++ // was it called within the last 3 seconds?
++ QDateTime now = QDateTime::currentDateTime();
++ if (m_lastRefresh.isValid() && m_lastRefresh.secsTo(now) < 3)
++ return; // yes: use previous values
++
++ m_driveReady = 0;
++ m_rewritableCd = 0;
++ m_discSize = 0;
++ m_remainingSize = 0;
++ m_deviceStatus = NO_INFO;
++ m_toc.clear();
++
++ KTempFile tmpfile;
++ tmpfile.setAutoDelete(true);
++
++ // call cdrecord -toc to get the toc and to detect empty disks
++ QString call = "/bin/sh -c \"cdrecord -toc " + QString("dev=%1").arg( busTargetLun() ) + " > " + tmpfile.name() + " 2>&1 \"";
++ kdDebug() << "(K3bCdDevice) Reading Toc : " << call << endl;
++ system(call.latin1());
++
++ // read tmp file line by line
++ K3bTrack lastTrack;
++ bool firstEntry = true;
++ QFile tmp (tmpfile.name());
++ if ( tmp.open( IO_ReadOnly ) )
++ {
++ QTextStream stream( &tmp );
++ bool done = false;
++ while ( !stream.eof() )
++ {
++ QString str = stream.readLine();
++ kdDebug() << "(K3bCdDevice): " << str << endl;
++ if (done)
++ continue;
++ // no disk inserted?
++ if ( str.startsWith( "cdrecord: No disk" ) )
++ {
++ m_driveReady = NO_DISK;
++ kdDebug() << "(K3bCdDevice) No Toc Data!" << endl;
++ // close and delete tmp file
++ tmp.close();
++ done = true;
++ continue;
++ }
++ // emoty disk inserted?
++ else if (str.startsWith("cdrecord: Cannot read TOC header"))
++ {
++ kdDebug() << "(K3bCdDevice) cd is empty" << endl;
++ m_driveReady = EMPTY;
++ }
++ // track data available?
++ if( str.startsWith("track:") )
++ {
++ // cdrecord produces the following outout:
++ // <tracknumber> lba: <startSector> (<...>) <startTime> adr: 1 control: <trackType> mode: <trackMode>
++ // the last tracknumber will always be "lout", the leadout of the cd which we only use to determine the
++ // length of the last track
++
++ // we just want the startSector, the trackType, and the trackMode
++ int start = 6; // skip the "track:"
++ start = str.find(":", start )+1;
++ int end = str.find( "(", start );
++
++ bool ok;
++ int startSec = str.mid( start, end-start ).toInt(&ok);
++ if( ok )
++ {
++ start = str.find( "control:", start )+8; // skip the "control:"
++ end = str.find("mode:", start );
++ int control = str.mid( start, end-start ).toInt(&ok);
++ if( ok )
++ {
++ start = end + 6;
++ int mode = str.mid( start ).toInt(&ok);
++ if( ok )
++ {
++ // all values have been determined
++ // since we need the start of the next track to determine the length we save the values
++ // in lastTrack and append the current lastTrack to the toc
++
++ if( !firstEntry )
++ {
++ m_toc.append( K3bTrack( lastTrack.firstSector(), startSec-1, lastTrack.type(), lastTrack.mode() ) );
++ kdDebug() << "(K3bCDDevice) Found track: first sector: " << lastTrack.firstSector().toString()
++ << ", last sector: " << startSec-1 << ", type: " << lastTrack.type()
++ << ", mode: " << lastTrack.mode() << endl;
++ if (m_deviceStatus == EMPTY)
++ m_deviceStatus = APPENDABLE;
++ if( lastTrack.mode() == K3bTrack::MODE1 )
++ m_deviceStatus = COMPLETE;
++ }
++ // now this is the meaning of control and mode:
++ // control (combination of the following)
++ // 0x01 - Audio with preemp
++ // 0x02 - Audio copy permitted
++ // 0x04 - Data track
++ // 0x08 - 4 channel audio
++
++ // mode (only for data tracks)
++ // 1 - Mode 1
++ // 2 - Mode 2
++
++ int trackType = 0;
++ int trackMode = K3bTrack::UNKNOWN;
++ if( control & 0x04 )
++ {
++ trackType = K3bTrack::DATA;
++ if( mode == 1 )
++ trackMode = K3bTrack::MODE1;
++ else if( mode == 2 )
++ trackMode = K3bTrack::MODE2;
++ }
++ else
++ trackType = K3bTrack::AUDIO;
++
++ lastTrack = K3bTrack( startSec, startSec, trackType, trackMode );
++ firstEntry = false;
++ }
++ else
++ {
++ kdDebug() << "(K3bCdDevice) Could not parse mode of track: " << str.mid( start ) << endl;
++ }
++ }
++ else
++ {
++ kdDebug() << "(K3bCdDevice) Could not parse control of track: " << str.mid( start, end-start ) << endl;
++ }
++ }
++ else
++ {
++ kdDebug() << "(K3bCdDevice) Could not parse start sector of track: " << str.mid( start, end-start) << endl;
++ }
++ }
++
++ }
++ // close and delete tmp file
++ tmp.close();
++
++ }
++ // skip further tests if there is no disk
++ if (m_driveReady != NO_DISK && m_driveReady != NO_INFO)
++ {
++
++ KTempFile tmpfile2;
++ tmpfile2.setAutoDelete(true);
++
++ // call cdrdao disk-info to get disk capacities, device status, and dsik type
++ call = "/bin/sh -c \"cdrdao disk-info --device " + QString("%1").arg( busTargetLun() ) + " --driver " + cdrdaoDriver() + " > " + tmpfile2.name() + " 2>&1 \"";
++ kdDebug() << "(K3bCdDevice) Reading remaining disk size : " << call << endl;
++ system(call.latin1());
++
++ // read tmp file line by line
++ QFile tmp2(tmpfile2.name());
++ if ( tmp2.open( IO_ReadOnly ) )
++ {
++ QTextStream stream( &tmp2 );
++ while ( !stream.eof() )
++ {
++ QString str = stream.readLine();
++ kdDebug() << "(K3bCdDevice): " << str << endl;
++
++ // remaining capacity available?
++ if ( str.contains( "Remaining Capacity :" ) )
++ {
++ // cdrdao produces the following outout:
++ // <remaining time> ( <remaining blocks> blocks, <remaining size> MB)
++
++ int start = str.find("(" )+1;
++ int end = str.find( " ", start );
++
++ bool ok;
++ int remaining = str.mid( start, end-start ).toInt(&ok);
++ if( ok )
++ {
++ m_remainingSize = remaining-1;
++ }
++ else
++ kdDebug() << "(K3bCdDevice) Could not parse remaining time: " << str.mid( start, end-start) << endl;
++ }
++
++ // total capacity available?
++ else if ( str.contains( "Total Capacity :" ) )
++ {
++ // cdrdao produces the following outout:
++ // <time> ( <blocks> blocks, <size> MB)
++
++ int start = str.find("(" )+1;
++ int end = str.find( " ", start );
++
++ bool ok;
++ int total = str.mid( start, end-start ).toInt(&ok);
++ if( ok )
++ {
++ m_discSize = total-1;
++ }
++ else
++ kdDebug() << "(K3bCdDevice) Could not parse total time: " << str.mid( start, end-start) << endl;
++ }
++
++ // is it an empty CD?
++ else if (str.startsWith("CD-R empty : yes"))
++ {
++ m_deviceStatus = EMPTY;
++ kdDebug() << "(K3bCdDevice) device status: empty" << endl;
++ }
++
++ // is the last session closed?
++ else if (str.startsWith("Appendable : no"))
++ {
++ m_deviceStatus = COMPLETE;
++ kdDebug() << "(K3bCdDevice) device status: complete" << endl;
++ }
++
++ // is the last session open?
++ else if (str.startsWith("Appendable : yes"))
++ {
++ m_deviceStatus = APPENDABLE;
++ kdDebug() << "(K3bCdDevice) device status: appendable" << endl;
++ }
++
++ // is it a cd-rw?
++ else if (str.startsWith("CD-RW : yes"))
++ {
++ kdDebug() << "(K3bCdDevice) cd is erasable" << endl;
++ m_rewritableCd = 1;
++ }
++
++ }
++ // close and delete tmp2 file
++ tmp2.close();
++ }
++
++ if (m_discSize.toString() == "00:00:00") // cdrdao failed somehow
++ {
++
++ KTempFile tmpfile3;
++ tmpfile3.setAutoDelete(true);
++
++ //create call
++ QString call = "/bin/sh -c \"cdrecord -atip " + QString("dev=%1").arg( busTargetLun() ) + " > " + tmpfile3.name() + " 2>&1 \"";
++ kdDebug() << "(K3bCdDevice) Reading disk size : " << call << endl;
++ system(call.latin1());
++
++ // read tmp file line by line
++ K3bTrack lastTrack;
++ QFile tmp3(tmpfile3.name());
++ if ( tmp3.open( IO_ReadOnly ) )
++ {
++ QTextStream stream( &tmp3 );
++ while ( !stream.eof() )
++ {
++ QString str = stream.readLine();
++ if (str.startsWith(" Is erasable"))
++ {
++ m_rewritableCd = 1;
++ }
++ else if( str.startsWith(" ATIP start of lead out:") )
++ {
++ // cdrecord produces the following outout:
++ // <tracknumber> lba: <startSector> (<...>) <startTime> adr: 1 control: <trackType> mode: <trackMode>
++ // the last tracknumber will always be "lout", the leadout of the cd which we only use to determine the
++ // length of the last track
++
++ // we just want the startSector, the trackType, and the trackMode
++ int start = 6; // skip the "track:"
++ start = str.find(":", start )+1;
++ int end = str.find( "(", start )-1;
++
++ bool ok;
++ int leadOut = str.mid( start, end-start ).toInt(&ok);
++ if( ok )
++ m_discSize = leadOut;
++ else
++ kdDebug() << "(K3bCdDevice) Could not parse lead out: " << str.mid( start, end-start) << endl;
++ }
++
++ }
++ // close and delete tmp3 file
++ tmp3.close();
++ }
++ }
++
++ }
++
++ // print out cd data
++ kdDebug() << "(K3bCdDevice) disk size: " << m_discSize.toString() << endl;
++ kdDebug() << "(K3bCdDevice) remaining size: " << m_remainingSize.toString() << endl;
++ kdDebug() << "(K3bCdDevice) total size: " << m_discSize.toString() << endl;
++ kdDebug() << "(K3bCdDevice) drive ready: " << m_driveReady << endl;
++
++ if (m_deviceStatus == EMPTY)
++ kdDebug() << "(K3bCdDevice) device status: empty" << endl;
++ else if (m_deviceStatus == APPENDABLE)
++ kdDebug() << "(K3bCdDevice) device status: appendable" << endl;
++ else if (m_deviceStatus == COMPLETE)
++ kdDebug() << "(K3bCdDevice) device status: complete" << endl;
++ else if (m_deviceStatus == NO_DISK)
++ kdDebug() << "(K3bCdDevice) device status: no disk" << endl;
++ else if (m_deviceStatus == NO_INFO)
++ kdDebug() << "(K3bCdDevice) device status: no info" << endl;
++ if (m_rewritableCd)
++ kdDebug() << "(K3bCdDevice) cd is erasable" << endl;
++ else
++ kdDebug() << "(K3bCdDevice) cd is not erasable" << endl;
++
++ // reset timer
++ m_lastRefresh = QDateTime::currentDateTime();
++}
++
++void K3bDevice::CdDevice::addDeviceType(DeviceType type)
++{
++ d->deviceType |= type;
++}
++
++int bsd_open_close_device(int bus, int target, int lun, bool eject)
++{
++ union ccb *ccb;
++ int error = 0;
++ struct cam_device *cam_dev = cam_open_btl(bus, target, lun, O_RDWR, NULL);
++ ccb = cam_getccb(cam_dev);
++ bool startstop = false;
++ scsi_start_stop(&ccb->csio, 1, NULL, startstop ? MSG_SIMPLE_Q_TAG :MSG_ORDERED_Q_TAG, startstop,
++ eject, 0, SSD_FULL_SIZE, 120000);
++ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
++ if (cam_send_ccb(cam_dev, ccb) < 0) {
++ perror("error sending start unit");
++
++ cam_freeccb(ccb);
++ return(1);
++ }
++
++ if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
++ if (startstop)
++ {
++ kdDebug() << "(K3bCdDevice) bsd_open_close_device: Unit started successfully" << endl;
++ if (eject)
++ kdDebug() << "(K3bCdDevice) bsd_open_close_device: Media loaded" << endl;
++ }
++ else
++ {
++ kdDebug() << "(K3bCdDevice) bsd_open_close_device: Unit stopped successfully" << endl;
++ if (eject)
++ kdDebug() << "(K3bCdDevice) bsd_open_close_device: Media ejected" << endl;
++ }
++ else
++ {
++ error = 1;
++ if (startstop)
++ kdDebug() << "(K3bCdDevice) bsd_open_close_device: Error received from start unit command" << endl;
++ else
++ kdDebug() << "(K3bCdDevice) bsd_open_close_device: Error received from stop unit command" << endl;
++ }
++ cam_freeccb(ccb);
++ return error;
++}
++
++#endif
diff --git a/sysutils/k3b/files/patch-src-core-device-k3bdevice.h b/sysutils/k3b/files/patch-src-core-device-k3bdevice.h
new file mode 100644
index 000000000000..7ec39a99dbdb
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-core-device-k3bdevice.h
@@ -0,0 +1,50 @@
+--- src/core/device/k3bdevice.h.orig Thu Oct 23 10:37:05 2003
++++ src/core/device/k3bdevice.h Fri Nov 7 12:35:44 2003
+@@ -21,6 +21,10 @@
+ #include <k3bdiskinfo.h>
+ #include <k3bcdtext.h>
+ #include <k3bmsf.h>
++#ifdef __FreeBSD__
++#include "k3btoc.h"
++#include <qdatetime.h>
++#endif
+
+
+ namespace K3bCdDevice
+@@ -43,10 +47,10 @@
+ CDROM = 4,
+ DVD = 8,
+ DVDRAM = 16,
+- DVDR = 32,
+- DVDRW = 64,
+- DVDPR = 128,
+- DVDPRW = 256 };
++ DVDR = 32, // "minus"
++ DVDRW = 64, // "minus"
++ DVDPR = 128, // "plus"
++ DVDPRW = 256 }; // "plus"
+ enum DiskStatus { EMPTY = 0,
+ APPENDABLE = 1,
+ COMPLETE = 2,
+@@ -420,6 +424,21 @@
+ private:
+ class Private;
+ Private* d;
++#ifdef __FreeBSD__
++ // allow K3bDeviceManager::initializeScsiDevice to set the device types
++ void addDeviceType(CdDevice::DeviceType type);
++
++ // allow K3bDeviceManager::initializeScsiDevice to guess the profiles, if none where found so far
++ void guessProfiles();
++
++ Toc m_toc;
++ int m_driveReady, m_rewritableCd;
++ K3b::Msf m_discSize, m_remainingSize;
++ void refreshDeviceData();
++ QDateTime m_lastRefresh;
++ int m_deviceStatus;
++ QString m_passDevice;
++#endif
+ friend class DeviceManager;
+ };
+
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"
diff --git a/sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.h b/sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.h
new file mode 100644
index 000000000000..2ffbb976a1ed
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-core-device-k3bdevicemanager.h
@@ -0,0 +1,43 @@
+--- src/core/device/k3bdevicemanager.h.orig Thu Aug 7 18:52:05 2003
++++ src/core/device/k3bdevicemanager.h Fri Nov 7 12:35:44 2003
+@@ -24,6 +24,10 @@
+ #include <qptrlist.h>
+
+ #include <kdebug.h>
++#ifdef __FreeBSD__
++#include <qdatetime.h>
++#include <qvaluelist.h>
++#endif
+
+ class KProcess;
+ class KConfig;
+@@ -116,6 +120,29 @@
+
+ class Private;
+ Private* d;
++#ifdef __FreeBSD__
++ void bsd_scan_devices(bool sudo);
++ QDateTime m_lastRefresh;
++ class BSDDevice
++ {
++ public:
++ BSDDevice() : m_bus(-1), m_target(-1), m_lun(-1) {}
++ BSDDevice(const QString & name, const QString & passDevice, const QString & vendor,
++ const QString & product, const QString & revision, int bus, int target, int lun) :
++ m_name(name), m_passDevice(passDevice), m_vendor(vendor), m_product(product),
++ m_revision(revision), m_bus(bus), m_target(target), m_lun(lun) {}
++ BSDDevice(const BSDDevice & src) :
++ m_name(src.m_name), m_passDevice(src.m_passDevice), m_vendor(src.m_vendor), m_product(src.m_product),
++ m_revision(src.m_revision), m_bus(src.m_bus), m_target(src.m_target), m_lun(src.m_lun) {}
++ const BSDDevice & operator= (const BSDDevice & src)
++ { m_name = src.m_name; m_passDevice = src.m_passDevice; m_vendor = src.m_vendor;
++ m_product = src.m_product; m_revision = src.m_revision; m_bus = src.m_bus; m_target = src.m_target;
++ m_lun = src.m_lun; return *this; }
++ QString m_name, m_passDevice, m_vendor, m_product, m_revision;
++ int m_bus, m_target, m_lun;
++ };
++ QValueList<BSDDevice> m_devices;
++#endif
+ };
+
+ /**
diff --git a/sysutils/k3b/files/patch-src-core-device-k3bscsicommand.cpp b/sysutils/k3b/files/patch-src-core-device-k3bscsicommand.cpp
new file mode 100644
index 000000000000..f11d2fc0ff38
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-core-device-k3bscsicommand.cpp
@@ -0,0 +1,127 @@
+--- src/core/device/k3bscsicommand.cpp.orig Mon Sep 1 12:20:02 2003
++++ src/core/device/k3bscsicommand.cpp Fri Nov 7 12:35:44 2003
+@@ -14,33 +14,70 @@
+ */
+
+ #include "k3bscsicommand.h"
+-
++#include <fcntl.h>
++#include <cam/scsi/scsi_message.h>
++#include <cam/scsi/scsi_pass.h>
++#include <errno.h>
++#define ERRCODE(s) ((((s)[2]&0x0F)<<16)|((s)[12]<<8)|((s)[13]))
++#define EMEDIUMTYPE EINVAL
++#define ENOMEDIUM ENODEV
++#define CREAM_ON_ERRNO(s) do { \
++ switch ((s)[12]) \
++ { case 0x04: errno=EAGAIN; break; \
++ case 0x20: errno=ENODEV; break; \
++ case 0x21: if ((s)[13]==0) errno=ENOSPC; \
++ else errno=EINVAL; \
++ break; \
++ case 0x30: errno=EMEDIUMTYPE; break; \
++ case 0x3A: errno=ENOMEDIUM; break; \
++ } \
++} while(0)
++#include <unistd.h>
+ #include <kdebug.h>
+
+ #include <string.h>
+ #include <sys/ioctl.h>
+
+
+-K3bCdDevice::ScsiCommand::ScsiCommand( int fd )
+- : m_fd(fd)
++K3bCdDevice::ScsiCommand::ScsiCommand( const QString & passDevice )
++ : m_passDevice(passDevice)
+ {
+ clear();
+ }
+
++K3bCdDevice::ScsiCommand::~ScsiCommand()
++{
++ if(cam)
++ cam_close_device(cam);
++// if (m_fd >0)
++// close(m_fd);
++}
++
+
+ void K3bCdDevice::ScsiCommand::clear()
+ {
+- ::memset( &m_cmd, 0, sizeof(struct cdrom_generic_command) );
+- ::memset( &m_sense, 0, sizeof(struct request_sense) );
+-
+- m_cmd.quiet = 1;
+- m_cmd.sense = &m_sense;
++// char pass[32];
++ cam=NULL;
++ memset (&ccb,0,sizeof(ccb));
++ ccb.ccb_h.func_code = XPT_GDEVLIST;
++// if (ioctl (m_fd,CAMGETPASSTHRU,&ccb) < 0) return;
++// sprintf (pass,"/dev/%.15s%u",ccb.cgdl.periph_name,ccb.cgdl.unit_number);
++ cam = cam_open_pass (m_passDevice.latin1(),O_RDWR,NULL);
++ kdDebug() << "(K3bCdDevice::ScsiCommand) open device " << m_passDevice << ((cam)?" succeeded.":" failed.") << endl;
+ }
+
+-
+ unsigned char& K3bCdDevice::ScsiCommand::operator[]( size_t i )
+ {
+- return m_cmd.cmd[i];
++ if (!i && cam)
++ {
++ memset(&ccb,0,sizeof(ccb));
++ ccb.ccb_h.path_id = cam->path_id;
++ ccb.ccb_h.target_id = cam->target_id;
++ ccb.ccb_h.target_lun = cam->target_lun;
++ cam_fill_csio (&(ccb.csio), 1, NULL, CAM_DEV_QFRZDIS, MSG_SIMPLE_Q_TAG, NULL, 0, sizeof(ccb.csio.sense_data), 0, 30*1000);
++ }
++ ccb.csio.cdb_len = i+1;
++ return ccb.csio.cdb_io.cdb_bytes[i];
+ }
+
+
+@@ -48,20 +85,29 @@
+ void* data,
+ size_t len )
+ {
+- m_cmd.buffer = (unsigned char*)data;
+- m_cmd.buflen = len;
+- if( dir == TR_DIR_READ )
+- m_cmd.data_direction = CGC_DATA_READ;
+- else if( dir == TR_DIR_WRITE )
+- m_cmd.data_direction = CGC_DATA_WRITE;
+- else
+- m_cmd.data_direction = CGC_DATA_NONE;
+-
+- if( ::ioctl( m_fd, CDROM_SEND_PACKET, &m_cmd ) ) {
+- kdDebug() << "(K3bCdDevice::ScsiCommand) failed: fd: " << m_fd
+- << " errorcode: " << m_sense.error_code << endl;
+- return ( m_sense.error_code != 0 ? m_sense.error_code : -1 );
++ if (!cam)
++ return -1;
++ kdDebug() << "(K3bCdDevice::ScsiCommand) transport command " << QString::number((int)ccb.csio.cdb_io.cdb_bytes[0], 16) << ", length: " << (int)ccb.csio.cdb_len << endl;
++ int ret=0;
++ ccb.csio.ccb_h.flags |= dir;
++ ccb.csio.data_ptr = (u_int8_t *)data;
++ ccb.csio.dxfer_len = len;
++ if ((ret = cam_send_ccb(cam, &ccb)) < 0)
++ {
++ kdDebug() << "(K3bCdDevice::ScsiCommand) transport failed: " << ret << endl;
++ return -1;
+ }
+- else
++ if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
++ {
++ kdDebug() << "(K3bCdDevice::ScsiCommand) transport succeeded" << endl;
+ return 0;
++ }
++ errno = EIO;
++ ret = ERRCODE(((unsigned char *)&ccb.csio.sense_data));
++ if (ret == 0)
++ ret = -1;
++ else
++ CREAM_ON_ERRNO(((unsigned char *)&ccb.csio.sense_data));
++ kdDebug() << "(K3bCdDevice::ScsiCommand) transport failed (2): " << ret << endl;
++ return ret;
+ }
diff --git a/sysutils/k3b/files/patch-src-core-device-k3bscsicommand.h b/sysutils/k3b/files/patch-src-core-device-k3bscsicommand.h
new file mode 100644
index 000000000000..be3979b107a4
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-core-device-k3bscsicommand.h
@@ -0,0 +1,51 @@
+--- src/core/device/k3bscsicommand.h.orig Mon Oct 20 22:29:12 2003
++++ src/core/device/k3bscsicommand.h Fri Nov 7 12:35:44 2003
+@@ -17,9 +17,9 @@
+ #define _K3B_SCSI_COMMAND_H_
+
+ #include <sys/types.h>
+-#undef __STRICT_ANSI__
+-#include <linux/cdrom.h>
+-#define __STRICT_ANSI__
++#include <stdio.h>
++#include <camlib.h>
++#include <qstring.h>
+
+
+ namespace K3bCdDevice
+@@ -29,15 +29,17 @@
+ // see transport.hxx for a BSD version
+
+ enum TransportDirection {
+- TR_DIR_NONE,
+- TR_DIR_READ,
+- TR_DIR_WRITE
++ TR_DIR_NONE = 0,
++ TR_DIR_READ = CAM_DIR_IN,
++ TR_DIR_WRITE = CAM_DIR_OUT
+ };
+
+ class ScsiCommand
+ {
+ public:
+- ScsiCommand( int fd );
++ ScsiCommand( const QString & passDevice );
++
++ ~ScsiCommand();
+
+ void clear();
+
+@@ -48,10 +50,9 @@
+ size_t len = 0 );
+
+ private:
+- struct cdrom_generic_command m_cmd;
+- struct request_sense m_sense;
+-
+- int m_fd;
++ struct cam_device *cam;
++ union ccb ccb;
++ QString m_passDevice;
+ };
+ }
+
diff --git a/sysutils/k3b/files/patch-src-core-k3bdefaultexternalprograms.cpp b/sysutils/k3b/files/patch-src-core-k3bdefaultexternalprograms.cpp
new file mode 100644
index 000000000000..81c20927545b
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-core-k3bdefaultexternalprograms.cpp
@@ -0,0 +1,173 @@
+--- src/core/k3bdefaultexternalprograms.cpp.orig Fri Sep 26 14:04:36 2003
++++ src/core/k3bdefaultexternalprograms.cpp Fri Nov 7 12:35:44 2003
+@@ -28,7 +28,7 @@
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+-
++#include "k3bprocess.h"
+
+
+ void K3b::addDefaultPrograms( K3bExternalBinManager* m )
+@@ -89,7 +89,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ OutputCollector out( &vp );
+
+ vp << path << "-version";
+@@ -128,7 +128,7 @@
+
+
+ // probe features
+- KProcess fp;
++ MyKProcess fp;
+ out.setProcess( &fp );
+ fp << path << "-help";
+ if( fp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -200,7 +200,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ OutputCollector out( &vp );
+
+ vp << path << "-version";
+@@ -229,7 +229,7 @@
+
+
+ // probe features
+- KProcess fp;
++ MyKProcess fp;
+ out.setProcess( &fp );
+ fp << path << "-help";
+ if( fp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -285,7 +285,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ vp << path << "-version";
+ OutputCollector out( &vp );
+ if( vp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -313,7 +313,7 @@
+
+
+ // probe features
+- KProcess fp;
++ MyKProcess fp;
+ fp << path << "-help";
+ out.setProcess( &fp );
+ if( fp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -374,7 +374,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ vp << path << "-version";
+ OutputCollector out( &vp );
+ if( vp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -402,7 +402,7 @@
+
+
+ // probe features
+- KProcess fp;
++ MyKProcess fp;
+ fp << path << "-help";
+ out.setProcess( &fp );
+ if( fp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -462,7 +462,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ vp << path ;
+ OutputCollector out( &vp );
+ if( vp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -490,7 +490,7 @@
+
+
+ // probe features
+- KProcess fp;
++ MyKProcess fp;
+ fp << path << "write" << "-h";
+ out.setProcess( &fp );
+ if( fp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -554,7 +554,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ vp << path ;
+ OutputCollector out( &vp );
+ if( vp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -604,7 +604,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ vp << path;
+ OutputCollector out( &vp );
+ if( vp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -631,7 +631,7 @@
+ return false;
+ }
+
+- KProcess cp;
++ MyKProcess cp;
+ cp << path;
+ out.setProcess( &cp );
+ if( cp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -694,7 +694,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ vp << path << "-V";
+ OutputCollector out( &vp );
+ if( vp.start( KProcess::Block, KProcess::AllOutput ) ) {
+@@ -751,7 +751,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ OutputCollector out( &vp );
+
+ vp << path << "--version";
+@@ -810,7 +810,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ OutputCollector out( &vp );
+
+ vp << path << "-version";
+@@ -879,7 +879,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ OutputCollector out( &vp );
+
+ vp << path;
+@@ -952,7 +952,7 @@
+ K3bExternalBin* bin = 0;
+
+ // probe version
+- KProcess vp;
++ MyKProcess vp;
+ OutputCollector out( &vp );
+
+ vp << path << "-h";
diff --git a/sysutils/k3b/files/patch-src-core-k3bglobals.cpp b/sysutils/k3b/files/patch-src-core-k3bglobals.cpp
new file mode 100644
index 000000000000..711480a51930
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-core-k3bglobals.cpp
@@ -0,0 +1,16 @@
+--- src/core/k3bglobals.cpp.orig Mon Sep 29 13:16:55 2003
++++ src/core/k3bglobals.cpp Fri Nov 7 12:35:44 2003
+@@ -30,8 +30,12 @@
+
+ #include <cmath>
+ #include <sys/utsname.h>
++#ifdef __FreeBSD__
++#include <sys/param.h>
++#include <sys/mount.h>
++#else
+ #include <sys/vfs.h>
+-
++#endif
+
+
+ struct Sample {
diff --git a/sysutils/k3b/files/patch-src-core-k3bprocess.cpp b/sysutils/k3b/files/patch-src-core-k3bprocess.cpp
new file mode 100644
index 000000000000..2453710cd98f
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-core-k3bprocess.cpp
@@ -0,0 +1,63 @@
+--- src/core/k3bprocess.cpp.orig Thu Sep 25 13:34:51 2003
++++ src/core/k3bprocess.cpp Fri Nov 7 12:35:44 2003
+@@ -27,7 +27,60 @@
+ #include <unistd.h>
+ #include <stdio.h>
+ #include <fcntl.h>
++#include <ktempfile.h>
++#include <stdlib.h>
++#include <qfile.h>
++MyKProcess & MyKProcess::operator<<(const QString& arg)
++{
++ m_args += " " + arg;
++ return *this;
++}
+
++MyKProcess &MyKProcess::operator<<(const char * arg)
++{
++ m_args += " ";
++ m_args += arg;
++ return *this;
++}
++
++MyKProcess &MyKProcess::operator<<(const QCString & arg)
++{
++ m_args += " " + arg;
++ return *this;
++}
++
++bool MyKProcess::start(KProcess::RunMode runmode, KProcess::Communication comm)
++{
++ // create temp file
++ KTempFile tmpfile;
++ tmpfile.setAutoDelete(true);
++
++ // create call
++ QString call = "/bin/sh -c \"" + m_args + " > " + tmpfile.name() + " 2>&1 \"";
++ printf("MyKProcess call: %s\n", call.latin1());
++
++ // execute it
++ system(call.latin1());
++
++ // read tmp file line by line
++ QFile tmp (tmpfile.name());
++ if ( tmp.open( IO_ReadOnly ) )
++ {
++ QTextStream stream( &tmp );
++ while ( !stream.eof() )
++ {
++ QString s = stream.readLine() + "\n";
++ printf("MyKProcess reponse: %s", s.latin1());
++
++ // send line to receivedStdout signal
++ receivedStdout(this, (char *)s.latin1(), strlen(s.latin1()));
++ }
++
++ // close and delete tmp file
++ tmp.close();
++ }
++ return true;
++}
+
+
+ class K3bProcess::Private
diff --git a/sysutils/k3b/files/patch-src-core-k3bprocess.h b/sysutils/k3b/files/patch-src-core-k3bprocess.h
new file mode 100644
index 000000000000..23f15634e044
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-core-k3bprocess.h
@@ -0,0 +1,25 @@
+--- src/core/k3bprocess.h.orig Fri Aug 29 17:32:44 2003
++++ src/core/k3bprocess.h Fri Nov 7 12:35:44 2003
+@@ -126,5 +126,22 @@
+ bool m_suppressEmptyLines;
+ };
+
++/** This is a KProcess fake class. It uses system() to call the process
++ * and waits for its return. It redirects all output into a file and
++ * reads this file after the system() call. The redirected output
++ * (out and err!) is sent to the receivedStdout signal. This eliminates
++ * the problem reported as bug
++ * http://www.FreeBSD.org/cgi/query-pr.cgi?pr=ports/51651
++ */
++class MyKProcess : public KProcess
++{
++ Q_OBJECT
++ QString m_args;
++public:
++ MyKProcess &operator<<(const QString& arg);
++ MyKProcess &operator<<(const char * arg);
++ MyKProcess &operator<<(const QCString & arg);
++ bool start(RunMode runmode = NotifyOnExit, Communication comm = NoCommunication);
++};
+
+ #endif
diff --git a/sysutils/k3b/files/patch-src-rip-k3bmovieview.cpp b/sysutils/k3b/files/patch-src-rip-k3bmovieview.cpp
new file mode 100644
index 000000000000..d4f06f94b84d
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-rip-k3bmovieview.cpp
@@ -0,0 +1,14 @@
+--- src/rip/k3bmovieview.cpp.orig Thu Jun 12 16:07:42 2003
++++ src/rip/k3bmovieview.cpp Fri Nov 7 12:35:44 2003
+@@ -248,8 +248,11 @@
+ }
+
+ QWidget::show();
++ if (longestTitle)
++ {
+ longestTitle->parent()->setOpen( true );
+ m_listView->setSelected( longestTitle, true );
++ }
+ } else {
+ // error during parsing
+ emit notSupportedDisc( m_device->devicename() );
diff --git a/sysutils/k3b/files/patch-src-rip-k3btcwrapper.cpp b/sysutils/k3b/files/patch-src-rip-k3btcwrapper.cpp
new file mode 100644
index 000000000000..968abbd3ad20
--- /dev/null
+++ b/sysutils/k3b/files/patch-src-rip-k3btcwrapper.cpp
@@ -0,0 +1,35 @@
+--- src/rip/k3btcwrapper.cpp.orig Thu Jun 12 16:07:42 2003
++++ src/rip/k3btcwrapper.cpp Fri Nov 7 12:35:44 2003
+@@ -27,7 +27,7 @@
+ //#include <kprocess.h>
+ #include <klocale.h>
+ #include <kdebug.h>
+-
++#include <stdlib.h>
+
+ K3bTcWrapper::K3bTcWrapper( QObject* parent )
+ : QObject( parent )
+@@ -65,7 +65,14 @@
+ //K3bProcess *p = new K3bProcess();
+ emit tcprobeTitleParsed( m_currentTitle );
+
++#ifndef __FreeBSD__
+ *p << bin->path << "-i" << m_device->ioctlDevice() << "-T" << QString::number(m_currentTitle);
++#else
++ QString s = "mount " + m_device->mountPoint();
++ system(s.latin1());
++ kdDebug() << "(K3bDirView) executing: " << bin->path << " -i " << m_device->mountPoint() << " -T " << QString::number(m_currentTitle) << endl;
++ *p << bin->path << "-i" << m_device->mountPoint() << "-T" << QString::number(m_currentTitle);
++#endif
+ //p->setSplitStdout( true );
+ connect( p, SIGNAL(receivedStderr(KProcess*, char*, int)), this, SLOT(slotParseTcprobeError(KProcess*, char*, int)) );
+ connect( p, SIGNAL(receivedStdout(KProcess*, char*, int)), this, SLOT(slotParseTcprobeOutput(KProcess*, char*, int)) );
+@@ -115,7 +122,7 @@
+ // check dvd
+ for( QStringList::Iterator str = errorLines.begin(); str != errorLines.end(); str++ ) {
+ kdDebug() << (*str) << endl;
+- if( !(*str).contains("tcprobe") && !(*str).contains("DVD image/device") ) {
++ if( !(*str).contains("tcprobe") || !(*str).contains("DVD image/device") ) {
+ continue;
+ } else{
+ isDvd = true;