detached backend from frontend

This commit is contained in:
arcan1s
2014-07-11 09:56:48 +04:00
parent eccb6b6578
commit 9852fb8f68
20 changed files with 637 additions and 132 deletions

View File

@ -0,0 +1,13 @@
# set project name
set (SUBPROJECT ${PROJECT_LIBRARY})
message (STATUS "Subproject ${SUBPROJECT}")
# set directories
set (SUBPROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set (SUBPROJECT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
# additional targets
set (TARGETS "")
set (HEADERS "")
add_subdirectory (${SUBPROJECT_SOURCE_DIR})

View File

@ -0,0 +1,59 @@
/***************************************************************************
* 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/ *
***************************************************************************/
#ifndef NETCTLINTERACT_H
#define NETCTLINTERACT_H
#include <QDir>
#include <QMap>
#include <QObject>
class Netctl : public QObject
{
Q_OBJECT
public:
explicit Netctl(const bool debugCmd = false,
const QMap<QString, QString> settings = QMap<QString, QString>());
~Netctl();
// general information
QList<QStringList> getProfileList();
QStringList getProfileDescriptions(const QStringList profileList);
QStringList getProfileStatuses(const QStringList profileList);
QString getSsidFromProfile(const QString profile);
bool isProfileActive(const QString profile);
bool isProfileEnabled(const QString profile);
public slots:
// functions
bool enableProfile(const QString profile);
bool restartProfile(const QString profile);
bool startProfile(const QString profile);
private:
bool debug;
QString netctlCommand;
QDir *profileDirectory;
QString sudoCommand;
// functions
QString getNetctlOutput(const bool sudo, const QString commandLine, const QString profile);
bool netctlCall(const bool sudo, const QString commandLine, const QString profile);
};
#endif /* NETCTLINTERACT_H */

View File

@ -0,0 +1,47 @@
/***************************************************************************
* 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/ *
***************************************************************************/
#ifndef NETCTLPROFILE_H
#define NETCTLPROFILE_H
#include <QDir>
#include <QMap>
#include <QObject>
class NetctlProfile : public QObject
{
Q_OBJECT
public:
explicit NetctlProfile(const bool debugCmd = false,
const QMap<QString, QString> settings = QMap<QString, QString>());
~NetctlProfile();
bool copyProfile(const QString oldPath);
bool removeProfile(const QString profile);
QString createProfile(const QString profile, const QMap<QString, QString> settings);
QString getNameByString(const QString profile);
QMap<QString, QString> getSettingsFromProfile(const QString profile);
private:
bool debug;
QDir *profileDirectory;
QString sudoCommand;
};
#endif /* NETCTLPROFILE_H */

View File

@ -0,0 +1,46 @@
/***************************************************************************
* 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/ *
***************************************************************************/
#ifndef SLEEPTHREAD_H
#define SLEEPTHREAD_H
#include <QThread>
class SleepThread : public QThread
{
Q_OBJECT
public:
static void usleep(long iSleepTime)
{
QThread::usleep(iSleepTime);
}
static void sleep(long iSleepTime)
{
QThread::sleep(iSleepTime);
}
static void msleep(long iSleepTime)
{
QThread::msleep(iSleepTime);
}
};
#endif /* SLEEPTHREAD_H */

View File

@ -0,0 +1,66 @@
/***************************************************************************
* 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/ *
***************************************************************************/
#ifndef WPASUPINTERACT_H
#define WPASUPINTERACT_H
#include <QDir>
#include <QMap>
#include <QObject>
class Netctl;
class WpaSup : public QObject
{
Q_OBJECT
public:
explicit WpaSup(const bool debugCmd = false,
const QMap<QString, QString> settings = QMap<QString, QString>());
~WpaSup();
// general information
QString existentProfile(const QString profile);
QStringList getInterfaceList();
bool isProfileActive(const QString profile);
bool isProfileExists(const QString profile);
public slots:
// functions
QList<QStringList> scanWifi();
bool startWpaSupplicant();
bool stopWpaSupplicant();
private:
Netctl *netctlCommand;
bool debug;
QString ctrlDir;
QString ctrlGroup;
QDir *ifaceDirectory;
QString mainInterface;
QString pidFile;
QString sudoCommand;
QString wpaCliPath;
QString wpaDrivers;
QString wpaSupPath;
// functions
bool wpaCliCall(const QString commandLine);
QString getWpaCliOutput(const QString commandLine);
};
#endif /* WPASUPINTERACT_H */

View File

@ -0,0 +1,46 @@
# set files
file (GLOB SOURCES *.cpp)
file (GLOB HEADERS ${SUBPROJECT_INCLUDE_DIR}/${SUBPROJECT}/*.h)
message (STATUS "${SUBPROJECT} Sources: ${SOURCES}")
message (STATUS "${SUBPROJECT} Headers: ${HEADERS}")
# include_path
include_directories (${SUBPROJECT_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}/../
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR})
if (USE_QT5)
find_package(Qt5Core REQUIRED)
find_package(Qt5Widgets REQUIRED)
add_definitions(${Qt5Core_DEFINITIONS})
add_definitions(${Qt5Widgets_DEFINITIONS})
qt5_wrap_cpp (MOC_SOURCES ${HEADERS})
source_group ("Header Files" FILES ${HEADERS})
source_group ("Source Files" FILES ${SOURCES})
source_group ("Generated Files" FILES ${MOC_SOURCES})
include_directories (${Qt5Core_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS})
add_library (${SUBPROJECT} SHARED ${SOURCES} ${HEADERS} ${MOC_SOURCES})
set_target_properties (${SUBPROJECT} PROPERTIES SOVERSION ${PROJECT_VERSION})
target_link_libraries (${SUBPROJECT} ${Qt5Widgets_LIBRARIES} ${Qt5Core_LIBRARIES})
else ()
find_package (Qt4 REQUIRED)
include (${QT_USE_FILE})
qt4_wrap_cpp (MOC_SOURCES ${HEADERS})
source_group ("Header Files" FILES ${HEADERS})
source_group ("Source Files" FILES ${SOURCES})
source_group ("Generated Files" FILES ${MOC_SOURCES})
add_library (${SUBPROJECT} SHARED ${SOURCES} ${HEADERS} ${MOC_SOURCES})
set_target_properties (${SUBPROJECT} PROPERTIES SOVERSION ${PROJECT_VERSION})
target_link_libraries (${SUBPROJECT} ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY})
endif()
# install properties
install (TARGETS ${SUBPROJECT} DESTINATION lib)
install (DIRECTORY ${SUBPROJECT_INCLUDE_DIR}/ DESTINATION include/)

View File

@ -0,0 +1,28 @@
/***************************************************************************
* 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/ *
***************************************************************************/
#include <netctlgui/netctlinteract.h>
#include <netctlgui/netctlprofile.h>
#include <netctlgui/sleepthread.h>
#include <netctlgui/wpasupinteract.h>
int main(int argc, char *argv[])
{
return 0;
}

View File

@ -0,0 +1,244 @@
/***************************************************************************
* 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/ *
***************************************************************************/
#include <QDebug>
#include <QFile>
#include <QProcess>
#include <netctlgui/netctlinteract.h>
Netctl::Netctl(const bool debugCmd, const QMap<QString, QString> settings)
: debug(debugCmd)
{
netctlCommand = settings[QString("NETCTL_PATH")];
profileDirectory = new QDir(settings[QString("PROFILE_DIR")]);
sudoCommand = settings[QString("SUDO_PATH")];
}
Netctl::~Netctl()
{
if (debug) qDebug() << "[Netctl]" << "[~Netctl]";
delete profileDirectory;
}
// functions
QString Netctl::getNetctlOutput(const bool sudo, const QString commandLine, const QString profile)
{
if (debug) qDebug() << "[Netctl]" << "[getNetctlOutput]";
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();
}
bool Netctl::netctlCall(const bool sudo, const QString commandLine, const QString profile)
{
if (debug) qDebug() << "[Netctl]" << "[netctlCall]";
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;
}
// general information
QList<QStringList> Netctl::getProfileList()
{
if (debug) qDebug() << "[Netctl]" << "[getProfileList]";
QList<QStringList> fullProfilesInfo;
QStringList profiles = profileDirectory->entryList(QDir::Files);
QStringList descriptions = getProfileDescriptions(profiles);
QStringList statuses = getProfileStatuses(profiles);
for (int i=0; i<profiles.count(); i++) {
QStringList profileInfo;
profileInfo.append(profiles[i]);
profileInfo.append(descriptions[i]);
profileInfo.append(statuses[i]);
fullProfilesInfo.append(profileInfo);
}
return fullProfilesInfo;
}
QStringList Netctl::getProfileDescriptions(const QStringList profileList)
{
if (debug) qDebug() << "[Netctl]" << "[getProfileDescription]";
QStringList descriptions;
for (int i=0; i<profileList.count(); i++) {
QString profileUrl = profileDirectory->absolutePath() + QDir::separator() + profileList[i];
if (debug) qDebug() << "[Netctl]" << "[getProfileDescriptions]" << ":" << "Check" << profileUrl;
QFile profile(profileUrl);
QString fileStr;
if (profile.open(QIODevice::ReadOnly))
while (true) {
fileStr = QString(profile.readLine());
if (fileStr[0] != '#')
if (fileStr.split(QString("="), QString::SkipEmptyParts).count() == 2)
if (fileStr.split(QString("="), QString::SkipEmptyParts)[0] == QString("Description"))
descriptions.append(fileStr.split(QString("="), QString::SkipEmptyParts)[1].trimmed());
if (profile.atEnd())
break;
}
else
descriptions.append(QString("<unknown>"));
}
for (int i=0; i<profileList.count(); i++) {
descriptions[i].remove(QChar('\''));
descriptions[i].remove(QChar('"'));
}
return descriptions;
}
QStringList Netctl::getProfileStatuses(const QStringList profileList)
{
if (debug) qDebug() << "[Netctl]" << "[getProfileStatuses]";
QStringList statuses;
for (int i=0; i<profileList.count(); i++) {
QString status;
if (isProfileActive(profileList[i]))
status = QString("active");
else
status = QString("inactive");
if (isProfileEnabled(profileList[i]))
status = status + QString(" (enabled)");
else
status = status + QString(" (static)");
statuses.append(status);
}
return statuses;
}
QString Netctl::getSsidFromProfile(const QString profile)
{
if (debug) qDebug() << "[Netctl]" << "[getSsidFromProfile]";
QString ssidName = QString("");
QString profileUrl = profileDirectory->absolutePath() + 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[0] != '#') {
if (fileStr.split(QString("="), QString::SkipEmptyParts).count() == 2)
if (fileStr.split(QString("="), QString::SkipEmptyParts)[0] == QString("ESSID"))
ssidName = fileStr.split(QString("="), QString::SkipEmptyParts)[1].trimmed();
}
if (profileFile.atEnd())
break;
}
profileFile.close();
ssidName.remove(QChar('\''));
ssidName.remove(QChar('"'));
return ssidName;
}
bool Netctl::isProfileActive(const QString profile)
{
if (debug) qDebug() << "[Netctl]" << "[isProfileActive]";
bool status = false;
QString cmdOutput = getNetctlOutput(false, QString("status"), profile);
if (!cmdOutput.isEmpty())
if (cmdOutput.contains(QString("Active: active")))
status = true;
return status;
}
bool Netctl::isProfileEnabled(const QString profile)
{
if (debug) qDebug() << "[Netctl]" << "[isProfileEnabled]";
return netctlCall(false, QString("is-enabled"), profile);
}
// functions
bool Netctl::enableProfile(const QString profile)
{
if (debug) qDebug() << "[Netctl]" << "[enableProfile]";
if (isProfileEnabled(profile))
return netctlCall(true, QString("disable"), profile);
else
return netctlCall(true, QString("enable"), profile);
}
bool Netctl::restartProfile(const QString profile)
{
if (debug) qDebug() << "[Netctl]" << "[restartProfile]";
return netctlCall(true, QString("restart"), profile);
}
bool Netctl::startProfile(const QString profile)
{
if (debug) qDebug() << "[Netctl]" << "[startProfile]";
if (isProfileActive(profile))
return netctlCall(true, QString("stop"), profile);
else
return netctlCall(true, QString("start"), profile);
}

View File

@ -0,0 +1,189 @@
/***************************************************************************
* 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/ *
***************************************************************************/
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QProcess>
#include <QTextStream>
#include <netctlgui/netctlprofile.h>
NetctlProfile::NetctlProfile(const bool debugCmd, const QMap<QString, QString> settings)
: debug(debugCmd)
{
profileDirectory = new QDir(settings[QString("PROFILE_DIR")]);
sudoCommand = settings[QString("SUDO_PATH")];
}
NetctlProfile::~NetctlProfile()
{
if (debug) qDebug() << "[NetctlProfile]" << "[~NetctlProfile]";
delete profileDirectory;
}
bool NetctlProfile::copyProfile(const QString oldPath)
{
if (debug) qDebug() << "[NetctlProfile]" << "[copyProfile]";
QString newPath = profileDirectory->absolutePath() + QDir::separator() + QFileInfo(oldPath).fileName();
QProcess command;
QString commandText = sudoCommand + QString(" /usr/bin/mv ") + oldPath + QString(" ") + newPath;
if (debug) qDebug() << "[NetctlProfile]" << "[copyProfile]" << ":" << "Run cmd" << commandText;
command.start(commandText);
command.waitForFinished(-1);
if (command.exitCode() == 0)
return true;
else
return false;
}
bool NetctlProfile::removeProfile(const QString profile)
{
if (debug) qDebug() << "[NetctlProfile]" << "[removeProfile]";
QString profilePath = profileDirectory->absolutePath() + QDir::separator() + QFileInfo(profile).fileName();
QProcess command;
QString commandText = sudoCommand + QString(" /usr/bin/rm ") + profilePath;
if (debug) qDebug() << "[NetctlProfile]" << "[removeProfile]" << ":" << "Run cmd" << commandText;
command.start(commandText);
command.waitForFinished(-1);
if (command.exitCode() == 0)
return true;
else
return false;
}
QString NetctlProfile::createProfile(const QString profile, const QMap<QString, QString> settings)
{
if (debug) qDebug() << "[NetctlProfile]" << "[createProfile]";
if (debug) qDebug() << "[NetctlProfile]" << "[createProfile]" << ":" << "Profile name" << profile;
QString profileTempName = QDir::homePath() + QDir::separator() +
QString(".cache") + QDir::separator() + QFileInfo(profile).fileName();
QFile profileFile(profileTempName);
if (debug) qDebug() << "[NetctlProfile]" << "[createProfile]" << ":" << "Save to" << profileTempName;
if (!profileFile.open(QIODevice::WriteOnly | QIODevice::Text))
return profileTempName;
QTextStream out(&profileFile);
for (int i=0; i<settings.keys().count(); i++) {
out << settings.keys()[i] << QString("=");
if ((settings.keys()[i] == QString("BindsToInterfaces")) ||
(settings.keys()[i] == QString("After")) ||
(settings.keys()[i] == QString("Address")) ||
(settings.keys()[i] == QString("Routes")) ||
(settings.keys()[i] == QString("Address6")) ||
(settings.keys()[i] == QString("Routes6")) ||
(settings.keys()[i] == QString("IPCustom")) ||
(settings.keys()[i] == QString("DNS")) ||
(settings.keys()[i] == QString("DNSOptions")) ||
(settings.keys()[i] == QString("WPAConfigSection")) ||
(settings.keys()[i] == QString("WPAConfigSection")))
out << QString("(") + settings[settings.keys()[i]] << QString(")\n");
else
out << settings[settings.keys()[i]] << QString("\n");
}
profileFile.close();
return profileTempName;
}
QString NetctlProfile::getNameByString(const QString profile)
{
if (debug) qDebug() << "[NetctlProfile]" << "[getNameByString]";
if (debug) qDebug() << "[NetctlProfile]" << "[getNameByString]" << ":" << "Raw string" << profile;
return QFileInfo(profile).fileName();
}
QMap<QString, QString> NetctlProfile::getSettingsFromProfile(const QString profile)
{
if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]";
QMap<QString, QString> settings;
QString fileStr, profileUrl;
profileUrl = profileDirectory->absolutePath() + QDir::separator() + QFileInfo(profile).fileName();
QFile profileFile(profileUrl);
if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]" << ":" << "Read from" << profileUrl;
if (!profileFile.open(QIODevice::ReadOnly))
return settings;
while (true) {
fileStr = QString(profileFile.readLine());
if (fileStr[0] != '#') {
if (fileStr.split(QString("="), QString::SkipEmptyParts).count() == 2) {
if ((fileStr.split(QString("="))[1][0] == QChar('(')) &&
(fileStr.split(QString("="))[1][fileStr.split(QString("="))[1].size()-2] == QChar(')')))
settings[fileStr.split(QString("="))[0]] = fileStr.split(QString("="))[1]
.remove(QString("("))
.remove(QString(")"))
.trimmed();
else if (fileStr.split(QString("="))[1][0] == QChar('(')) {
QString parameterName = fileStr.split(QString("="))[0];
QStringList parameter;
if (!fileStr.split(QString("="))[1]
.remove(QString("("))
.remove(QString(")"))
.trimmed()
.isEmpty())
parameter.append(fileStr.split(QString("="))[1]
.remove(QString("("))
.remove(QString(")"))
.trimmed());
while(true) {
fileStr = QString(profileFile.readLine());
if (fileStr[fileStr.size()-2] == QChar(')'))
break;
if (!fileStr.remove(QString("("))
.remove(QString(")"))
.trimmed()
.isEmpty())
parameter.append(fileStr.remove(QString("("))
.remove(QString(")"))
.trimmed());
if (profileFile.atEnd())
break;
}
settings[parameterName] = parameter.join(QString("\n"));
}
else
settings[fileStr.split(QString("="))[0]] = fileStr.split(QString("="))[1]
.trimmed();
}
}
if (profileFile.atEnd())
break;
}
profileFile.close();
return settings;
}

