Beispiel #1
0
MHWD::STATUS Mhwd::uninstallConfig(Config *config)
{
    std::shared_ptr<Config> installedConfig{getInstalledConfig(config->name_, config->type_)};

    // Check if installed
    if (nullptr == installedConfig)
    {
        return MHWD::STATUS::ERROR_NOT_INSTALLED;
    }
    else if (installedConfig->basePath_ != config->basePath_)
    {
        return MHWD::STATUS::ERROR_NO_MATCH_LOCAL_CONFIG;
    }
    else
    {
        // TODO: Should we check for local requirements here?

        // Run script
        if (!runScript(installedConfig, MHWD::TRANSACTIONTYPE::REMOVE))
        {
            return MHWD::STATUS::ERROR_SCRIPT_FAILED;
        }

        if (!removeDirectory(installedConfig->basePath_))
        {
            return MHWD::STATUS::ERROR_SET_DATABASE;
        }

        // Installed config vectors have to be updated manual with updateInstalledConfigData(Data*)

        return MHWD::STATUS::SUCCESS;
    }
}
Beispiel #2
0
mhwd::STATUS mhwd::performTransaction(mhwd::Data *data, mhwd::Transaction *transaction) {
    if (transaction->type == mhwd::Transaction::TYPE_INSTALL && !transaction->conflictedConfigs.empty())
        return STATUS_ERROR_CONFLICTS;
    else if (transaction->type == mhwd::Transaction::TYPE_REMOVE && !transaction->requiredByConfigs.empty())
        return STATUS_ERROR_REQUIREMENTS;


    // Check if already installed
    mhwd::Config *installedConfig = getInstalledConfig(data, transaction->config->name, transaction->config->type);
    mhwd::STATUS status = STATUS_SUCCESS;


    if (transaction->type == mhwd::Transaction::TYPE_REMOVE || (installedConfig != NULL && transaction->allowReinstallation)) {
        if (installedConfig == NULL)
                return STATUS_ERROR_NOT_INSTALLED;

        emitMessageFunc(data, mhwd::MESSAGETYPE_REMOVE_START, installedConfig->name);
        if ((status = uninstallConfig(data, installedConfig)) != STATUS_SUCCESS)
            return status;
        emitMessageFunc(data, mhwd::MESSAGETYPE_REMOVE_END, installedConfig->name);
    }

    if (transaction->type == mhwd::Transaction::TYPE_INSTALL) {
        // Check if already installed but not allowed to reinstall
        if (installedConfig != NULL && !transaction->allowReinstallation)
                return STATUS_ERROR_ALREADY_INSTALLED;

        // Install all dependencies first
        for (std::vector<mhwd::Config*>::const_iterator it = transaction->dependencyConfigs.end() - 1; it != transaction->dependencyConfigs.begin() - 1; --it) {
            emitMessageFunc(data, mhwd::MESSAGETYPE_INSTALLDEPENDENCY_START, (*it)->name);
            if ((status = installConfig(data, (*it))) != STATUS_SUCCESS)
                return status;
            emitMessageFunc(data, mhwd::MESSAGETYPE_INSTALLDEPENDENCY_END, (*it)->name);
        }

        emitMessageFunc(data, mhwd::MESSAGETYPE_INSTALL_START, transaction->config->name);
        if ((status = installConfig(data, transaction->config)) != STATUS_SUCCESS)
            return status;
        emitMessageFunc(data, mhwd::MESSAGETYPE_INSTALL_END, transaction->config->name);
    }

    return status;
}
Beispiel #3
0
int Mhwd::launch(int argc, char *argv[])
{
    std::vector<std::string> missingDirs { checkEnvironment() };
    if (!missingDirs.empty())
    {
        consoleWriter_.printError("Following directories do not exist:");
        for (const auto& dir : missingDirs)
        {
            consoleWriter_.printStatus(dir);
        }
        return 1;
    }

    std::string operationType;
    bool autoConfigureNonFreeDriver = false;
    std::string autoConfigureClassID;

    try
    {
        tryToParseCmdLineOptions(argc, argv, autoConfigureNonFreeDriver, operationType,
                autoConfigureClassID);
    }
    catch(const std::runtime_error& e)
    {
        consoleWriter_.printError(e.what());
        consoleWriter_.printHelp();
        return 1;
    }

    if (!optionsDontInterfereWithEachOther())
    {
        return 1;
    }

    // Check for invalid configs
    for (auto&& invalidConfig : data_.invalidConfigs)
    {
        consoleWriter_.printWarning("config '" + invalidConfig->configPath_ + "' is invalid!");
    }

    // > Perform operations:

    // List all configs
    if (arguments_.LIST_ALL && arguments_.SHOW_PCI)
    {
        if (!data_.allPCIConfigs.empty())
        {
            consoleWriter_.listConfigs(data_.allPCIConfigs, "All PCI configs:");
        }
        else
        {
            consoleWriter_.printWarning("No PCI configs found!");
        }
    }
    if (arguments_.LIST_ALL && arguments_.SHOW_USB)
    {
        if (!data_.allUSBConfigs.empty())
        {
            consoleWriter_.listConfigs(data_.allUSBConfigs, "All USB configs:");
        }
        else
        {
            consoleWriter_.printWarning("No USB configs found!");
        }
    }

    // List installed configs
    if (arguments_.LIST_INSTALLED && arguments_.SHOW_PCI)
    {
        if (arguments_.DETAIL)
        {
            consoleWriter_.printInstalledConfigs("PCI", data_.installedPCIConfigs);
        }
        else
        {
            if (!data_.installedPCIConfigs.empty())
            {
                consoleWriter_.listConfigs(data_.installedPCIConfigs, "Installed PCI configs:");
            }
            else
            {
                consoleWriter_.printWarning("No installed PCI configs!");
            }
        }
    }
    if (arguments_.LIST_INSTALLED && arguments_.SHOW_USB)
    {
        if (arguments_.DETAIL)
        {
            consoleWriter_.printInstalledConfigs("USB", data_.installedUSBConfigs);
        }
        else
        {
            if (!data_.installedUSBConfigs.empty())
            {
                consoleWriter_.listConfigs(data_.installedUSBConfigs, "Installed USB configs:");
            }
            else
            {
                consoleWriter_.printWarning("No installed USB configs!");
            }
        }
    }

    // List available configs
    if (arguments_.LIST_AVAILABLE && arguments_.SHOW_PCI)
    {
        if (arguments_.DETAIL)
        {
            consoleWriter_.printAvailableConfigsInDetail("PCI", data_.PCIDevices);
        }
        else
        {
            for (auto&& PCIDevice : data_.PCIDevices)
            {
                if (!PCIDevice->availableConfigs_.empty())
                {
                    consoleWriter_.listConfigs(PCIDevice->availableConfigs_,
                            PCIDevice->sysfsBusID_ + " (" + PCIDevice->classID_ + ":"
                                    + PCIDevice->vendorID_ + ":" + PCIDevice->deviceID_ + ") "
                                    + PCIDevice->className_ + " " + PCIDevice->vendorName_ + ":");
                }
            }
        }
    }

    if (arguments_.LIST_AVAILABLE && arguments_.SHOW_USB)
    {
        if (arguments_.DETAIL)
        {
            consoleWriter_.printAvailableConfigsInDetail("USB", data_.USBDevices);
        }

        else
        {
            for (auto&& USBdevice : data_.USBDevices)
            {
                if (!USBdevice->availableConfigs_.empty())
                {
                    consoleWriter_.listConfigs(USBdevice->availableConfigs_,
                            USBdevice->sysfsBusID_ + " (" + USBdevice->classID_ + ":"
                            + USBdevice->vendorID_ + ":" + USBdevice->deviceID_ + ") "
                            + USBdevice->className_ + " " + USBdevice->vendorName_ + ":");
                }
            }
        }
    }

    // List hardware information
    if (arguments_.LIST_HARDWARE && arguments_.SHOW_PCI)
    {
        if (arguments_.DETAIL)
        {
            consoleWriter_.printDeviceDetails(hw_pci);
        }
        else
        {
            consoleWriter_.listDevices(data_.PCIDevices, "PCI");
        }
    }
    if (arguments_.LIST_HARDWARE && arguments_.SHOW_USB)
    {
        if (arguments_.DETAIL)
        {
            consoleWriter_.printDeviceDetails(hw_usb);
        }
        else
        {
            consoleWriter_.listDevices(data_.USBDevices, "USB");
        }
    }

    // Auto configuration
    if (arguments_.AUTOCONFIGURE)
    {
        std::vector<std::shared_ptr<Device>> *devices;
        std::vector<std::shared_ptr<Config>> *installedConfigs;

        if ("USB" == operationType)
        {
            devices = &data_.USBDevices;
            installedConfigs = &data_.installedUSBConfigs;
        }
        else
        {
            devices = &data_.PCIDevices;
            installedConfigs = &data_.installedPCIConfigs;
        }
        bool foundDevice = false;
        for (auto&& device : *devices)
        {
            if (device->classID_ != autoConfigureClassID)
            {
                continue;
            }
            else
            {
                foundDevice = true;
                std::shared_ptr<Config> config;

                for (auto&& availableConfig : device->availableConfigs_)
                {
                    if (autoConfigureNonFreeDriver || availableConfig->freedriver_)
                    {
                        config = availableConfig;
                        break;
                    }
                }

                if (nullptr == config)
                {
                    consoleWriter_.printWarning(
                            "No config found for device: " + device->sysfsBusID_ + " ("
                                    + device->classID_ + ":" + device->vendorID_ + ":"
                                    + device->deviceID_ + ") " + device->className_ + " "
                                    + device->vendorName_ + " " + device->deviceName_);
                    continue;
                }
                else
                {
                    // If force is not set then skip found config
                    bool skip = false;
                    if (!arguments_.FORCE)
                    {
                        skip = std::find_if(installedConfigs->begin(), installedConfigs->end(),
                                [&config](const std::shared_ptr<Config>& conf) -> bool {
                                    return conf->name_ == config->name_;
                                }) != installedConfigs->end();
                    }
                    // Print found config
                    if (skip)
                    {
                        consoleWriter_.printStatus(
                                "Skipping already installed config '" + config->name_ +
                                "' for device: " + device->sysfsBusID_ + " (" +
                                device->classID_ + ":" + device->vendorID_ + ":" +
                                device->deviceID_ + ") " + device->className_ + " " +
                                device->vendorName_ + " " + device->deviceName_);
                    }
                    else
                    {
                        consoleWriter_.printStatus(
                                "Using config '" + config->name_ + "' for device: " +
                                device->sysfsBusID_ + " (" + device->classID_ + ":" +
                                device->vendorID_ + ":" + device->deviceID_ + ") " +
                                device->className_ + " " + device->vendorName_ + " " +
                                device->deviceName_);
                    }

                    bool alreadyInList = std::find(configs_.begin(), configs_.end(), config->name_) != configs_.end();
                    if (!alreadyInList && !skip)
                    {
                        configs_.push_back(config->name_);
                    }
                }
            }
        }

        if (!foundDevice)
        {
            consoleWriter_.printWarning("No device of class " + autoConfigureClassID + " found!");
        }
        else if (!configs_.empty())
        {
            arguments_.INSTALL = true;
        }
    }

    // Transaction
    if (arguments_.INSTALL || arguments_.REMOVE)
    {
        if (!isUserRoot())
        {
            consoleWriter_.printError("You cannot perform this operation unless you are root!");
        }
        else
        {
            for (auto&& configName = configs_.begin();
                    configName != configs_.end(); configName++)
            {
                if (arguments_.CUSTOM_INSTALL)
                {
                    // Custom install -> get configs
                    struct stat filestatus;
                    std::string filepath = (*configName) + "/MHWDCONFIG";

                    if (0 != stat(filepath.c_str(), &filestatus))
                    {
                        consoleWriter_.printError("custom config '" + filepath + "' does not exist!");
                        return 1;
                    }
                    else if (!S_ISREG(filestatus.st_mode))
                    {
                        consoleWriter_.printError("custom config '" + filepath + "' is invalid!");
                        return 1;
                    }
                    else
                    {
                        config_.reset(new Config(filepath, operationType));
                        if (!config_->readConfigFile(filepath))
                        {
                            consoleWriter_.printError("failed to read custom config '" + filepath + "'!");
                            return 1;
                        }

                        else if (!performTransaction(config_, MHWD::TRANSACTIONTYPE::INSTALL))
                        {
                            return 1;
                        }
                    }
                }
                else if (arguments_.INSTALL)
                {
                    config_ = getAvailableConfig((*configName), operationType);
                    if (config_ == nullptr)
                    {
                        config_ = getDatabaseConfig((*configName), operationType);
                        if (config_ == nullptr)
                        {
                            consoleWriter_.printError("config '" + (*configName) + "' does not exist!");
                            return 1;
                        }
                        else
                        {
                            consoleWriter_.printWarning(
                                    "no matching device for config '" + (*configName) + "' found!");
                        }
                    }

                    if (!performTransaction(config_, MHWD::TRANSACTIONTYPE::INSTALL))
                    {
                        return 1;
                    }
                }
                else if (arguments_.REMOVE)
                {
                    config_ = getInstalledConfig((*configName), operationType);

                    if (nullptr == config_)
                    {
                        consoleWriter_.printError("config '" + (*configName) + "' is not installed!");
                        return 1;
                    }

                    else if (!performTransaction(config_, MHWD::TRANSACTIONTYPE::REMOVE))
                    {
                        return 1;
                    }
                }
            }
        }
    }
    return 0;
}
Beispiel #4
0
MHWD::STATUS Mhwd::performTransaction(const Transaction& transaction)
{
    if ((MHWD::TRANSACTIONTYPE::INSTALL == transaction.type_) &&
            !transaction.conflictedConfigs_.empty())
    {
        return MHWD::STATUS::ERROR_CONFLICTS;
    }
    else if ((MHWD::TRANSACTIONTYPE::REMOVE == transaction.type_)
            && !transaction.configsRequirements_.empty())
    {
        return MHWD::STATUS::ERROR_REQUIREMENTS;
    }
    else
    {
        // Check if already installed
        std::shared_ptr<Config> installedConfig{getInstalledConfig(transaction.config_->name_,
                transaction.config_->type_)};
        MHWD::STATUS status = MHWD::STATUS::SUCCESS;

        if ((MHWD::TRANSACTIONTYPE::REMOVE == transaction.type_)
                || (installedConfig != nullptr && transaction.isAllowedToReinstall()))
        {
            if (nullptr == installedConfig)
            {
                return MHWD::STATUS::ERROR_NOT_INSTALLED;
            }
            else
            {
                consoleWriter_.printMessage(MHWD::MESSAGETYPE::REMOVE_START, installedConfig->name_);
                if (MHWD::STATUS::SUCCESS != (status = uninstallConfig(installedConfig.get())))
                {
                    return status;
                }
                else
                {
                    consoleWriter_.printMessage(MHWD::MESSAGETYPE::REMOVE_END, installedConfig->name_);
                }
            }
        }

        if (MHWD::TRANSACTIONTYPE::INSTALL == transaction.type_)
        {
            // Check if already installed but not allowed to reinstall
            if ((nullptr != installedConfig) && !transaction.isAllowedToReinstall())
            {
                return MHWD::STATUS::ERROR_ALREADY_INSTALLED;
            }
            else
            {
                // Install all dependencies first
                for (auto&& dependencyConfig = transaction.dependencyConfigs_.end() - 1;
                        dependencyConfig != transaction.dependencyConfigs_.begin() - 1;
                        --dependencyConfig)
                {
                    consoleWriter_.printMessage(MHWD::MESSAGETYPE::INSTALLDEPENDENCY_START,
                            (*dependencyConfig)->name_);
                    if (MHWD::STATUS::SUCCESS != (status = installConfig((*dependencyConfig))))
                    {
                        return status;
                    }
                    else
                    {
                        consoleWriter_.printMessage(MHWD::MESSAGETYPE::INSTALLDEPENDENCY_END,
                                (*dependencyConfig)->name_);
                    }
                }

                consoleWriter_.printMessage(MHWD::MESSAGETYPE::INSTALL_START, transaction.config_->name_);
                if (MHWD::STATUS::SUCCESS != (status = installConfig(transaction.config_)))
                {
                    return status;
                }
                else
                {
                    consoleWriter_.printMessage(MHWD::MESSAGETYPE::INSTALL_END,
                            transaction.config_->name_);
                }
            }
        }
        return status;
    }
}