00001
00002 #include "config.h"
00003
00004
00005 #include <cstdio>
00006
00007
00008 #include <dirent.h>
00009 #include <unistd.h>
00010 #include <fcntl.h>
00011 #include <fstab.h>
00012
00013
00014 #include <sys/file.h>
00015 #include <sys/types.h>
00016 #include <sys/stat.h>
00017 #include <sys/wait.h>
00018 #include <sys/param.h>
00019
00020
00021 #include <iostream>
00022
00023 using namespace std;
00024
00025
00026 #if CONFIG_QTDBUS
00027 #include <QtDBus>
00028 #include <QDBusConnection>
00029 #endif
00030 #include <QList>
00031 #include <QTextStream>
00032 #include <QDir>
00033 #include <QFile>
00034
00035
00036 #include "mythmediamonitor.h"
00037 #include "mediamonitor-unix.h"
00038 #include "mythdialogs.h"
00039 #include "mythconfig.h"
00040 #include "mythcdrom.h"
00041 #include "mythhdd.h"
00042 #include "mythlogging.h"
00043 #include "mythsystem.h"
00044 #include "exitcodes.h"
00045
00046 #if HAVE_LIBUDEV
00047 extern "C" {
00048 #include <libudev.h>
00049 }
00050 #endif
00051
00052
00053 #ifndef MNTTYPE_ISO9660
00054 #ifdef linux
00055 #define MNTTYPE_ISO9660 "iso9660"
00056 #elif defined(__FreeBSD__) || CONFIG_DARWIN || defined(__OpenBSD__)
00057 #define MNTTYPE_ISO9660 "cd9660"
00058 #endif
00059 #endif
00060
00061 #ifndef MNTTYPE_UDF
00062 #define MNTTYPE_UDF "udf"
00063 #endif
00064
00065 #ifndef MNTTYPE_AUTO
00066 #define MNTTYPE_AUTO "auto"
00067 #endif
00068
00069 #ifndef MNTTYPE_SUPERMOUNT
00070 #define MNTTYPE_SUPERMOUNT "supermount"
00071 #endif
00072 #define SUPER_OPT_DEV "dev="
00073
00074 #if CONFIG_QTDBUS
00075
00076 #define UDISKS_SVC "org.freedesktop.UDisks"
00077 #define UDISKS_PATH "/org/freedesktop/UDisks"
00078 #define UDISKS_IFACE "org.freedesktop.UDisks"
00079 #define UDISKS_DEVADD "DeviceAdded"
00080 #define UDISKS_DEVRMV "DeviceRemoved"
00081 #define UDISKS_DEVSIG "o" // OBJECT_PATH
00082 #endif
00083
00084 const char * MediaMonitorUnix::kUDEV_FIFO = "/tmp/mythtv_media";
00085
00086
00087
00088
00089 static const QString LOC = QString("MMUnix:");
00090
00091
00092 static void fstabError(const QString &methodName)
00093 {
00094 LOG(VB_GENERAL, LOG_ALERT,
00095 LOC + methodName + " Error: failed to open " + _PATH_FSTAB +
00096 " for reading, " + ENO);
00097 }
00098
00099 static void statError(const QString &methodName, const QString devPath)
00100 {
00101 LOG(VB_GENERAL, LOG_ALERT,
00102 LOC + methodName + " Error: failed to stat " + devPath +
00103 ", " + ENO);
00104 }
00105
00107
00108
00109
00110 MediaMonitorUnix::MediaMonitorUnix(QObject* par,
00111 unsigned long interval, bool allowEject)
00112 : MediaMonitor(par, interval, allowEject), m_fifo(-1)
00113 {
00114 CheckFileSystemTable();
00115 CheckMountable();
00116
00117 LOG(VB_MEDIA, LOG_INFO, "Initial device list...\n" + listDevices());
00118 }
00119
00120
00121 #if !CONFIG_QTDBUS
00122 void MediaMonitorUnix::deleteLater(void)
00123 {
00124 if (m_fifo >= 0)
00125 {
00126 close(m_fifo);
00127 m_fifo = -1;
00128 unlink(kUDEV_FIFO);
00129 }
00130 MediaMonitor::deleteLater();
00131 }
00132 #endif // !CONFIG_QTDBUS
00133
00134
00135
00136 bool MediaMonitorUnix::CheckFileSystemTable(void)
00137 {
00138 struct fstab * mep = NULL;
00139
00140
00141 if (!setfsent())
00142 {
00143 fstabError(":CheckFileSystemTable()");
00144 return false;
00145 }
00146
00147
00148 while ((mep = getfsent()) != NULL)
00149 AddDevice(mep);
00150
00151 endfsent();
00152
00153 if (m_Devices.isEmpty())
00154 return false;
00155
00156 return true;
00157 }
00158
00159 #if CONFIG_QTDBUS
00160
00161 static QVariant DeviceProperty(const QDBusObjectPath& o, const char kszProperty[])
00162 {
00163 QVariant v;
00164
00165 QDBusInterface iface(UDISKS_SVC, o.path(), UDISKS_IFACE".Device",
00166 QDBusConnection::systemBus() );
00167 if (iface.isValid())
00168 v = iface.property(kszProperty);
00169
00170 return v;
00171 }
00172 #endif
00173
00185 bool MediaMonitorUnix::CheckMountable(void)
00186 {
00187 #if CONFIG_QTDBUS
00188 for (int i = 0; i < 10; ++i, usleep(500000))
00189 {
00190
00191
00192 QDBusInterface iface(UDISKS_SVC, UDISKS_PATH, UDISKS_IFACE,
00193 QDBusConnection::systemBus() );
00194 if (!iface.isValid())
00195 {
00196 LOG(VB_GENERAL, LOG_ALERT, LOC +
00197 "CheckMountable: DBus interface error: " +
00198 iface.lastError().message() );
00199 continue;
00200 }
00201
00202
00203 typedef QList<QDBusObjectPath> QDBusObjectPathList;
00204 QDBusReply<QDBusObjectPathList> reply = iface.call("EnumerateDevices");
00205 if (!reply.isValid())
00206 {
00207 LOG(VB_GENERAL, LOG_ALERT, LOC +
00208 "CheckMountable DBus EnumerateDevices error: " +
00209 reply.error().message() );
00210 continue;
00211 }
00212
00213
00214 (void)QDBusConnection::systemBus().connect(
00215 UDISKS_SVC, UDISKS_PATH, UDISKS_IFACE, UDISKS_DEVADD, UDISKS_DEVSIG,
00216 this, SLOT(deviceAdded(QDBusObjectPath)) );
00217 (void)QDBusConnection::systemBus().connect(
00218 UDISKS_SVC, UDISKS_PATH, UDISKS_IFACE, UDISKS_DEVRMV, UDISKS_DEVSIG,
00219 this, SLOT(deviceRemoved(QDBusObjectPath)) );
00220
00221
00222 const QDBusObjectPathList& list(reply.value());
00223 for (QDBusObjectPathList::const_iterator it = list.begin();
00224 it != list.end(); ++it)
00225 {
00226 if (!DeviceProperty(*it, "DeviceIsSystemInternal").toBool() &&
00227 !DeviceProperty(*it, "DeviceIsPartitionTable").toBool() )
00228 {
00229 QString dev = DeviceProperty(*it, "DeviceFile").toString();
00230
00231
00232 if (dev.startsWith("/dev/fd"))
00233 continue;
00234
00235 MythMediaDevice* pDevice;
00236 if (DeviceProperty(*it, "DeviceIsRemovable").toBool())
00237 pDevice = MythCDROM::get(this, dev.toAscii(), false, m_AllowEject);
00238 else
00239 pDevice = MythHDD::Get(this, dev.toAscii(), false, false);
00240
00241 if (pDevice && !AddDevice(pDevice))
00242 pDevice->deleteLater();
00243 }
00244 }
00245
00246
00247 return true;
00248 }
00249
00250
00251 return false;
00252
00253 #elif defined linux
00254
00255 mkfifo(kUDEV_FIFO, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
00256 m_fifo = open(kUDEV_FIFO, O_RDONLY | O_NONBLOCK);
00257
00258 QDir sysfs("/sys/block");
00259 sysfs.setFilter(QDir::Dirs);
00260
00261 QStringList devices = sysfs.entryList();
00262
00263 for (QStringList::iterator it = devices.begin(); it != devices.end(); ++it)
00264 {
00265 if (*it == "." || *it == "..")
00266 continue;
00267
00268
00269 if ((*it).startsWith("fd"))
00270 continue;
00271
00272 sysfs.cd(*it);
00273 QString path = sysfs.absolutePath();
00274 if (CheckRemovable(path))
00275 FindPartitions(path, true);
00276 sysfs.cdUp();
00277 }
00278 return true;
00279 #else // linux
00280 return false;
00281 #endif
00282 }
00283
00284 #if !CONFIG_QTDBUS
00285
00288 bool MediaMonitorUnix::CheckRemovable(const QString &dev)
00289 {
00290 #ifdef linux
00291 QString removablePath = dev + "/removable";
00292 QFile removable(removablePath);
00293 if (removable.exists() && removable.open(QIODevice::ReadOnly))
00294 {
00295 char c = 0;
00296 QString msg = LOC + ":CheckRemovable(" + dev + ")/removable ";
00297 bool ok = removable.getChar(&c);
00298 removable.close();
00299
00300 if (ok)
00301 {
00302 LOG(VB_MEDIA, LOG_DEBUG, msg + c);
00303 if (c == '1')
00304 return true;
00305 }
00306 else
00307 {
00308 LOG(VB_GENERAL, LOG_ALERT, msg + "failed");
00309 }
00310 }
00311 return false;
00312 #else // if !linux
00313 return false;
00314 #endif // !linux
00315 }
00316
00322 QString MediaMonitorUnix::GetDeviceFile(const QString &sysfs)
00323 {
00324 QString msg = LOC + ":GetDeviceFile(" + sysfs + ")";
00325 QString ret = sysfs;
00326
00327
00328 ret.replace(QRegExp(".*/"), "/dev/");
00329
00330 #ifdef linux
00331 #if HAVE_LIBUDEV
00332
00333 ret.clear();
00334 struct udev *udev = udev_new();
00335 if (udev != NULL)
00336 {
00337 struct udev_device *device =
00338 udev_device_new_from_syspath(udev, sysfs.toAscii().constData());
00339 if (device != NULL)
00340 {
00341 const char *name = udev_device_get_devnode(device);
00342
00343 if (name != NULL)
00344 ret = tr(name);
00345 else
00346 {
00347
00348
00349
00350
00351 LOG(VB_MEDIA, LOG_DEBUG, msg + " devnode not (yet) known");
00352 }
00353
00354 udev_device_unref(device);
00355 }
00356 else
00357 {
00358 LOG(VB_GENERAL, LOG_ALERT,
00359 msg + " udev_device_new_from_syspath returned NULL");
00360 ret = "";
00361 }
00362
00363 udev_unref(udev);
00364 }
00365 else
00366 LOG(VB_GENERAL, LOG_ALERT,
00367 "MediaMonitorUnix::GetDeviceFile udev_new failed");
00368 #else // HAVE_LIBUDEV
00369
00370 QStringList args;
00371 args << "info" << "-q" << "name"
00372 << "-rp" << sysfs;
00373
00374 uint flags = kMSStdOut | kMSBuffered;
00375 if (VERBOSE_LEVEL_CHECK(VB_MEDIA, LOG_DEBUG))
00376 flags |= kMSStdErr;
00377
00378
00379 MythSystem *udevinfo = new MythSystem("udevinfo", args, flags);
00380 udevinfo->Run(4);
00381 if( udevinfo->Wait() != GENERIC_EXIT_OK )
00382 {
00383 delete udevinfo;
00384 return ret;
00385 }
00386
00387 if (VERBOSE_LEVEL_CHECK(VB_MEDIA, LOG_DEBUG))
00388 {
00389 QTextStream estream(udevinfo->ReadAllErr());
00390 while( !estream.atEnd() )
00391 LOG(VB_MEDIA, LOG_DEBUG,
00392 msg + " - udevadm info error...\n" + estream.readLine());
00393 }
00394
00395 QTextStream ostream(udevinfo->ReadAll());
00396 QString udevLine = ostream.readLine();
00397 if (!udevLine.startsWith("device not found in database") )
00398 ret = udevLine;
00399
00400 delete udevinfo;
00401 #endif // HAVE_LIBUDEV
00402 #endif // linux
00403
00404 LOG(VB_MEDIA, LOG_INFO, msg + "->'" + ret + "'");
00405 return ret;
00406 }
00407 #endif // !CONFIG_QTDBUS
00408
00409
00410
00411
00412
00413
00414 QStringList MediaMonitorUnix::GetCDROMBlockDevices(void)
00415 {
00416 QStringList l;
00417
00418 #if CONFIG_QTDBUS
00419 QDBusInterface iface(UDISKS_SVC, UDISKS_PATH, UDISKS_IFACE,
00420 QDBusConnection::systemBus() );
00421 if (iface.isValid())
00422 {
00423
00424 typedef QList<QDBusObjectPath> QDBusObjectPathList;
00425 QDBusReply<QDBusObjectPathList> reply = iface.call("EnumerateDevices");
00426 if (reply.isValid())
00427 {
00428 const QDBusObjectPathList& list(reply.value());
00429 for (QDBusObjectPathList::const_iterator it = list.begin();
00430 it != list.end(); ++it)
00431 {
00432 if (DeviceProperty(*it, "DeviceIsRemovable").toBool())
00433 {
00434 QString dev = DeviceProperty(*it, "DeviceFile").toString();
00435 if (dev.startsWith("/dev/"))
00436 dev.remove(0,5);
00437 l.push_back(dev);
00438 }
00439 }
00440 }
00441 }
00442
00443 #elif defined linux
00444 QFile file("/proc/sys/dev/cdrom/info");
00445 if (file.open(QIODevice::ReadOnly))
00446 {
00447 QString line;
00448 QTextStream stream(&file);
00449 do
00450 {
00451 line = stream.readLine();
00452 if (line.startsWith("drive name:"))
00453 {
00454 l = line.split('\t', QString::SkipEmptyParts);
00455 l.pop_front();
00456 break;
00457 }
00458 }
00459 while (!stream.atEnd());
00460 file.close();
00461 }
00462 #endif // linux
00463
00464 LOG(VB_MEDIA, LOG_DEBUG,
00465 LOC + ":GetCDROMBlockDevices()->'" + l.join(", ") + "'");
00466 return l;
00467 }
00468
00469 static void LookupModel(MythMediaDevice* device)
00470 {
00471 QString desc;
00472
00473 #if CONFIG_QTDBUS
00474 QDBusInterface iface(UDISKS_SVC, UDISKS_PATH, UDISKS_IFACE,
00475 QDBusConnection::systemBus() );
00476 if (iface.isValid())
00477 {
00478 QDBusReply<QDBusObjectPath> reply = iface.call(
00479 "FindDeviceByDeviceFile", device->getRealDevice());
00480 if (reply.isValid())
00481 {
00482 desc = DeviceProperty(reply, "DriveVendor").toString();
00483 if (!desc.isEmpty())
00484 desc += " ";
00485 desc += DeviceProperty(reply, "DriveModel").toString();
00486 }
00487 }
00488
00489 #elif defined linux
00490
00491
00492 QString devname = device->getRealDevice().mid(5,5);
00493
00494 if (devname.startsWith("hd"))
00495 {
00496 QFile file("/proc/ide/" + devname.left(3) + "/model");
00497 if (file.open(QIODevice::ReadOnly))
00498 {
00499 QTextStream stream(&file);
00500
00501 desc.append(stream.readLine());
00502 file.close();
00503 }
00504 }
00505
00506 if (devname.startsWith("scd"))
00507 devname.replace("scd", "sr");
00508
00509 if (devname.startsWith("sd")
00510 || devname.startsWith("sr"))
00511 {
00512 QString path = devname.prepend("/sys/block/");
00513 path.append("/device/");
00514
00515 QFile file(path + "vendor");
00516 if (file.open(QIODevice::ReadOnly))
00517 {
00518 QTextStream stream(&file);
00519
00520 desc.append(stream.readLine());
00521 desc.append(' ');
00522 file.close();
00523 }
00524
00525 file.setFileName(path + "model");
00526 if (file.open(QIODevice::ReadOnly))
00527 {
00528 QTextStream stream(&file);
00529
00530 desc.append(stream.readLine());
00531 desc.append(' ');
00532 file.close();
00533 }
00534 }
00535 #endif
00536
00537 LOG(VB_MEDIA, LOG_DEBUG, QString("LookupModel '%1' -> '%2'")
00538 .arg(device->getRealDevice()).arg(desc) );
00539 device->setDeviceModel(desc.toAscii().constData());
00540 }
00541
00545 bool MediaMonitorUnix::AddDevice(MythMediaDevice* pDevice)
00546 {
00547 if ( ! pDevice )
00548 {
00549 LOG(VB_GENERAL, LOG_ERR, "MediaMonitorUnix::AddDevice(null)");
00550 return false;
00551 }
00552
00553
00554 if (shouldIgnore(pDevice))
00555 return false;
00556
00557 QString path = pDevice->getDevicePath();
00558 if (!path.length())
00559 {
00560 LOG(VB_GENERAL, LOG_ALERT,
00561 "MediaMonitorUnix::AddDevice() - empty device path.");
00562 return false;
00563 }
00564
00565 dev_t new_rdev;
00566 struct stat sb;
00567
00568 if (stat(path.toLocal8Bit().constData(), &sb) < 0)
00569 {
00570 statError(":AddDevice()", path);
00571 return false;
00572 }
00573 new_rdev = sb.st_rdev;
00574
00575
00576
00577
00578 QList<MythMediaDevice*>::const_iterator itr = m_Devices.begin();
00579 for (; itr != m_Devices.end(); ++itr)
00580 {
00581 if (stat((*itr)->getDevicePath().toLocal8Bit().constData(), &sb) < 0)
00582 {
00583 statError(":AddDevice()", (*itr)->getDevicePath());
00584 return false;
00585 }
00586
00587 if (sb.st_rdev == new_rdev)
00588 {
00589 LOG(VB_MEDIA, LOG_INFO,
00590 LOC + ":AddDevice() - not adding " + path +
00591 "\n "
00592 "because it appears to be a duplicate of " +
00593 (*itr)->getDevicePath());
00594 return false;
00595 }
00596 }
00597
00598 LookupModel(pDevice);
00599
00600 QMutexLocker locker(&m_DevicesLock);
00601
00602 connect(pDevice, SIGNAL(statusChanged(MythMediaStatus, MythMediaDevice*)),
00603 this, SLOT(mediaStatusChanged(MythMediaStatus, MythMediaDevice*)));
00604 m_Devices.push_back( pDevice );
00605 m_UseCount[pDevice] = 0;
00606 LOG(VB_MEDIA, LOG_INFO, LOC + ":AddDevice() - Added " + path);
00607
00608 return true;
00609 }
00610
00611
00612 bool MediaMonitorUnix::AddDevice(struct fstab * mep)
00613 {
00614 if (!mep)
00615 return false;
00616
00617 QString devicePath( mep->fs_spec );
00618 #if 0
00619 LOG(VB_GENERAL, LOG_DEBUG, "AddDevice - " + devicePath);
00620 #endif
00621
00622 MythMediaDevice* pDevice = NULL;
00623 struct stat sbuf;
00624
00625 bool is_supermount = false;
00626 bool is_cdrom = false;
00627
00628 if (stat(mep->fs_spec, &sbuf) < 0)
00629 return false;
00630
00631
00632 if ( ! ( ((strstr(mep->fs_mntops, "owner") &&
00633 (sbuf.st_mode & S_IRUSR)) || strstr(mep->fs_mntops, "user")) &&
00634 (strstr(mep->fs_vfstype, MNTTYPE_ISO9660) ||
00635 strstr(mep->fs_vfstype, MNTTYPE_UDF) ||
00636 strstr(mep->fs_vfstype, MNTTYPE_AUTO)) ) )
00637 {
00638 if (strstr(mep->fs_mntops, MNTTYPE_ISO9660) &&
00639 strstr(mep->fs_vfstype, MNTTYPE_SUPERMOUNT))
00640 {
00641 is_supermount = true;
00642 }
00643 else
00644 {
00645 return false;
00646 }
00647 }
00648
00649 if (strstr(mep->fs_mntops, MNTTYPE_ISO9660) ||
00650 strstr(mep->fs_vfstype, MNTTYPE_ISO9660) ||
00651 strstr(mep->fs_vfstype, MNTTYPE_UDF) ||
00652 strstr(mep->fs_vfstype, MNTTYPE_AUTO))
00653 {
00654 is_cdrom = true;
00655 #if 0
00656 LOG(VB_GENERAL, LOG_DEBUG, "Device is a CDROM");
00657 #endif
00658 }
00659
00660 if (!is_supermount)
00661 {
00662 if (is_cdrom)
00663 pDevice = MythCDROM::get(this, mep->fs_spec,
00664 is_supermount, m_AllowEject);
00665 }
00666 else
00667 {
00668 char *dev = 0;
00669 int len = 0;
00670 dev = strstr(mep->fs_mntops, SUPER_OPT_DEV);
00671 if (dev == NULL)
00672 return false;
00673
00674 dev += sizeof(SUPER_OPT_DEV)-1;
00675 while (dev[len] != ',' && dev[len] != ' ' && dev[len] != 0)
00676 len++;
00677
00678 if (dev[len] != 0)
00679 {
00680 char devstr[256];
00681 strncpy(devstr, dev, len);
00682 devstr[len] = 0;
00683 if (is_cdrom)
00684 pDevice = MythCDROM::get(this, devstr,
00685 is_supermount, m_AllowEject);
00686 }
00687 else
00688 return false;
00689 }
00690
00691 if (pDevice)
00692 {
00693 pDevice->setMountPath(mep->fs_file);
00694 if (pDevice->testMedia() == MEDIAERR_OK)
00695 {
00696 if (AddDevice(pDevice))
00697 return true;
00698 }
00699 pDevice->deleteLater();
00700 }
00701
00702 return false;
00703 }
00704
00705 #if CONFIG_QTDBUS
00706
00707
00708
00709 void MediaMonitorUnix::deviceAdded( QDBusObjectPath o)
00710 {
00711 LOG(VB_MEDIA, LOG_INFO, LOC + ":deviceAdded " + o.path());
00712
00713
00714 if (!DeviceProperty(o, "DeviceIsPartitionTable").toBool())
00715 {
00716 QString dev = DeviceProperty(o, "DeviceFile").toString();
00717
00718 MythMediaDevice* pDevice;
00719 if (DeviceProperty(o, "DeviceIsRemovable").toBool())
00720 pDevice = MythCDROM::get(this, dev.toAscii(), false, m_AllowEject);
00721 else
00722 pDevice = MythHDD::Get(this, dev.toAscii(), false, false);
00723
00724 if (pDevice && !AddDevice(pDevice))
00725 pDevice->deleteLater();
00726 }
00727 }
00728
00729
00730
00731
00732 void MediaMonitorUnix::deviceRemoved( QDBusObjectPath o)
00733 {
00734 LOG(VB_MEDIA, LOG_INFO, LOC + "deviceRemoved " + o.path());
00735 #if 0 // This fails because the DeviceFile has just been deleted
00736 QString dev = DeviceProperty(o, "DeviceFile");
00737 if (!dev.isEmpty())
00738 RemoveDevice(dev);
00739 #else
00740 QString dev = QFileInfo(o.path()).baseName();
00741 dev.prepend("/dev/");
00742 RemoveDevice(dev);
00743 #endif
00744 }
00745
00746 #else //CONFIG_QTDBUS
00747
00764 bool MediaMonitorUnix::FindPartitions(const QString &dev, bool checkPartitions)
00765 {
00766 LOG(VB_MEDIA, LOG_DEBUG,
00767 LOC + ":FindPartitions(" + dev +
00768 QString(",%1").arg(checkPartitions ? " true" : " false" ) + ")");
00769 MythMediaDevice* pDevice = NULL;
00770
00771 if (checkPartitions)
00772 {
00773
00774 QDir sysfs(dev);
00775 sysfs.setFilter(QDir::Dirs);
00776
00777 bool found_partitions = false;
00778 QStringList parts = sysfs.entryList();
00779 for (QStringList::iterator pit = parts.begin();
00780 pit != parts.end(); ++pit)
00781 {
00782 if (*pit == "." || *pit == "..")
00783 continue;
00784
00785
00786 if (*pit == "device" || *pit == "holders" || *pit == "queue"
00787 || *pit == "slaves" || *pit == "subsystem"
00788 || *pit == "bdi" || *pit == "power")
00789 continue;
00790
00791 found_partitions |= FindPartitions(
00792 sysfs.absoluteFilePath(*pit), false);
00793 }
00794
00795
00796 if (!found_partitions)
00797 found_partitions |= FindPartitions(sysfs.absolutePath(), false);
00798
00799 return found_partitions;
00800 }
00801
00802 QString device_file = GetDeviceFile(dev);
00803
00804 if (device_file.isEmpty())
00805 return false;
00806
00807 QStringList cdroms = GetCDROMBlockDevices();
00808
00809 if (cdroms.contains(dev.section('/', -1)))
00810 {
00811
00812 pDevice = MythCDROM::get(
00813 this, device_file.toAscii().constData(), false, m_AllowEject);
00814 }
00815 else
00816 {
00817
00818 pDevice = MythHDD::Get(
00819 this, device_file.toAscii().constData(), false, false);
00820 }
00821
00822 if (AddDevice(pDevice))
00823 return true;
00824
00825 if (pDevice)
00826 pDevice->deleteLater();
00827
00828 return false;
00829 }
00830
00836 void MediaMonitorUnix::CheckDeviceNotifications(void)
00837 {
00838 char buffer[256];
00839 QString qBuffer;
00840
00841 if (m_fifo == -1)
00842 return;
00843
00844 int size = read(m_fifo, buffer, 255);
00845 while (size > 0)
00846 {
00847
00848 buffer[size] = '\0';
00849 qBuffer.append(buffer);
00850 size = read(m_fifo, buffer, 255);
00851 }
00852 const QStringList list = qBuffer.split('\n', QString::SkipEmptyParts);
00853
00854 QStringList::const_iterator it = list.begin();
00855 for (; it != list.end(); ++it)
00856 {
00857 if ((*it).startsWith("add"))
00858 {
00859 QString dev = (*it).section(' ', 1, 1);
00860 LOG(VB_MEDIA, LOG_INFO, "Udev add " + dev);
00861
00862 if (CheckRemovable(dev))
00863 FindPartitions(dev, true);
00864 }
00865 else if ((*it).startsWith("remove"))
00866 {
00867 QString dev = (*it).section(' ', 2, 2);
00868 LOG(VB_MEDIA, LOG_INFO, "Udev remove " + dev);
00869 RemoveDevice(dev);
00870 }
00871 }
00872 }
00873 #endif //!CONFIG_QTDBUS
00874