Esempio n. 1
0
/*
 * DBus UDisk AddDevice handler
 */
void MediaMonitorUnix::deviceAdded( QDBusObjectPath o)
{
    LOG(VB_MEDIA, LOG_INFO, LOC + ":deviceAdded " + o.path());

    // Don't add devices with partition tables, just the partitions
    if (!DeviceProperty(o, "DeviceIsPartitionTable").toBool())
    {
        QString dev = DeviceProperty(o, "DeviceFile").toString();

        MythMediaDevice* pDevice;
        if (DeviceProperty(o, "DeviceIsRemovable").toBool())
            pDevice = MythCDROM::get(this, dev.toLatin1(), false, m_AllowEject);
        else
            pDevice = MythHDD::Get(this, dev.toLatin1(), false, false);

        if (pDevice && !AddDevice(pDevice))
            pDevice->deleteLater();
    }
}
Esempio n. 2
0
/**
 *  \brief Creates MythMedia instances for sysfs removable media devices.
 *
 *   Block devices are represented as directories in sysfs with directories
 *   for each partition underneath the parent device directory.
 *
 *   This function recursively calls itself to find all partitions on a block
 *   device and creates a MythHDD instance for each partition found.  If no
 *   partitions are found and the device is a CD or DVD device a MythCDROM
 *   instance is created.  Otherwise a MythHDD instance is created for the
 *   entire block device.
 *
 *  \param dev path to sysfs block device.
 *  \param checkPartitions check for partitions on block device.
 *  \return true if MythMedia instances are created.
 */
bool MediaMonitorUnix::FindPartitions(const QString &dev, bool checkPartitions)
{
    LOG(VB_MEDIA, LOG_DEBUG,
             LOC + ":FindPartitions(" + dev +
             QString(",%1").arg(checkPartitions ? " true" : " false" ) + ")");
    MythMediaDevice* pDevice = NULL;

    if (checkPartitions)
    {
        // check for partitions
        QDir sysfs(dev);
        sysfs.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);

        bool found_partitions = false;
        QStringList parts = sysfs.entryList();
        for (QStringList::iterator pit = parts.begin();
             pit != parts.end(); ++pit)
        {
            // skip some sysfs dirs that are _not_ sub-partitions
            if (*pit == "device" || *pit == "holders" || *pit == "queue"
                                 || *pit == "slaves"  || *pit == "subsystem"
                                 || *pit == "bdi"     || *pit == "power")
                continue;

            found_partitions |= FindPartitions(
                sysfs.absoluteFilePath(*pit), false);
        }

        // no partitions on block device, use main device
        if (!found_partitions)
            found_partitions |= FindPartitions(sysfs.absolutePath(), false);

        return found_partitions;
    }

    QString device_file = GetDeviceFile(dev);

    if (device_file.isEmpty())
        return false;

    QStringList cdroms = GetCDROMBlockDevices();

    if (cdroms.contains(dev.section('/', -1)))
    {
        // found cdrom device
            pDevice = MythCDROM::get(
                this, device_file.toLatin1().constData(), false, m_AllowEject);
    }
    else
    {
        // found block or partition device
            pDevice = MythHDD::Get(
                this, device_file.toLatin1().constData(), false, false);
    }

    if (AddDevice(pDevice))
        return true;

    if (pDevice)
        pDevice->deleteLater();

    return false;
}
Esempio n. 3
0
// Given a fstab entry to a media device determine what type of device it is
bool MediaMonitorUnix::AddDevice(struct fstab * mep)
{
    if (!mep)
        return false;

#ifndef Q_OS_ANDROID
    QString devicePath( mep->fs_spec );
#if 0
    LOG(VB_GENERAL, LOG_DEBUG, "AddDevice - " + devicePath);
#endif

    MythMediaDevice* pDevice = NULL;
    struct stat sbuf;

    bool is_supermount = false;
    bool is_cdrom = false;

    if (stat(mep->fs_spec, &sbuf) < 0)
       return false;

    //  Can it be mounted?
    if ( ! ( ((strstr(mep->fs_mntops, "owner") &&
        (sbuf.st_mode & S_IRUSR)) || strstr(mep->fs_mntops, "user")) &&
        (strstr(mep->fs_vfstype, MNTTYPE_ISO9660) ||
         strstr(mep->fs_vfstype, MNTTYPE_UDF) ||
         strstr(mep->fs_vfstype, MNTTYPE_AUTO)) ) )
    {
        if (strstr(mep->fs_mntops, MNTTYPE_ISO9660) &&
            strstr(mep->fs_vfstype, MNTTYPE_SUPERMOUNT))
        {
            is_supermount = true;
        }
        else
        {
            return false;
        }
    }

    if (strstr(mep->fs_mntops, MNTTYPE_ISO9660)  ||
        strstr(mep->fs_vfstype, MNTTYPE_ISO9660) ||
        strstr(mep->fs_vfstype, MNTTYPE_UDF)     ||
        strstr(mep->fs_vfstype, MNTTYPE_AUTO))
    {
        is_cdrom = true;
#if 0
        LOG(VB_GENERAL, LOG_DEBUG, "Device is a CDROM");
#endif
    }

    if (!is_supermount)
    {
        if (is_cdrom)
            pDevice = MythCDROM::get(this, mep->fs_spec,
                                     is_supermount, m_AllowEject);
    }
    else
    {
        char *dev = 0;
        int len = 0;
        dev = strstr(mep->fs_mntops, SUPER_OPT_DEV);
        if (dev == NULL)
            return false;

        dev += sizeof(SUPER_OPT_DEV)-1;
        while (dev[len] != ',' && dev[len] != ' ' && dev[len] != 0)
            len++;

        if (dev[len] != 0)
        {
            char devstr[256];
            strncpy(devstr, dev, len);
            devstr[len] = 0;
            if (is_cdrom)
                pDevice = MythCDROM::get(this, devstr,
                                         is_supermount, m_AllowEject);
        }
        else
            return false;
    }

    if (pDevice)
    {
        pDevice->setMountPath(mep->fs_file);
        if (pDevice->testMedia() == MEDIAERR_OK)
        {
            if (AddDevice(pDevice))
                return true;
        }
        pDevice->deleteLater();
    }
#endif

    return false;
}
Esempio n. 4
0
/**
 *  \brief Search /sys/block for valid removable media devices.
 *
 *   This function creates MediaDevice instances for valid removable media
 *   devices found under the /sys/block filesystem in Linux.  CD and DVD
 *   devices are created as MythCDROM instances.  MythHDD instances will be
 *   created for each partition on removable hard disk devices, if they exist.
 *   Otherwise a single MythHDD instance will be created for the entire disc.
 *
 *   NOTE: Floppy disks are ignored.
 */
