mirror of
https://gitlab.com/Syping/mayu
synced 2024-11-22 12:00:23 +01:00
add mayu resolve
This commit is contained in:
parent
cba86b4b28
commit
16d5d83eec
4 changed files with 195 additions and 50 deletions
20
main.cpp
20
main.cpp
|
@ -16,6 +16,9 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QString>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "mayu.h"
|
#include "mayu.h"
|
||||||
|
|
||||||
|
@ -28,11 +31,28 @@ int main(int argc, char *argv[])
|
||||||
QStringList arguments = a.arguments();
|
QStringList arguments = a.arguments();
|
||||||
arguments.removeAt(0);
|
arguments.removeAt(0);
|
||||||
|
|
||||||
|
mayuMode a_mode = mayuMode::Ping;
|
||||||
|
for (int i = arguments.length(); i > 0; i--) {
|
||||||
|
const QString &argument = arguments.at(i-1);
|
||||||
|
if (argument == "-p" || argument == "--ping") {
|
||||||
|
a_mode = mayuMode::Ping;
|
||||||
|
arguments.removeAt(i-1);
|
||||||
|
}
|
||||||
|
else if (argument == "-r" || argument == "--resolve") {
|
||||||
|
a_mode = mayuMode::Resolve;
|
||||||
|
arguments.removeAt(i-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (arguments.length() >= 2) {
|
if (arguments.length() >= 2) {
|
||||||
mayu a_mayu(arguments.at(0), arguments.at(1));
|
mayu a_mayu(arguments.at(0), arguments.at(1));
|
||||||
|
a_mayu.setMayuMode(a_mode);
|
||||||
a_mayu.work();
|
a_mayu.work();
|
||||||
return a_mayu.getResult();
|
return a_mayu.getResult();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
QTextStream(stdout) << "Usage: " << a.arguments().at(0) << " [-p ping]" << " [-r resolve]" << " input.txt" << " output.json" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
185
mayu.cpp
185
mayu.cpp
|
@ -26,20 +26,29 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#ifdef MAYU_UNIX
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "oping.h"
|
#include "oping.h"
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
mayu::mayu(const QString &hostsFile, const QString &jsonFile, int tries, QObject *parent) : QObject(parent)
|
mayu::mayu(const QString &hostsFile, const QString &jsonFile, QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
p_return = -1;
|
p_return = -1;
|
||||||
p_tries = tries;
|
p_timeout = 2.5;
|
||||||
|
p_tries = 4;
|
||||||
|
p_mayuMode = mayuMode::Ping;
|
||||||
if (!hostsFile.isEmpty())
|
if (!hostsFile.isEmpty())
|
||||||
setHostsFile(hostsFile);
|
setHostsFile(hostsFile);
|
||||||
if (!jsonFile.isEmpty())
|
if (!jsonFile.isEmpty())
|
||||||
setJsonFile(jsonFile);
|
setJsonFile(jsonFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mayu::setMayuMode(mayuMode mode)
|
||||||
|
{
|
||||||
|
p_mayuMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
void mayu::setHostsFile(const QString &fileName)
|
void mayu::setHostsFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
p_hostsFile = fileName;
|
p_hostsFile = fileName;
|
||||||
|
@ -57,11 +66,21 @@ void mayu::setJsonFile(const QString &fileName)
|
||||||
p_jsonFile = fileName;
|
p_jsonFile = fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mayu::setMaxTries(int tries)
|
void mayu::setPingTimeout(double timeout)
|
||||||
|
{
|
||||||
|
p_timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mayu::setPingTries(int tries)
|
||||||
{
|
{
|
||||||
p_tries = tries;
|
p_tries = tries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mayuMode mayu::getMayuMode()
|
||||||
|
{
|
||||||
|
return p_mayuMode;
|
||||||
|
}
|
||||||
|
|
||||||
const QString mayu::getHostsFile()
|
const QString mayu::getHostsFile()
|
||||||
{
|
{
|
||||||
return p_hostsFile;
|
return p_hostsFile;
|
||||||
|
@ -77,7 +96,12 @@ const QString mayu::getJsonFile()
|
||||||
return p_jsonFile;
|
return p_jsonFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mayu::getMaxTries()
|
double mayu::getPingTimeout()
|
||||||
|
{
|
||||||
|
return p_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mayu::getPingTries()
|
||||||
{
|
{
|
||||||
return p_tries;
|
return p_tries;
|
||||||
}
|
}
|
||||||
|
@ -87,21 +111,18 @@ int mayu::getResult()
|
||||||
return p_return;
|
return p_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAYU_UNIX
|
||||||
double mayu::ping(const QString &host, int tries, double timeout)
|
double mayu::ping(const QString &host, int tries, double timeout)
|
||||||
{
|
{
|
||||||
double latency;
|
double latency;
|
||||||
pingobj_t *pingObj;
|
pingobj_t *pingObj;
|
||||||
pingobj_iter_t *pingIter;
|
pingobj_iter_t *pingIter;
|
||||||
if ((pingObj = ping_construct()) == NULL) {
|
if ((pingObj = ping_construct()) == NULL) {
|
||||||
#ifdef E_DEBUG
|
QTextStream(stderr) << "Ping construction failed " << endl;
|
||||||
qDebug() << "Ping construction failed";
|
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (ping_setopt(pingObj, PING_OPT_TIMEOUT, (void*)(&timeout)) < 0) {
|
if (ping_setopt(pingObj, PING_OPT_TIMEOUT, (void*)(&timeout)) < 0) {
|
||||||
#ifdef E_DEBUG
|
QTextStream(stderr) << "Setting timeout to" << timeout << " have failed" << endl;
|
||||||
qDebug() << "Setting timeout to" << timeout << "have failed";
|
|
||||||
#endif
|
|
||||||
ping_destroy(pingObj);
|
ping_destroy(pingObj);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -148,9 +169,7 @@ double mayu::ping(const QString &host, int tries, double timeout)
|
||||||
int curTry = 0;
|
int curTry = 0;
|
||||||
while (!hostUp && curTry != tries) {
|
while (!hostUp && curTry != tries) {
|
||||||
if (ping_send(pingObj) < 0) {
|
if (ping_send(pingObj) < 0) {
|
||||||
#ifdef E_DEBUG
|
QTextStream(stderr) << "Pinging host " << host << " has failed" << endl;
|
||||||
qDebug() << "Pinging host" << host << " has failed";
|
|
||||||
#endif
|
|
||||||
ping_destroy(pingObj);
|
ping_destroy(pingObj);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +184,7 @@ double mayu::ping(const QString &host, int tries, double timeout)
|
||||||
char hostname[100];
|
char hostname[100];
|
||||||
len = 100;
|
len = 100;
|
||||||
ping_iterator_get_info(pingIter, PING_INFO_HOSTNAME, hostname, &len);
|
ping_iterator_get_info(pingIter, PING_INFO_HOSTNAME, hostname, &len);
|
||||||
qDebug() << hostname << latency << pingSuccess;
|
QTextStream(stdout) << "Host: " << hostname << " Ping: " << latency << "ms" << " Status: " << (pingSuccess ? "true" : "false") << endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (pingSuccess) {
|
if (pingSuccess) {
|
||||||
|
@ -178,14 +197,44 @@ double mayu::ping(const QString &host, int tries, double timeout)
|
||||||
return latency;
|
return latency;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const QList<mayuResult> mayu::resolve(const QString &host)
|
||||||
|
{
|
||||||
|
QList<mayuResult> resultList;
|
||||||
|
QList<QHostAddress> hostAddresses = QHostInfo::fromName(host).addresses();
|
||||||
|
if (hostAddresses.length() >= 1) {
|
||||||
|
for (const QHostAddress &hostAddress : hostAddresses) {
|
||||||
|
#ifdef E_DEBUG
|
||||||
|
qDebug() << "Hostname" << host << "found and resolved" << hostAddress.toString();
|
||||||
|
#endif
|
||||||
|
mayuResult m_result;
|
||||||
|
m_result.host = host;
|
||||||
|
m_result.result = hostAddress.toString();
|
||||||
|
resultList += m_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef E_DEBUG
|
||||||
|
qDebug() << "Hostname" << host << "not found";
|
||||||
|
#endif
|
||||||
|
mayuResult m_result;
|
||||||
|
m_result.host = host;
|
||||||
|
m_result.result = "-1";
|
||||||
|
resultList += m_result;
|
||||||
|
}
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
|
|
||||||
void mayu::parse_hosts()
|
void mayu::parse_hosts()
|
||||||
{
|
{
|
||||||
p_hostsList.clear();
|
p_hostsList.clear();
|
||||||
if (!dropPrivileges()) {
|
#ifdef PRIVILEGE_DROP_REQUIRED
|
||||||
|
if (!p_dropPrivileges()) {
|
||||||
p_return = 2;
|
p_return = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
QFile hostsFile(p_hostsFile);
|
QFile hostsFile(p_hostsFile);
|
||||||
if (hostsFile.open(QFile::ReadOnly)) {
|
if (hostsFile.open(QFile::ReadOnly)) {
|
||||||
const QList<QByteArray> hostsArray = hostsFile.readAll().split('\n');
|
const QList<QByteArray> hostsArray = hostsFile.readAll().split('\n');
|
||||||
|
@ -210,57 +259,104 @@ void mayu::parse_hosts()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qCritical() << "Failed read hosts from" << p_hostsFile;
|
QTextStream(stderr) << "Failed read hosts from " << p_hostsFile << endl;
|
||||||
}
|
}
|
||||||
if (!regainPrivileges()) {
|
#ifdef PRIVILEGE_DROP_REQUIRED
|
||||||
|
if (!p_regainPrivileges()) {
|
||||||
p_return = 3;
|
p_return = 3;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void mayu::p_saveWork(QJsonObject jsonObject)
|
||||||
|
{
|
||||||
|
QJsonDocument jsonDocument;
|
||||||
|
jsonDocument.setObject(jsonObject);
|
||||||
|
QByteArray jsonArray = jsonDocument.toJson();
|
||||||
|
#ifdef PRIVILEGE_DROP_REQUIRED
|
||||||
|
if (!p_dropPrivileges()) {
|
||||||
|
p_return = 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
QSaveFile jsonFile(p_jsonFile);
|
||||||
|
if (jsonFile.open(QSaveFile::WriteOnly)) {
|
||||||
|
jsonFile.write(jsonArray);
|
||||||
|
if (!jsonFile.commit()) {
|
||||||
|
QTextStream(stderr) << "Failed save result to " << p_jsonFile << " because file can't be saved!" << endl;
|
||||||
|
p_return = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
QTextStream(stderr) << "Failed save result to " << p_jsonFile << " because file can't be opened!" << endl;
|
||||||
|
p_return = 1;
|
||||||
|
}
|
||||||
|
#ifdef PRIVILEGE_DROP_REQUIRED
|
||||||
|
if (!p_regainPrivileges()) {
|
||||||
|
p_return = 3;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
p_return = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mayu::work()
|
void mayu::work()
|
||||||
|
{
|
||||||
|
switch(p_mayuMode) {
|
||||||
|
case mayuMode::Ping:
|
||||||
|
#ifdef MAYU_UNIX
|
||||||
|
p_workPing();
|
||||||
|
#else
|
||||||
|
QTextStream(stderr) << "Mayu doesn't support pinging on your Operating System!" << endl;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case mayuMode::Resolve:
|
||||||
|
p_workResolve();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MAYU_UNIX
|
||||||
|
void mayu::p_workPing()
|
||||||
{
|
{
|
||||||
if (!p_hostsParsed)
|
if (!p_hostsParsed)
|
||||||
parse_hosts();
|
parse_hosts();
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
const QStringList hostsList = getHosts();
|
const QStringList hostsList = getHosts();
|
||||||
for (const QString &host : hostsList) {
|
for (const QString &host : hostsList) {
|
||||||
double result = ping(host, p_tries);
|
double result = ping(host, p_tries, p_timeout);
|
||||||
jsonObject[host] = result;
|
jsonObject[host] = result;
|
||||||
}
|
}
|
||||||
QJsonDocument jsonDocument;
|
p_saveWork(jsonObject);
|
||||||
jsonDocument.setObject(jsonObject);
|
}
|
||||||
QByteArray jsonArray = jsonDocument.toJson();
|
#endif
|
||||||
if (!dropPrivileges()) {
|
|
||||||
p_return = 2;
|
void mayu::p_workResolve()
|
||||||
return;
|
{
|
||||||
}
|
if (!p_hostsParsed)
|
||||||
QSaveFile jsonFile(p_jsonFile);
|
parse_hosts();
|
||||||
if (jsonFile.open(QSaveFile::WriteOnly)) {
|
QJsonObject jsonObject;
|
||||||
jsonFile.write(jsonArray);
|
const QStringList hostsList = getHosts();
|
||||||
if (!jsonFile.commit()) {
|
for (const QString &host : hostsList) {
|
||||||
qCritical() << "Failed save result to" << p_jsonFile << "because file can't be saved!";
|
const QList<mayuResult> resultList = resolve(host);
|
||||||
p_return = 1;
|
QJsonArray arrayList;
|
||||||
|
for (const mayuResult &result : resultList) {
|
||||||
|
arrayList += result.result;
|
||||||
}
|
}
|
||||||
|
jsonObject[host] = arrayList;
|
||||||
}
|
}
|
||||||
else {
|
p_saveWork(jsonObject);
|
||||||
qCritical() << "Failed save result to" << p_jsonFile << "because file can't be opened!";
|
|
||||||
p_return = 1;
|
|
||||||
}
|
|
||||||
if (!regainPrivileges()) {
|
|
||||||
p_return = 3;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p_return = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mayu::dropPrivileges()
|
#ifdef PRIVILEGE_DROP_REQUIRED
|
||||||
|
bool mayu::p_dropPrivileges()
|
||||||
{
|
{
|
||||||
#if _POSIX_SAVED_IDS
|
#if _POSIX_SAVED_IDS
|
||||||
p_uid = geteuid();
|
p_uid = geteuid();
|
||||||
int status = seteuid(getuid());
|
int status = seteuid(getuid());
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
qCritical() << "Dropping of privileges has failed!";
|
QTextStream(stderr) << "Dropping of privileges has failed!" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -269,12 +365,12 @@ bool mayu::dropPrivileges()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mayu::regainPrivileges()
|
bool mayu::p_regainPrivileges()
|
||||||
{
|
{
|
||||||
#if _POSIX_SAVED_IDS
|
#if _POSIX_SAVED_IDS
|
||||||
int status = seteuid(p_uid);
|
int status = seteuid(p_uid);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
qCritical() << "Regaining of privileges has failed!";
|
QTextStream(stderr) << "Regaining of privileges has failed!" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -282,3 +378,4 @@ bool mayu::regainPrivileges()
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
36
mayu.h
36
mayu.h
|
@ -21,38 +21,64 @@
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QJsonArray>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
enum class mayuMode : int{Ping = 0, Resolve = 1};
|
||||||
|
struct mayuResult {
|
||||||
|
QString host;
|
||||||
|
QString result;
|
||||||
|
};
|
||||||
|
|
||||||
class mayu : public QObject
|
class mayu : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit mayu(const QString &hostsFile = QString(), const QString &jsonFile = QString(), int tries = 4, QObject *parent = nullptr);
|
explicit mayu(const QString &hostsFile = QString(), const QString &jsonFile = QString(), QObject *parent = nullptr);
|
||||||
|
void setMayuMode(mayuMode mode);
|
||||||
void setHostsFile(const QString &fileName);
|
void setHostsFile(const QString &fileName);
|
||||||
void setHosts(const QStringList &hostsList);
|
void setHosts(const QStringList &hostsList);
|
||||||
void setJsonFile(const QString &fileName);
|
void setJsonFile(const QString &fileName);
|
||||||
void setMaxTries(int tries);
|
void setPingTimeout(double timeout);
|
||||||
|
void setPingTries(int tries);
|
||||||
|
mayuMode getMayuMode();
|
||||||
const QString getHostsFile();
|
const QString getHostsFile();
|
||||||
const QStringList getHosts();
|
const QStringList getHosts();
|
||||||
const QString getJsonFile();
|
const QString getJsonFile();
|
||||||
int getMaxTries();
|
double getPingTimeout();
|
||||||
|
int getPingTries();
|
||||||
int getResult();
|
int getResult();
|
||||||
|
#ifdef MAYU_UNIX
|
||||||
static double ping(const QString &host, int tries, double timeout = 2.5);
|
static double ping(const QString &host, int tries, double timeout = 2.5);
|
||||||
|
#endif
|
||||||
|
static const QList<mayuResult> resolve(const QString &host);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void parse_hosts();
|
void parse_hosts();
|
||||||
void work();
|
void work();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool dropPrivileges();
|
#ifdef PRIVILEGE_DROP_REQUIRED
|
||||||
bool regainPrivileges();
|
bool p_dropPrivileges();
|
||||||
|
bool p_regainPrivileges();
|
||||||
|
#endif
|
||||||
|
void p_saveWork(QJsonObject jsonObject);
|
||||||
|
#ifdef MAYU_UNIX
|
||||||
|
void p_workPing();
|
||||||
|
#endif
|
||||||
|
void p_workResolve();
|
||||||
QStringList p_hostsList;
|
QStringList p_hostsList;
|
||||||
QString p_hostsFile;
|
QString p_hostsFile;
|
||||||
QString p_jsonFile;
|
QString p_jsonFile;
|
||||||
|
mayuMode p_mayuMode;
|
||||||
bool p_hostsParsed;
|
bool p_hostsParsed;
|
||||||
|
double p_timeout;
|
||||||
int p_return;
|
int p_return;
|
||||||
int p_tries;
|
int p_tries;
|
||||||
|
#ifdef PRIVILEGE_DROP_REQUIRED
|
||||||
uid_t p_uid;
|
uid_t p_uid;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAYU_H
|
#endif // MAYU_H
|
||||||
|
|
4
mayu.pro
4
mayu.pro
|
@ -18,7 +18,9 @@
|
||||||
QT -= gui
|
QT -= gui
|
||||||
QT += network
|
QT += network
|
||||||
|
|
||||||
LIBS += -loping
|
unix: DEFINES += PRIVILEGE_DROP_REQUIRED
|
||||||
|
unix: DEFINES += MAYU_UNIX
|
||||||
|
unix: LIBS += -loping
|
||||||
|
|
||||||
CONFIG += c++11 console
|
CONFIG += c++11 console
|
||||||
CONFIG -= app_bundle
|
CONFIG -= app_bundle
|
||||||
|
|
Loading…
Reference in a new issue