Index: libs/libmythtv/RingBuffer.cpp =================================================================== --- libs/libmythtv/RingBuffer.cpp (revision 25722) +++ libs/libmythtv/RingBuffer.cpp (working copy) @@ -304,16 +304,22 @@ #ifdef USING_FRONTEND else if (filename.left(4) == "dvd:") { +VERBOSE(VB_PLAYBACK, "OpenFile() checking DVD at " + filename); is_dvd = true; dvdPriv = new DVDRingBufferPriv(); startreadahead = false; - if (filename.left(6) == "dvd://") // 'Play DVD' sends "dvd:/" + dev - filename.remove(0,5); // e.g. "dvd://dev/sda" - else // Less correct URI "dvd:" + path - filename.remove(0,4); // e.g. "dvd:/videos/ET" + if (filename.left(12) == "dvd://myth://") + filename.remove(0,6); + else if (filename.left(12) == "dvd:/myth://") + filename.remove(0,5); + else if (filename.left(6) == "dvd://") // 'Play DVD' sends "dvd:/" + dev + filename.remove(0,5); // e.g. "dvd://dev/sda" + else // Less correct URI "dvd:" + path + filename.remove(0,4); // e.g. "dvd:/videos/ET" - if (QFile::exists(filename)) +VERBOSE(VB_PLAYBACK, "OpenFile() now checking DVD at " + filename); + if (QFile::exists(filename) || filename.startsWith("myth://")) VERBOSE(VB_PLAYBACK, "OpenFile() trying DVD at " + filename); else { @@ -326,12 +332,16 @@ bdPriv = new BDRingBufferPriv(); startreadahead = false; - if (filename.left(5) == "bd://") // 'Play DVD' sends "bd:/" + dev - filename.remove(0,4); // e.g. "bd://dev/sda" - else // Less correct URI "bd:" + path - filename.remove(0,3); // e.g. "bd:/videos/ET" + if (filename.left(12) == "bd://myth://") + filename.remove(0,5); + else if (filename.left(12) == "bd:/myth://") + filename.remove(0,4); + else if (filename.left(5) == "bd://") // 'Play DVD' sends "bd:/" + dev + filename.remove(0,4); // e.g. "bd://dev/sda" + else // Less correct URI "bd:" + path + filename.remove(0,3); // e.g. "bd:/videos/ET" - if (QFile::exists(filename)) + if (QFile::exists(filename) || filename.startsWith("myth://")) VERBOSE(VB_PLAYBACK, "OpenFile() trying BD at " + filename); else { Index: libs/libmythdvdnav/dvdnav/vm/vm.c =================================================================== --- libs/libmythdvdnav/dvdnav/vm/vm.c (revision 25722) +++ libs/libmythdvdnav/dvdnav/vm/vm.c (working copy) @@ -171,11 +171,13 @@ uint8_t data[DVD_VIDEO_LB_LEN]; /* Read DVD name */ - fd = open(device, O_RDONLY); +//CTP fd = open(device, O_RDONLY); + fd = remotefile_open(device, O_RDONLY); if (fd > 0) { off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET ); if( off == ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) { - off = read( fd, data, DVD_VIDEO_LB_LEN ); +//CTP off = read( fd, data, DVD_VIDEO_LB_LEN ); + off = remotefile_read( fd, data, DVD_VIDEO_LB_LEN ); if (off == ( (off_t) DVD_VIDEO_LB_LEN )) { fprintf(MSG_OUT, "libdvdnav: DVD Title: "); for(i=25; i < 73; i++ ) { @@ -215,7 +217,8 @@ } else { fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 ); } - close(fd); +//CTP close(fd); + remotefile_close(fd); } else { fprintf(MSG_OUT, "NAME OPEN FAILED\n"); } Index: libs/libmythdvdnav/dvdread/dvd_reader.c =================================================================== --- libs/libmythdvdnav/dvdread/dvd_reader.c (revision 25722) +++ libs/libmythdvdnav/dvdread/dvd_reader.c (working copy) @@ -68,6 +68,7 @@ #include "dvd_input.h" #include "dvdread/dvd_reader.h" #include "md5.h" +#include "remotefile_wrapper.h" #define DEFAULT_UDF_CACHE_LEVEL 1 @@ -366,7 +367,8 @@ } #endif - ret = stat( path, &fileinfo ); +//CTP ret = stat( path, &fileinfo ); + ret = remotefile_stat( path, &fileinfo ); if( ret < 0 ) { @@ -383,6 +385,7 @@ goto DVDOpen_error; } +fprintf(stderr, "CTP: fileinfo.stmode = %x\n", fileinfo.st_mode); /* First check if this is a block/char device or a file*/ if( S_ISBLK( fileinfo.st_mode ) || S_ISCHR( fileinfo.st_mode ) || @@ -419,6 +422,9 @@ /* Also WIN32 does not have symlinks, so we don't need this bit of code. */ /* Resolve any symlinks and get the absolute dir name. */ +//CTP +dev_name = strdup( path ); +if (0) { if( ( cdir = open( ".", O_RDONLY ) ) >= 0 ) { if( chdir( path_copy ) == -1 ) { @@ -630,6 +636,16 @@ DIR *dir; struct dirent *ent; +//CTP +if (remotefile_exists(path, file)) +{ + sprintf( filename, "%s%s%s", path, + ( ( path[ strlen( path ) - 1 ] == '/' ) ? "" : "/" ), + file ); + return 0; +} +return -1; + dir = opendir( path ); if( !dir ) return -2; @@ -712,7 +728,8 @@ memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = 0; - if( stat( full_path, &fileinfo ) < 0 ) { +//CTP if( stat( full_path, &fileinfo ) < 0 ) { + if( remotefile_stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); free( dvd_file ); dvdinput_close(dev); @@ -811,7 +828,8 @@ return NULL; } - if( stat( full_path, &fileinfo ) < 0 ) { +//CTP if( stat( full_path, &fileinfo ) < 0 ) { + if( remotefile_stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); dvdinput_close(dev); free( dvd_file ); @@ -830,7 +848,8 @@ break; } - if( stat( full_path, &fileinfo ) < 0 ) { +//CT{ if( stat( full_path, &fileinfo ) < 0 ) { + if( remotefile_stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); break; } @@ -982,7 +1001,8 @@ if( !findDVDFile( dvd, filename, full_path ) ) return -1; - if( stat( full_path, &fileinfo ) < 0 ) { +//CT{ if( stat( full_path, &fileinfo ) < 0 ) { + if( remotefile_stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); return -1; } @@ -998,7 +1018,8 @@ if( !findDVDFile( dvd, filename, full_path ) ) break; - if( stat( full_path, &fileinfo ) < 0 ) { +//CT{ if( stat( full_path, &fileinfo ) < 0 ) { + if( remotefile_stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); break; } @@ -1079,9 +1100,10 @@ } } else { if( findDVDFile( dvd, filename, full_path ) ) { - if( stat( full_path, &fileinfo ) < 0 ) +//CT{ if( stat( full_path, &fileinfo ) < 0 ) + if( remotefile_stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); - else { + } else { statbuf->size = fileinfo.st_size; statbuf->nr_parts = 1; statbuf->parts_size[ 0 ] = statbuf->size; Index: libs/libmythdvdnav/dvdread/dvd_input.c =================================================================== --- libs/libmythdvdnav/dvdread/dvd_input.c (revision 25722) +++ libs/libmythdvdnav/dvdread/dvd_input.c (working copy) @@ -27,6 +27,7 @@ #include "config.h" #include "dvdread/dvd_reader.h" #include "dvd_input.h" +#include "remotefile_wrapper.h" /* The function pointers that is the exported interface of this file. */ @@ -161,6 +162,8 @@ { dvd_input_t dev; +// FIXME: CTP +fprintf(stderr, "CTP: Inside file_open(%s)\n", target); /* Allocate the library structure */ dev = (dvd_input_t) malloc(sizeof(*dev)); if(dev == NULL) { @@ -170,9 +173,11 @@ /* Open the device */ #if !defined(WIN32) && !defined(__OS2__) - dev->fd = open(target, O_RDONLY); +//CTP dev->fd = open(target, O_RDONLY); + dev->fd = remotefile_open(target, O_RDONLY); #else - dev->fd = open(target, O_RDONLY | O_BINARY); +//CTP dev->fd = open(target, O_RDONLY | O_BINARY); + dev->fd = remotefile_open(target, O_RDONLY | O_BINARY); #endif if(dev->fd < 0) { perror("libdvdread: Could not open input"); @@ -199,7 +204,10 @@ { off_t pos; - pos = lseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET); +// FIXME: CTP +fprintf(stderr, "CTP: Inside file_seek(%d), seeking to offset %d\n", dev->fd, blocks); +//CTP pos = lseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET); + pos = remotefile_seek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET); if(pos < 0) { return pos; } @@ -225,9 +233,12 @@ len = (size_t)blocks * DVD_VIDEO_LB_LEN; +// FIXME: CTP +fprintf(stderr, "CTP: Inside file_read(%d), reading %d blocks\n", dev->fd, blocks); while(len > 0) { - ret = read(dev->fd, buffer, len); +//CTP ret = read(dev->fd, buffer, len); + ret = remotefile_read(dev->fd, buffer, len); if(ret < 0) { /* One of the reads failed, too bad. We won't even bother @@ -241,7 +252,8 @@ * Adjust the file position back to the previous block boundary. */ size_t bytes = (size_t)blocks * DVD_VIDEO_LB_LEN - len; off_t over_read = -(bytes % DVD_VIDEO_LB_LEN); - /*off_t pos =*/ lseek(dev->fd, over_read, SEEK_CUR); +//CTP /*off_t pos =*/ lseek(dev->fd, over_read, SEEK_CUR); + /*off_t pos =*/ remotefile_seek(dev->fd, over_read, SEEK_CUR); /* should have pos % 2048 == 0 */ return (int) (bytes / DVD_VIDEO_LB_LEN); } @@ -259,7 +271,10 @@ { int ret; - ret = close(dev->fd); +// FIXME: CTP +fprintf(stderr, "CTP: Inside file_close(%d)\n", dev->fd); +//CTP ret = close(dev->fd); + ret = remotefile_close(dev->fd); if(ret < 0) return ret; Index: libs/libmythdvdnav/libmythdvdnav.pro =================================================================== --- libs/libmythdvdnav/libmythdvdnav.pro (revision 25722) +++ libs/libmythdvdnav/libmythdvdnav.pro (working copy) @@ -12,6 +12,7 @@ # for -ldl LIBS += $$EXTRA_LIBS +LIBS += -L../libmythdb -lmythdb-$$LIBVERSION DEFINES += HAVE_AV_CONFIG_H Index: libs/libmythdb/remotefile_wrapper.h =================================================================== --- libs/libmythdb/remotefile_wrapper.h (revision 0) +++ libs/libmythdb/remotefile_wrapper.h (revision 0) @@ -0,0 +1,21 @@ +#ifndef __REMOTEFILE_WRAPPER__ +#define __REMOTEFILE_WRAPPER__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int remotefile_open(const char *pathname, int flags); +int remotefile_close(int fd); +off_t remotefile_seek(int fd, off_t offset, int whence); +ssize_t remotefile_read(int fd, void *buf, size_t count); +int remotefile_stat(const char *path, struct stat *buf); +int remotefile_exists(const char *path, const char *file); + +#ifdef __cplusplus +} +#endif + +#endif Index: libs/libmythdb/remotefile_wrapper.cpp =================================================================== --- libs/libmythdb/remotefile_wrapper.cpp (revision 0) +++ libs/libmythdb/remotefile_wrapper.cpp (revision 0) @@ -0,0 +1,76 @@ + +#include +#include +#include +#include +#include + +#include + +#include "remotefile.h" + +int m_fileids = 0; +QMap m_remotefiles; + +extern "C" int remotefile_open(const char *pathname, int flags) +{ + fprintf(stderr, "CTP: inside remotefile_open(%s)\n", pathname); + + RemoteFile *rf = new RemoteFile(pathname, false, true, -1); + + if (!rf) + return -1; + + int fd = m_fileids++; + m_remotefiles[fd] = rf; + return fd; +} + +extern "C" int remotefile_close(int fd) +{ + fprintf(stderr, "CTP: inside remotefile_close(%d)\n", fd); + if (!m_remotefiles.contains(fd)) + return -1; + + RemoteFile *rf = m_remotefiles[fd]; + m_remotefiles.remove(fd); + rf->Close(); + delete rf; + + return 0; +} + +extern "C" off_t remotefile_seek(int fd, off_t offset, int whence) +{ + fprintf(stderr, "CTP: inside remotefile_seek(%d)\n", fd); + if (!m_remotefiles.contains(fd)) + return -1; + + return m_remotefiles[fd]->Seek(offset, whence); +} + +extern "C" ssize_t remotefile_read(int fd, void *buf, size_t count) +{ + fprintf(stderr, "CTP: inside remotefile_read(%d, %p, %d)\n", fd, buf, count); + if (!m_remotefiles.contains(fd)) + return -1; + + return m_remotefiles[fd]->Read(buf, count); +} + +extern "C" int remotefile_stat(const char *path, struct stat *buf) +{ + fprintf(stderr, "CTP: inside remotefile_stat(%s, %p)\n", path, buf); + + bool res = RemoteFile::Exists(path, buf); + if (res) + return 0; + + return -1; +} + +extern "C" bool remotefile_exists(const char *path, const char *file) +{ + return RemoteFile::Exists(QString("%1/%2").arg(path).arg(file)); +} + Index: libs/libmythdb/libmythdb.pro =================================================================== --- libs/libmythdb/libmythdb.pro (revision 25722) +++ libs/libmythdb/libmythdb.pro (working copy) @@ -19,6 +19,7 @@ HEADERS += mythcorecontext.h mythsystem.h mythlocale.h storagegroup.h HEADERS += mythcoreutil.h mythdownloadmanager.h mythtranslation.h HEADERS += unzip.h unzip_p.h zipentry_p.h iso639.h iso3166.h +HEADERS += remotefile_wrapper.h SOURCES += mythsocket.cpp mythsocketthread.cpp msocketdevice.cpp SOURCES += mythdbcon.cpp mythdb.cpp oldsettings.cpp mythverbose.cpp @@ -28,6 +29,7 @@ SOURCES += mythcorecontext.cpp mythsystem.cpp mythlocale.cpp storagegroup.cpp SOURCES += mythcoreutil.cpp mythdownloadmanager.cpp mythtranslation.cpp SOURCES += unzip.cpp iso639.cpp iso3166.cpp +SOURCES += remotefile_wrapper.cpp win32:SOURCES += msocketdevice_win.cpp unix { Index: libs/libmythdb/remotefile.h =================================================================== --- libs/libmythdb/remotefile.h (revision 25722) +++ libs/libmythdb/remotefile.h (working copy) @@ -1,6 +1,9 @@ #ifndef REMOTEFILE_H_ #define REMOTEFILE_H_ +#include + +#include #include #include @@ -24,6 +27,7 @@ long long Seek(long long pos, int whence, long long curpos = -1); static bool DeleteFile(const QString &url); + static bool Exists(const QString &url, struct stat *fileinfo); static bool Exists(const QString &url); static QString GetFileHash(const QString &url); static QDateTime LastModified(const QString &url); Index: libs/libmythdb/remotefile.cpp =================================================================== --- libs/libmythdb/remotefile.cpp (revision 25722) +++ libs/libmythdb/remotefile.cpp (working copy) @@ -235,6 +235,12 @@ bool RemoteFile::Exists(const QString &url) { + struct stat fileinfo; + return Exists(url, &fileinfo); +} + +bool RemoteFile::Exists(const QString &url, struct stat *fileinfo) +{ bool result = false; QUrl qurl(url); QString filename = qurl.path(); @@ -256,7 +262,26 @@ gCoreContext->SendReceiveStringList(strlist); if (strlist[0] == "1") + { result = true; + if (fileinfo) + { + int pos = 2; + fileinfo->st_dev = strlist[pos++].toLongLong(); + fileinfo->st_ino = strlist[pos++].toLongLong(); + fileinfo->st_mode = strlist[pos++].toLongLong(); + fileinfo->st_nlink = strlist[pos++].toLongLong(); + fileinfo->st_uid = strlist[pos++].toLongLong(); + fileinfo->st_gid = strlist[pos++].toLongLong(); + fileinfo->st_rdev = strlist[pos++].toLongLong(); + fileinfo->st_size = strlist[pos++].toLongLong(); + fileinfo->st_blksize = strlist[pos++].toLongLong(); + fileinfo->st_blocks = strlist[pos++].toLongLong(); + fileinfo->st_atime = strlist[pos++].toLongLong(); + fileinfo->st_mtime = strlist[pos++].toLongLong(); + fileinfo->st_ctime = strlist[pos++].toLongLong(); + } + } return result; } Index: programs/mythbackend/mainserver.cpp =================================================================== --- programs/mythbackend/mainserver.cpp (revision 25722) +++ programs/mythbackend/mainserver.cpp (working copy) @@ -2737,6 +2737,24 @@ { retlist << "1"; retlist << fullname; + + struct stat fileinfo; + if (stat(fullname.toLocal8Bit().constData(), &fileinfo) >= 0) + { + retlist << QString::number(fileinfo.st_dev); + retlist << QString::number(fileinfo.st_ino); + retlist << QString::number(fileinfo.st_mode); + retlist << QString::number(fileinfo.st_nlink); + retlist << QString::number(fileinfo.st_uid); + retlist << QString::number(fileinfo.st_gid); + retlist << QString::number(fileinfo.st_rdev); + retlist << QString::number(fileinfo.st_size); + retlist << QString::number(fileinfo.st_blksize); + retlist << QString::number(fileinfo.st_blocks); + retlist << QString::number(fileinfo.st_atime); + retlist << QString::number(fileinfo.st_mtime); + retlist << QString::number(fileinfo.st_ctime); + } } else retlist << "0";