bool MediaMonitorUnix::CheckMountable(void)
{
#if CONFIG_QTDBUS
    for (int i = 0; i < 10; ++i, usleep(500000))
    {
        // Connect to UDisks.  This can sometimes fail if mythfrontend
        // is started during system init
        QDBusInterface iface(UDISKS_SVC, UDISKS_PATH, UDISKS_IFACE,
            QDBusConnection::systemBus() );
        if (!iface.isValid())
        {
            LOG(VB_GENERAL, LOG_ALERT, LOC +
                "CheckMountable: DBus interface error: " +
                     iface.lastError().message() );
            continue;
        }

        // Enumerate devices
        typedef QList<QDBusObjectPath> QDBusObjectPathList;
        QDBusReply<QDBusObjectPathList> reply = iface.call("EnumerateDevices");
        if (!reply.isValid())
        {
            LOG(VB_GENERAL, LOG_ALERT, LOC +
                "CheckMountable DBus EnumerateDevices error: " +
                     reply.error().message() );
            continue;
        }

        // Listen on DBus for UDisk add/remove device messages
        (void)QDBusConnection::systemBus().connect(
            UDISKS_SVC, UDISKS_PATH, UDISKS_IFACE, UDISKS_DEVADD, UDISKS_DEVSIG,
            this, SLOT(deviceAdded(QDBusObjectPath)) );
        (void)QDBusConnection::systemBus().connect(
            UDISKS_SVC, UDISKS_PATH, UDISKS_IFACE, UDISKS_DEVRMV, UDISKS_DEVSIG,
            this, SLOT(deviceRemoved(QDBusObjectPath)) );

        // Parse the returned device array
        const QDBusObjectPathList& list(reply.value());
        for (QDBusObjectPathList::const_iterator it = list.begin();
            it != list.end(); ++it)
        {
            if (!DeviceProperty(*it, "DeviceIsSystemInternal").toBool() &&
                !DeviceProperty(*it, "DeviceIsPartitionTable").toBool() )
            {
                QString dev = DeviceProperty(*it, "DeviceFile").toString();

                // ignore floppies, too slow
                if (dev.startsWith("/dev/fd"))
                    continue;

                MythMediaDevice* pDevice;
                if (DeviceProperty(*it, "DeviceIsRemovable").toBool())
                    pDevice = MythCDROM::get(this, dev.toLatin1(), false, m_AllowEject);
                else
                    pDevice = MythHDD::Get(this, dev.toLatin1(), false, false);

                if (pDevice && !AddDevice(pDevice))
                    pDevice->deleteLater();
            }
        }

        // Success
        return true;
    }

    // Timed out
    return false;

#elif defined linux
    // NB needs script in /etc/udev/rules.d
    mkfifo(kUDEV_FIFO, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
    m_fifo = open(kUDEV_FIFO, O_RDONLY | O_NONBLOCK);

    QDir sysfs("/sys/block");
    sysfs.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);

    QStringList devices = sysfs.entryList();

    for (QStringList::iterator it = devices.begin(); it != devices.end(); ++it)
    {
        // ignore floppies, too slow
        if ((*it).startsWith("fd"))
            continue;

        sysfs.cd(*it);
        QString path = sysfs.absolutePath();
        if (CheckRemovable(path))
            FindPartitions(path, true);
        sysfs.cdUp();
    }
    return true;
#else // linux
    return false;
#endif
}