View File

@ -0,0 +1,257 @@
/***************************************************************************
* 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/ *
***************************************************************************/
#include <QDebug>
#include <QProcess>
#include <netctlgui/netctlinteract.h>
#include <netctlgui/sleepthread.h>
#include <netctlgui/wpasupinteract.h>
WpaSup::WpaSup(const bool debugCmd, const QMap<QString, QString> settings)
: debug(debugCmd)
{
netctlCommand = new Netctl(debug, settings);
ctrlDir = settings[QString("CTRL_DIR")];
ctrlGroup = settings[QString("CTRL_GROUP")];
ifaceDirectory = new QDir(settings[QString("IFACE_DIR")]);
mainInterface = settings[QString("PREFERED_IFACE")];
pidFile = settings[QString("PID_FILE")];
sudoCommand = settings[QString("SUDO_PATH")];
wpaCliPath = settings[QString("WPACLI_PATH")];
wpaDrivers = settings[QString("WPA_DRIVERS")];
wpaSupPath = settings[QString("WPASUP_PATH")];
// terminate old loaded profile
if (QFile(pidFile).exists() || QDir(ctrlDir).exists())
stopWpaSupplicant();
}
WpaSup::~WpaSup()
{
if (debug) qDebug() << "[WpaSup]" << "[~WpaSup]";
delete netctlCommand;
delete ifaceDirectory;
}
// general information
QString WpaSup::existentProfile(const QString profile)
{
if (debug) qDebug() << "[WpaSup]" << "[existentProfile]";
QString profileFile = QString("");
QList<QStringList> profileList = netctlCommand->getProfileList();
for (int i=0; i<profileList.count(); i++)
if (profile == netctlCommand->getSsidFromProfile(profileList[i][0]))
profileFile = profileList[i][0];
return profileFile;
}
QStringList WpaSup::getInterfaceList()
{
if (debug) qDebug() << "[WpaSup]" << "[getInterfaceList]";
QStringList interfaces;
if (!mainInterface.isEmpty())
interfaces.append(mainInterface);
QStringList allInterfaces = ifaceDirectory->entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (int i=0; i<allInterfaces.count(); i++) {
if (debug) qDebug() << "[WpaSup]" << "[getInterfaceList]" << ":" << "Check directory"
<< ifaceDirectory->path() + 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]);
}
return interfaces;
}
bool WpaSup::isProfileActive(const QString profile)
{
if (debug) qDebug() << "[WpaSup]" << "[isProfileActive]";
QString profileFile;
QList<QStringList> profileList = netctlCommand->getProfileList();
for (int i=0; i<profileList.count(); i++)
if (profile == netctlCommand->getSsidFromProfile(profileList[i][0]))
profileFile = profileList[i][0];
return netctlCommand->isProfileActive(profileFile);
}
bool WpaSup::isProfileExists(const QString profile)
{
if (debug) qDebug() << "[WpaSup]" << "[isProfileExists]";
bool exists = false;
QList<QStringList> profileList = netctlCommand->getProfileList();
for (int i=0; i<profileList.count(); i++)
if (profile == netctlCommand->getSsidFromProfile(profileList[i][0]))
exists = true;
return exists;
}
// functions
bool WpaSup::wpaCliCall(const QString commandLine)
{
if (debug) qDebug() << "[WpaSup]" << "[getInterfaceList]";
QString interface = getInterfaceList()[0];
QProcess command;
QString commandText = wpaCliPath + QString(" -i ") + interface + QString(" -p ") + ctrlDir +
QString(" -P ") + pidFile + QString(" ") + commandLine;
if (debug) qDebug() << "[WpaSup]" << "[wpaCliCall]" << ":" << "Run cmd" << commandText;
command.start(commandText);
command.waitForFinished(-1);
SleepThread::sleep(1);
if (debug) qDebug() << "[WpaSup]" << "[wpaCliCall]" << ":" << "Cmd returns" << command.exitCode();
if (command.exitCode() == 0)
return true;
else
return false;
}
QString WpaSup::getWpaCliOutput(const QString commandLine)
{
if (debug) qDebug() << "[WpaSup]" << "[getWpaCliOutput]";
QString interface = getInterfaceList()[0];
QProcess command;
QString commandText = wpaCliPath + QString(" -i ") + interface + QString(" -p ") + ctrlDir +
QString(" -P ") + pidFile + QString(" ") + commandLine;
if (debug) qDebug() << "[WpaSup]" << "[getWpaCliOutput]" << ":" << "Run cmd" << commandText;
command.start(commandText);
command.waitForFinished(-1);
return command.readAllStandardOutput();
}
QList<QStringList> WpaSup::scanWifi()
{
if (debug) qDebug() << "[WpaSup]" << "[scanWifi]";
QList<QStringList> scanResults;
if (!startWpaSupplicant()) {
stopWpaSupplicant();
return scanResults;
}
if (!wpaCliCall(QString("scan")))
return scanResults;
SleepThread::sleep(3);
QStringList rawOutput = getWpaCliOutput(QString("scan_results")).split(QString("\n"), QString::SkipEmptyParts);
// remove table header
rawOutput.removeFirst();
// remove duplicates
QStringList rawList;
for (int i=0; i<rawOutput.count(); i++) {
bool exist = false;
if (rawOutput[i].split(QString("\t"), QString::SkipEmptyParts).count() > 4)
for (int j=0; j<rawList.count(); j++)
if (rawList[j].split(QString("\t"), QString::SkipEmptyParts).count() > 4)
if (rawOutput[i].split(QString("\t"), QString::SkipEmptyParts)[4] ==
rawList[j].split(QString("\t"), QString::SkipEmptyParts)[4])
exist = true;
if (!exist)
rawList.append(rawOutput[i]);
}
for (int i=0; i<rawList.count(); i++) {
QStringList wifiPoint;
// point name
if (rawList[i].split(QString("\t"), QString::SkipEmptyParts).count() > 4)
wifiPoint.append(rawList[i].split(QString("\t"), QString::SkipEmptyParts)[4]);
else
wifiPoint.append(QString("<hidden>"));
// profile status
QString status;
if (isProfileExists(wifiPoint[0])) {
status = QString("exists");
if (isProfileActive(wifiPoint[0]))
status = status + QString(" (active)");
else
status = status + QString(" (inactive)");
}
else
status = QString("new");
wifiPoint.append(status);
// point signal
wifiPoint.append(rawList[i].split(QString("\t"), QString::SkipEmptyParts)[2]);
// point security
QString security = rawList[i].split(QString("\t"), QString::SkipEmptyParts)[3];
if (security.contains(QString("WPA2")))
security = QString("WPA2");
else if (security.contains(QString("WPA")))
security = QString("WPA");
else if (security.contains(QString("WEP")))
security = QString("WEP");
else
security = QString("none");
wifiPoint.append(security);
scanResults.append(wifiPoint);
}
stopWpaSupplicant();
return scanResults;
}
bool WpaSup::startWpaSupplicant()
{
if (debug) qDebug() << "[WpaSup]" << "[startWpaSupplicant]";
if (!QFile(pidFile).exists()) {
QString interface = getInterfaceList()[0];
QProcess command;
QString commandText = sudoCommand + QString(" ") + wpaSupPath + QString(" -B -P ") + pidFile +
QString(" -i ") + interface + QString(" -D ") + wpaDrivers +
QString(" -C \"DIR=") + ctrlDir + QString(" GROUP=") + ctrlGroup + QString("\"");
if (debug) qDebug() << "[WpaSup]" << "[startWpaSupplicant]" << ":" << "Run cmd" << commandText;
command.start(commandText);
command.waitForFinished(-1);
SleepThread::sleep(1);
if (debug) qDebug() << "[WpaSup]" << "[startWpaSupplicant]" << ":" << "Cmd returns" << command.exitCode();
if (command.exitCode() != 0)
return false;
}
return true;
}
bool WpaSup::stopWpaSupplicant()
{
if (debug) qDebug() << "[WpaSup]" << "[stopWpaSupplicant]";
return wpaCliCall(QString("terminate"));
}