/*************************************************************************** * This file is part of netctl-gui * * * * netctl-gui is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * * * netctl-gui is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with netctl-gui. If not, see http://www.gnu.org/licenses/ * ***************************************************************************/ /** * @file netctlinteract.cpp * Source code of netctlgui library * @author Evgeniy Alekseev * @copyright GPLv3 * @bug https://github.com/arcan1s/netctl-gui/issues */ #include #include #include #include /** * @class Netctl */ /** * @fn Netctl */ Netctl::Netctl(const bool debugCmd, const QMap settings) : debug(debugCmd) { if (settings.contains(QString("IFACE_DIR"))) ifaceDirectory = new QDir(settings[QString("IFACE_DIR")]); else ifaceDirectory = new QDir(QString("/sys/class/net/")); if (settings.contains(QString("PREFERED_IFACE"))) mainInterface = settings[QString("PREFERED_IFACE")]; else mainInterface = QString(""); if (settings.contains(QString("NETCTL_PATH"))) netctlCommand = settings[QString("NETCTL_PATH")]; else netctlCommand = QString("/usr/bin/netctl"); if (settings.contains(QString("NETCTLAUTO_PATH"))) netctlAutoCommand = settings[QString("NETCTLAUTO_PATH")]; else netctlAutoCommand = QString("/usr/bin/netctl-auto"); if (settings.contains(QString("NETCTLAUTO_SERVICE"))) netctlAutoService = settings[QString("NETCTLAUTO_SERVICE")]; else netctlAutoService = QString("netctl-auto"); if (settings.contains(QString("PROFILE_DIR"))) profileDirectory = new QDir(settings[QString("PROFILE_DIR")]); else profileDirectory = new QDir(QString("/etc/netctl/")); if (settings.contains(QString("SUDO_PATH"))) sudoCommand = settings[QString("SUDO_PATH")]; else sudoCommand = QString("/usr/bin/kdesu"); if (settings.contains(QString("SYSTEMCTL_PATH"))) systemctlCommand = settings[QString("SYSTEMCTL_PATH")]; else systemctlCommand = QString("/usr/bin/systemctl"); } /** * @fn ~Netctl */ Netctl::~Netctl() { if (debug) qDebug() << "[Netctl]" << "[~Netctl]"; if (ifaceDirectory != 0) delete ifaceDirectory; if (profileDirectory != 0) delete profileDirectory; } // functions /** * @fn getNetctlOutput */ QString Netctl::getNetctlOutput(const bool sudo, const QString commandLine, const QString profile) { if (debug) qDebug() << "[Netctl]" << "[getNetctlOutput]"; if (debug) qDebug() << "[Netctl]" << "[getNetctlOutput]" << ":" << "Command" << commandLine; if (debug) qDebug() << "[Netctl]" << "[getNetctlOutput]" << ":" << "Profile" << profile; if (netctlCommand == 0) { if (debug) qDebug() << "[Netctl]" << "[getNetctlOutput]" << ":" << "Could not find netctl"; return QString(); } if ((sudo) && (sudoCommand == 0)) { if (debug) qDebug() << "[Netctl]" << "[getNetctlOutput]" << ":" << "Could not find sudo"; return QString(); } QProcess command; QString commandText; if (sudo) commandText = sudoCommand + QString(" ") + netctlCommand + QString(" ") + commandLine + QString(" ") + profile; else commandText = netctlCommand + QString(" ") + commandLine + QString(" ") + profile; if (debug) qDebug() << "[Netctl]" << "[getNetctlOutput]" << ":" << "Run cmd" << commandText; command.start(commandText); command.waitForFinished(-1); return command.readAllStandardOutput(); } /** * @fn getWifiInterface */ QString Netctl::getWifiInterface() { if (debug) qDebug() << "[Netctl]" << "[getWifiInterface]"; if (ifaceDirectory == 0) { if (debug) qDebug() << "[Netctl]" << "[getWifiInterface]" << ":" << "Could not find directory"; return QString(); } QStringList interfaces; if (!mainInterface.isEmpty()) interfaces.append(mainInterface); QStringList allInterfaces = ifaceDirectory->entryList(QDir::Dirs | QDir::NoDotAndDotDot); for (int i=0; ipath() + QDir::separator() + allInterfaces[i] + QDir::separator() + QString("wireless"); if (QDir(ifaceDirectory->path() + QDir::separator() + allInterfaces[i] + QDir::separator() + QString("wireless")).exists()) interfaces.append(allInterfaces[i]); } if (interfaces.isEmpty()) return QString(""); else return interfaces[0]; } /** * @fn netctlCall */ bool Netctl::netctlCall(const bool sudo, const QString commandLine, const QString profile) { if (debug) qDebug() << "[Netctl]" << "[netctlCall]"; if (debug) qDebug() << "[Netctl]" << "[netctlCall]" << ":" << "Command" << commandLine; if (debug) qDebug() << "[Netctl]" << "[netctlCall]" << ":" << "Profile" << profile; if (netctlCommand == 0) { if (debug) qDebug() << "[Netctl]" << "[netctlCall]" << ":" << "Could not find netctl"; return false; } if ((sudo) && (sudoCommand == 0)) { if (debug) qDebug() << "[Netctl]" << "[netctlCall]" << ":" << "Could not find sudo"; return false; } QProcess command; QString commandText; if (sudo) commandText = sudoCommand + QString(" ") + netctlCommand + QString(" ") + commandLine + QString(" ") + profile; else commandText = netctlCommand + QString(" ") + commandLine + QString(" ") + profile; if (debug) qDebug() << "[Netctl]" << "[netctlCall]" << ":" << "Run cmd" << commandText; command.start(commandText); command.waitForFinished(-1); if (debug) qDebug() << "[Netctl]" << "[netctlCall]" << ":" << "Cmd returns" << command.exitCode(); if (command.exitCode() == 0) return true; else return false; } /** * @fn netctlAutoCall */ bool Netctl::netctlAutoCall(const bool sudo, const QString commandLine, const QString profile) { if (debug) qDebug() << "[Netctl]" << "[netctlAutoCall]"; if (debug) qDebug() << "[Netctl]" << "[netctlAutoCall]" << ":" << "Command" << commandLine; if (debug) qDebug() << "[Netctl]" << "[netctlAutoCall]" << ":" << "Profile" << profile; if (netctlAutoCommand == 0) { if (debug) qDebug() << "[Netctl]" << "[netctlAutoCall]" << ":" << "Could not find netctl-auto"; return false; } if ((sudo) && (sudoCommand == 0)) { if (debug) qDebug() << "[Netctl]" << "[netctlAutoCall]" << ":" << "Could not find sudo"; return false; } QProcess command; QString commandText; if (sudo) commandText = sudoCommand + QString(" ") + netctlAutoCommand + QString(" ") + commandLine; else commandText = netctlAutoCommand + QString(" ") + commandLine; if (profile != 0) commandText = commandText + QString(" ") + profile; if (debug) qDebug() << "[Netctl]" << "[netctlAutoCall]" << ":" << "Run cmd" << commandText; command.start(commandText); command.waitForFinished(-1); if (debug) qDebug() << "[Netctl]" << "[netctlAutoCall]" << ":" << "Cmd returns" << command.exitCode(); if (command.exitCode() == 0) return true; else return false; } /** * @fn systemctlCall */ bool Netctl::systemctlCall(const bool sudo, const QString commandLine) { if (debug) qDebug() << "[Netctl]" << "[systemctlCall]"; if (debug) qDebug() << "[Netctl]" << "[systemctlCall]" << ":" << "Command" << commandLine; if (netctlAutoService == 0) { if (debug) qDebug() << "[Netctl]" << "[systemctlCall]" << ":" << "Could not find service"; return false; } if ((sudo) && (sudoCommand == 0)) { if (debug) qDebug() << "[Netctl]" << "[systemctlCall]" << ":" << "Could not find sudo"; return false; } if (systemctlCommand == 0) { if (debug) qDebug() << "[Netctl]" << "[systemctlCall]" << ":" << "Could not find systemctl"; return false; } QProcess command; QString commandText; QString interface = getWifiInterface(); if (interface.isEmpty()) return false; if (sudo) commandText = sudoCommand + QString(" ") + systemctlCommand + QString(" ") + commandLine + QString(" ") + netctlAutoService + QString("@") + interface + QString(".service"); else commandText = systemctlCommand + QString(" ") + commandLine + QString(" ") + netctlAutoService + QString("@") + interface + QString(".service"); if (debug) qDebug() << "[Netctl]" << "[systemctlCall]" << ":" << "Run cmd" << commandText; command.start(commandText); command.waitForFinished(-1); if (debug) qDebug() << "[Netctl]" << "[systemctlCall]" << ":" << "Cmd returns" << command.exitCode(); if (command.exitCode() == 0) return true; else return false; } // general information /** * @fn getProfileList */ QList Netctl::getProfileList() { if (debug) qDebug() << "[Netctl]" << "[getProfileList]"; if (profileDirectory == 0) { if (debug) qDebug() << "[Netctl]" << "[getProfileList]" << ":" << "Could not find directory"; return QList(); } QList fullProfilesInfo; QStringList profiles = profileDirectory->entryList(QDir::Files); QStringList descriptions = getProfileDescriptions(profiles); QStringList statuses = getProfileStatuses(profiles); for (int i=0; i Netctl::getProfileListFromNetctlAuto() { if (debug) qDebug() << "[Netctl]" << "[getProfileListFromNetctlAuto]"; if (netctlAutoCommand == 0) { if (debug) qDebug() << "[Netctl]" << "[getProfileListFromNetctlAuto]" << ":" << "Could not find netctl-auto"; return QList(); } QProcess command; QString commandText = netctlAutoCommand + QString(" list"); if (debug) qDebug() << "[Netctl]" << "[getProfileListFromNetctlAuto]" << ":" << "Run cmd" << commandText; command.start(commandText); command.waitForFinished(-1); QStringList output = QString(command.readAllStandardOutput()).split(QChar('\n'), QString::SkipEmptyParts); QList fullProfilesInfo; for (int i=0; i"); QString profileUrl = profileDirectory->absolutePath() + QDir::separator() + profile; if (debug) qDebug() << "[Netctl]" << "[getProfileDescription]" << ":" << "Check" << profileUrl; QFile profileFile(profileUrl); QString fileStr; if (!profileFile.open(QIODevice::ReadOnly)) return description; while (true) { fileStr = QString(profileFile.readLine()); if (fileStr.isEmpty()) continue; if (fileStr[0] == QChar('#')) continue; if (fileStr.split(QChar('='), QString::SkipEmptyParts).count() == 2) if (fileStr.split(QChar('='), QString::SkipEmptyParts)[0] == QString("Description")) description = fileStr.split(QChar('='), QString::SkipEmptyParts)[1].trimmed(); if (profileFile.atEnd()) break; } profileFile.close(); description.remove(QChar('\'')).remove(QChar('"')); return description; } /** * @fn getProfileDescriptions */ QStringList Netctl::getProfileDescriptions(const QStringList profileList) { if (debug) qDebug() << "[Netctl]" << "[getProfileDescriptions]"; if (debug) qDebug() << "[Netctl]" << "[getProfileDescriptions]" << ":" << "Profile list" << profileList; if (profileDirectory == 0) { if (debug) qDebug() << "[Netctl]" << "[getProfileDescriptions]" << ":" << "Could not find directory"; return QStringList(); } QStringList descriptions; for (int i=0; i"); QString profileUrl = profileDirectory->absolutePath() + QDir::separator() + profileList[i]; if (debug) qDebug() << "[Netctl]" << "[getProfileDescriptions]" << ":" << "Check" << profileUrl; QFile profileFile(profileUrl); QString fileStr; if (!profileFile.open(QIODevice::ReadOnly)) { descriptions.append(description); continue; } while (true) { fileStr = QString(profileFile.readLine()); if (fileStr[0] == QChar('#')) continue; if (fileStr.split(QChar('='), QString::SkipEmptyParts).count() == 2) if (fileStr.split(QChar('='), QString::SkipEmptyParts)[0] == QString("Description")) description = fileStr.split(QChar('='), QString::SkipEmptyParts)[1].trimmed(); if (profileFile.atEnd()) break; } profileFile.close(); description.remove(QChar('\'')).remove(QChar('"')); descriptions.append(description); } return descriptions; } /** * @fn getProfileStatus */ QString Netctl::getProfileStatus(const QString profile) { if (debug) qDebug() << "[Netctl]" << "[getProfileStatus]"; if (debug) qDebug() << "[Netctl]" << "[getProfileStatus]" << ":" << "Profile" << profile; QString status; if (isProfileActive(profile)) status = QString("active"); else status = QString("inactive"); if (isProfileEnabled(profile)) status = status + QString(" (enabled)"); else status = status + QString(" (static)"); return status; } /** * @fn getProfileStatuses */ QStringList Netctl::getProfileStatuses(const QStringList profileList) { if (debug) qDebug() << "[Netctl]" << "[getProfileStatuses]"; if (debug) qDebug() << "[Netctl]" << "[getProfileStatuses]" << ":" << "Profile list" << profileList; QStringList statuses; for (int i=0; iabsolutePath() + QDir::separator() + profile; if (debug) qDebug() << "[Netctl]" << "[getSsidFromProfile]" << ":" << "Check" << profileUrl; QFile profileFile(profileUrl); QString fileStr; if (!profileFile.open(QIODevice::ReadOnly)) return ssidName; while (true) { fileStr = QString(profileFile.readLine()); if (fileStr.isEmpty()) continue; if (fileStr[0] == QChar('#')) continue; if (fileStr.split(QChar('='), QString::SkipEmptyParts).count() == 2) if (fileStr.split(QChar('='), QString::SkipEmptyParts)[0] == QString("ESSID")) ssidName = fileStr.split(QChar('='), QString::SkipEmptyParts)[1].trimmed(); if (profileFile.atEnd()) break; } profileFile.close(); ssidName.remove(QChar('\'')).remove(QChar('"')); return ssidName; } /** * @fn isProfileActive */ bool Netctl::isProfileActive(const QString profile) { if (debug) qDebug() << "[Netctl]" << "[isProfileActive]"; if (debug) qDebug() << "[Netctl]" << "[isProfileActive]" << ":" << "Profile" << profile; bool status = false; QString cmdOutput = getNetctlOutput(false, QString("status"), profile); if (cmdOutput.contains(QString("Active: active"))) status = true; return status; } /** * @fn isProfileEnabled */ bool Netctl::isProfileEnabled(const QString profile) { if (debug) qDebug() << "[Netctl]" << "[isProfileEnabled]"; if (debug) qDebug() << "[Netctl]" << "[isProfileEnabled]" << ":" << "Profile" << profile; return netctlCall(false, QString("is-enabled"), profile); } /** * @fn autoIsProfileActive */ bool Netctl::autoIsProfileActive(const QString profile) { if (debug) qDebug() << "[Netctl]" << "[autoIsProfileActive]"; if (debug) qDebug() << "[Netctl]" << "[autoIsProfileActive]" << ":" << "Profile" << profile; bool status = false; QList profiles = getProfileListFromNetctlAuto(); for (int i=0; i profiles = getProfileListFromNetctlAuto(); for (int i=0; i