2019-09-06 23:43:07 -04:00
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
|
|
// This file is part of MRCI.
|
|
|
|
|
|
|
|
|
|
// MRCI 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.
|
|
|
|
|
|
|
|
|
|
// MRCI 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 MRCI under the LICENSE.md file. If not, see
|
|
|
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
QString boolStr(bool state)
|
|
|
|
|
{
|
|
|
|
|
QString ret;
|
|
|
|
|
|
|
|
|
|
if (state) ret = "true";
|
|
|
|
|
else ret = "false";
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString genSerialNumber()
|
|
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
Serial::serialIndex++;
|
|
|
|
|
|
|
|
|
|
return QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()) + "-" + QString::number(Serial::serialIndex);
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void serializeThread(QThread *thr)
|
|
|
|
|
{
|
|
|
|
|
thr->setObjectName(genSerialNumber());
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
quint32 toCmdId32(quint16 cmdId, quint16 branchId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
quint32 ret = 0;
|
|
|
|
|
quint32 *dst = &ret;
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
memcpy(dst, &cmdId, 2);
|
|
|
|
|
memcpy(dst + 2, &branchId, 2);
|
2019-09-06 23:43:07 -04:00
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
quint16 toCmdId16(quint32 id)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
quint16 ret = 0;
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
memcpy(&ret, &id, 2);
|
2019-09-06 23:43:07 -04:00
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray toTEXT(const QString &txt)
|
|
|
|
|
{
|
|
|
|
|
QByteArray ret = QTextCodec::codecForName(TXT_CODEC)->fromUnicode(txt);
|
|
|
|
|
|
|
|
|
|
return ret.mid(2); // removes BOM.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray fixedToTEXT(const QString &txt, int len)
|
|
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
return toTEXT(txt).leftJustified(len, 0, true);
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
QByteArray nullTermTEXT(const QString &txt)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
return toTEXT(txt) + QByteArray(2, 0x00);
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
QString fromTEXT(const QByteArray &txt)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
QByteArray ba = txt;
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
ba.replace(QByteArray(2, 0x00), QByteArray());
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
return QTextCodec::codecForName(TXT_CODEC)->toUnicode(ba);
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool noCaseMatch(const QString &strA, const QString &strB)
|
|
|
|
|
{
|
|
|
|
|
return strA.toLower() == strB.toLower();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool containsNewLine(const QString &str)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
for (auto&& chr : str)
|
|
|
|
|
{
|
|
|
|
|
if (chr.category() == QChar::Other_Control)
|
|
|
|
|
{
|
|
|
|
|
ret = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool validSubId(const QString &num)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if (isInt(num))
|
|
|
|
|
{
|
|
|
|
|
ret = (num.toInt() >= 0) && (num.toInt() <= 255);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool validUserName(const QString &uName)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
if ((uName.size() >= 2) && ((uName.size() * 2) <= BLKSIZE_USER_NAME))
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
ret = !uName.contains(' ') && !containsNewLine(uName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool validCommonName(const QString &name)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
if ((name.size() >= 1) && (name.size() <= 136))
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
ret = !name.contains(' ') && !containsNewLine(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool validEmailAddr(const QString &email)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
QStringList spEmail = email.split('@');
|
|
|
|
|
|
|
|
|
|
if ((spEmail.size() == 2) && (email.size() >= 4) && (email.size() <= 64))
|
|
|
|
|
{
|
|
|
|
|
if (!email.contains(' ') && !containsNewLine(email))
|
|
|
|
|
{
|
|
|
|
|
ret = (spEmail[1].split('.').size() > 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool validCommandName(const QString &name)
|
|
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
bool ret = false;
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
if ((name.size() >= 1) && (name.size() <= 64))
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
ret = !name.contains(' ') && !containsNewLine(name);
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool validDispName(const QString &name)
|
|
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
return ((name.size() * 2) <= BLKSIZE_DISP_NAME) && !containsNewLine(name);
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool validChName(const QString &name)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if ((name.size() >= 4) && (name.size() <= 32))
|
|
|
|
|
{
|
|
|
|
|
ret = !name.contains(' ') && !containsNewLine(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool validLevel(const QString &num, bool includePub)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if (isInt(num))
|
|
|
|
|
{
|
|
|
|
|
if (includePub)
|
|
|
|
|
{
|
|
|
|
|
ret = (num.toInt() >= 1) && (num.toInt() <= PUBLIC);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret = (num.toInt() >= 1) && (num.toInt() <= REGULAR);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool validModPath(const QString &modPath)
|
|
|
|
|
{
|
|
|
|
|
bool ret = true;
|
|
|
|
|
QString forbidden = "|*:\"?<>";
|
|
|
|
|
|
2019-11-16 13:08:02 -05:00
|
|
|
if ((modPath.size() > 512) || modPath.isEmpty())
|
2019-11-08 22:06:09 -05:00
|
|
|
{
|
2019-11-16 13:08:02 -05:00
|
|
|
for (auto&& chr : forbidden)
|
2019-11-08 22:06:09 -05:00
|
|
|
{
|
2019-11-16 13:08:02 -05:00
|
|
|
if (modPath.contains(chr))
|
|
|
|
|
{
|
|
|
|
|
ret = false;
|
2019-11-08 22:06:09 -05:00
|
|
|
|
2019-11-16 13:08:02 -05:00
|
|
|
break;
|
|
|
|
|
}
|
2019-11-08 22:06:09 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-29 12:29:01 -05:00
|
|
|
bool acceptablePw(const QString &pw, const QString &uName, const QString &dispName, const QString &email, QString *errMsg)
|
|
|
|
|
{
|
|
|
|
|
auto ret = validPassword(pw);
|
|
|
|
|
|
|
|
|
|
if (!ret)
|
|
|
|
|
{
|
|
|
|
|
*errMsg = "err: Invalid password. it must be between 8-200 chars long containing numbers, mixed case letters and special chars.\n";
|
|
|
|
|
}
|
|
|
|
|
else if (ret && !email.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
if (pw.contains(email, Qt::CaseInsensitive))
|
|
|
|
|
{
|
|
|
|
|
*errMsg = "err: Invalid password. it contains your email address.\n"; ret = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ret && !uName.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
if (pw.contains(uName, Qt::CaseInsensitive))
|
|
|
|
|
{
|
|
|
|
|
*errMsg = "err: Invalid password. it contains your user name.\n"; ret = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ret && !dispName.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
if (pw.contains(dispName, Qt::CaseInsensitive))
|
|
|
|
|
{
|
|
|
|
|
*errMsg = "err: Invalid password. it contains your display name.\n"; ret = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool acceptablePw(const QString &pw, const QByteArray &uId, QString *errMsg)
|
|
|
|
|
{
|
|
|
|
|
auto ret = false;
|
|
|
|
|
|
|
|
|
|
if (auth(uId, pw, TABLE_USERS))
|
|
|
|
|
{
|
|
|
|
|
*errMsg = "err: Invaild password. you cannot re-use your old password.\n";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_USERS);
|
|
|
|
|
db.addColumn(COLUMN_EMAIL);
|
|
|
|
|
db.addColumn(COLUMN_USERNAME);
|
|
|
|
|
db.addColumn(COLUMN_DISPLAY_NAME);
|
|
|
|
|
db.addCondition(COLUMN_USER_ID, uId);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
auto email = db.getData(COLUMN_EMAIL).toString();
|
|
|
|
|
auto uName = db.getData(COLUMN_USERNAME).toString();
|
|
|
|
|
auto dName = db.getData(COLUMN_DISPLAY_NAME).toString();
|
|
|
|
|
|
|
|
|
|
ret = acceptablePw(pw, uName, dName, email, errMsg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 23:43:07 -04:00
|
|
|
bool validPassword(const QString &pw)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if ((pw.size() >= 8) && (pw.size() <= 200))
|
|
|
|
|
{
|
|
|
|
|
bool letters = false;
|
|
|
|
|
bool numbers = false;
|
|
|
|
|
bool upper = false;
|
|
|
|
|
bool lower = false;
|
|
|
|
|
bool special = false;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < pw.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (pw[i].isLetter()) {letters = true; break;}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; (i < pw.size()) && letters; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (pw[i].isNumber()) {numbers = true; break;}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; (i < pw.size()) && numbers; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (pw[i].isUpper()) {upper = true; break;}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; (i < pw.size()) && upper; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (pw[i].isLower()) {lower = true; break;}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; (i < pw.size()) && lower; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (pw[i].isSymbol() || pw[i].isPunct()) {special = true; break;}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = (letters && numbers && upper && lower && special);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool matchedFsObjTypes(const QString &pathA, const QString &pathB)
|
|
|
|
|
{
|
|
|
|
|
QFileInfo infoA(pathA);
|
|
|
|
|
QFileInfo infoB(pathB);
|
|
|
|
|
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if (infoA.isSymLink()) ret = infoB.isSymLink();
|
|
|
|
|
else if (infoA.isFile()) ret = infoB.isFile();
|
|
|
|
|
else ret = infoB.isDir();
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool matchedVolume(const QString &pathA, const QString &pathB)
|
|
|
|
|
{
|
|
|
|
|
QFileInfo infoA(pathA);
|
|
|
|
|
QFileInfo infoB(pathB);
|
|
|
|
|
|
|
|
|
|
QStorageInfo storA(infoA.absolutePath());
|
|
|
|
|
QStorageInfo storB(infoB.absolutePath());
|
|
|
|
|
|
|
|
|
|
return storA.device() == storB.device();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool userExists(const QString &uName, QByteArray *uId, QString *email)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_USERS);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addColumn(COLUMN_USER_ID);
|
|
|
|
|
db.addColumn(COLUMN_EMAIL);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.addCondition(COLUMN_USERNAME, uName);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
if (db.rows() && (uId != nullptr))
|
|
|
|
|
{
|
|
|
|
|
*uId = db.getData(COLUMN_USER_ID).toByteArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (db.rows() && (email != nullptr))
|
|
|
|
|
{
|
|
|
|
|
*email = db.getData(COLUMN_EMAIL).toString();
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 23:43:07 -04:00
|
|
|
return db.rows();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool recoverPWExists(const QByteArray &uId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_PW_RECOVERY);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addColumn(COLUMN_USER_ID);
|
|
|
|
|
db.addCondition(COLUMN_USER_ID, uId);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
return db.rows();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool emailExists(const QString &email, QByteArray *uId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_USERS);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addColumn(COLUMN_USER_ID);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.addCondition(COLUMN_EMAIL, email);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
if (db.rows() && (uId != nullptr))
|
|
|
|
|
{
|
|
|
|
|
*uId = db.getData(COLUMN_USER_ID).toByteArray();
|
|
|
|
|
}
|
2019-09-06 23:43:07 -04:00
|
|
|
|
|
|
|
|
return db.rows();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool modExists(const QString &modPath)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_MODULES);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addColumn(COLUMN_MOD_MAIN);
|
|
|
|
|
db.addCondition(COLUMN_MOD_MAIN, modPath);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
return db.rows();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool rdOnlyFlagExists(const QString &chName, uchar subId, int level)
|
|
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_RDONLY_CAST);
|
|
|
|
|
db.addColumn(COLUMN_ACCESS_LEVEL);
|
|
|
|
|
db.addCondition(COLUMN_SUB_CH_ID, subId);
|
|
|
|
|
db.addCondition(COLUMN_CHANNEL_NAME, chName);
|
|
|
|
|
db.addCondition(COLUMN_ACCESS_LEVEL, level);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
return db.rows();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool isLocked(const QByteArray &uId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_USERS);
|
|
|
|
|
db.addColumn(COLUMN_LOCKED);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addCondition(COLUMN_USER_ID, uId);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
return db.getData(COLUMN_LOCKED).toBool();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isBool(const QString &str)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
int binary = str.toInt(&ret);
|
|
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
ret = (binary == 1) || (binary == 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isInt(const QString &str)
|
|
|
|
|
{
|
|
|
|
|
bool ret;
|
|
|
|
|
|
|
|
|
|
str.toULongLong(&ret);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool matchChs(const char *chsA, const char *chsB)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
for (int i = 0; i < MAX_OPEN_SUB_CHANNELS; i += BLKSIZE_SUB_CHANNEL)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
if (posOfBlock(chsA + i, chsB, MAX_OPEN_SUB_CHANNELS, BLKSIZE_SUB_CHANNEL) != -1)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
ret = true;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
void containsActiveCh(const char *subChs, char *actBlock)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
if (globalActiveFlag())
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
wr8BitToBlock(1, actBlock);
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
2019-11-08 22:06:09 -05:00
|
|
|
else
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
wr8BitToBlock(0, actBlock);
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
Query db;
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
for (int i = 0; i < MAX_OPEN_SUB_CHANNELS; i += BLKSIZE_SUB_CHANNEL)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
quint64 chId = rd64BitFromBlock(subChs + i);
|
|
|
|
|
quint8 subId = rd8BitFromBlock(subChs + (i + 8));
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
db.setType(Query::PULL, TABLE_SUB_CHANNELS);
|
|
|
|
|
db.addColumn(COLUMN_CHANNEL_ID);
|
|
|
|
|
db.addCondition(COLUMN_CHANNEL_ID, chId);
|
|
|
|
|
db.addCondition(COLUMN_SUB_CH_ID, subId);
|
|
|
|
|
db.addCondition(COLUMN_ACTIVE_UPDATE, true);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
if (db.rows())
|
|
|
|
|
{
|
|
|
|
|
wr8BitToBlock(1, actBlock);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
QString defaultPw()
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
db.setType(Query::PULL, TABLE_SERV_SETTINGS);
|
|
|
|
|
db.addColumn(COLUMN_DEFAULT_PASS);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
return db.getData(COLUMN_DEFAULT_PASS).toString();
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool channelExists(const QString &chName, quint64 *chId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_CHANNELS);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addColumn(COLUMN_CHANNEL_ID);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.addCondition(COLUMN_CHANNEL_NAME, chName);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
if (db.rows() && (chId != nullptr))
|
|
|
|
|
{
|
|
|
|
|
*chId = db.getData(COLUMN_CHANNEL_ID).toULongLong();
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 23:43:07 -04:00
|
|
|
return db.rows();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool channelSubExists(quint64 chId, const QString &sub, quint8 *subId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_SUB_CHANNELS);
|
|
|
|
|
db.addColumn(COLUMN_SUB_CH_ID);
|
|
|
|
|
db.addCondition(COLUMN_CHANNEL_ID, chId);
|
|
|
|
|
db.addCondition(COLUMN_SUB_CH_NAME, sub);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
if (db.rows() && (subId != nullptr))
|
|
|
|
|
{
|
|
|
|
|
*subId = static_cast<quint8>(db.getData(COLUMN_SUB_CH_ID).toUInt());
|
|
|
|
|
}
|
2019-09-06 23:43:07 -04:00
|
|
|
|
|
|
|
|
return db.rows();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool inviteExists(const QByteArray &uId, quint64 chId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_CH_MEMBERS);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addColumn(COLUMN_CHANNEL_ID);
|
|
|
|
|
db.addCondition(COLUMN_CHANNEL_ID, chId);
|
|
|
|
|
db.addCondition(COLUMN_USER_ID, uId);
|
|
|
|
|
db.addCondition(COLUMN_PENDING_INVITE, true);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
return db.rows();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool globalActiveFlag()
|
|
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_SERV_SETTINGS);
|
|
|
|
|
db.addColumn(COLUMN_ACTIVE_UPDATE);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
return db.getData(COLUMN_ACTIVE_UPDATE).toBool();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool genSubId(quint64 chId, quint8 *newId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_SUB_CHANNELS);
|
|
|
|
|
db.addColumn(COLUMN_SUB_CH_ID);
|
|
|
|
|
db.addCondition(COLUMN_CHANNEL_ID, chId);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
if (db.rows() < maxSubChannels())
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
QList<quint8> subList;
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
for (int i = 0; i < db.rows(); ++i)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
subList.append(static_cast<quint8>(db.getData(COLUMN_SUB_CH_ID, i).toUInt()));
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
ret = true;
|
|
|
|
|
*newId = 0;
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
while (subList.contains(*newId)) *newId += 1;
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
bool isChOwner(const QByteArray &uId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_CH_MEMBERS);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addColumn(COLUMN_USER_ID);
|
|
|
|
|
db.addCondition(COLUMN_USER_ID, uId);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.addCondition(COLUMN_PENDING_INVITE, false);
|
|
|
|
|
db.addCondition(COLUMN_ACCESS_LEVEL, OWNER);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
return db.rows();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
int maxSubChannels()
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
db.setType(Query::PULL, TABLE_SERV_SETTINGS);
|
|
|
|
|
db.addColumn(COLUMN_MAX_SUB_CH);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
return db.getData(COLUMN_MAX_SUB_CH).toInt();
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
int channelAccessLevel(const QByteArray &uId, const char *override, quint64 chId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
if (rd8BitFromBlock(override) == 1)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
return OWNER;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
return channelAccessLevel(uId, chId);
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
int channelAccessLevel(const QByteArray &uId, quint64 chId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
db.setType(Query::PULL, TABLE_CH_MEMBERS);
|
|
|
|
|
db.addColumn(COLUMN_ACCESS_LEVEL);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.addCondition(COLUMN_CHANNEL_ID, chId);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addCondition(COLUMN_USER_ID, uId);
|
|
|
|
|
db.addCondition(COLUMN_PENDING_INVITE, false);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
if (db.rows())
|
|
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
return db.getData(COLUMN_ACCESS_LEVEL).toInt();
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
return PUBLIC;
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void listDir(QList<QPair<QString, QString> > &list, const QString &srcPath, const QString &dstPath)
|
|
|
|
|
{
|
|
|
|
|
QDir dir(srcPath);
|
|
|
|
|
|
|
|
|
|
dir.setFilter(QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot);
|
|
|
|
|
dir.setSorting(QDir::DirsFirst);
|
|
|
|
|
|
|
|
|
|
QStringList ls = dir.entryList();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ls.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
QPair<QString,QString> srcToDst(srcPath + "/" + ls[i], dstPath + "/" + ls[i]);
|
|
|
|
|
|
|
|
|
|
list.append(srcToDst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
QString getUserNameForEmail(const QString &email)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_USERS);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addColumn(COLUMN_USERNAME);
|
|
|
|
|
db.addCondition(COLUMN_EMAIL, email);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
return db.getData(COLUMN_USERNAME).toString();
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
QString getDispName(const QByteArray &uId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_USERS);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addColumn(COLUMN_DISPLAY_NAME);
|
|
|
|
|
db.addCondition(COLUMN_USER_ID, uId);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
return db.getData(COLUMN_DISPLAY_NAME).toString();
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
2020-01-29 12:29:01 -05:00
|
|
|
QString getUserName(const QByteArray &uId)
|
|
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_USERS);
|
|
|
|
|
db.addColumn(COLUMN_USERNAME);
|
|
|
|
|
db.addCondition(COLUMN_USER_ID, uId);
|
|
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
return db.getData(COLUMN_USERNAME).toString();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
QString getEmailForUser(const QByteArray &uId)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
|
|
|
|
Query db;
|
|
|
|
|
|
|
|
|
|
db.setType(Query::PULL, TABLE_USERS);
|
|
|
|
|
db.addColumn(COLUMN_EMAIL);
|
2019-11-08 22:06:09 -05:00
|
|
|
db.addCondition(COLUMN_USER_ID, uId);
|
2019-09-06 23:43:07 -04:00
|
|
|
db.exec();
|
|
|
|
|
|
|
|
|
|
return db.getData(COLUMN_EMAIL).toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString escapeChars(const QString &str, const QChar &escapeChr, const QChar &chr)
|
|
|
|
|
{
|
|
|
|
|
QString ret;
|
|
|
|
|
bool escaped = false;
|
|
|
|
|
|
|
|
|
|
if (escapeChr == chr)
|
|
|
|
|
{
|
|
|
|
|
ret = str;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (auto&& strChr : str)
|
|
|
|
|
{
|
|
|
|
|
if ((strChr == chr) && !escaped)
|
|
|
|
|
{
|
|
|
|
|
ret.append(escapeChr);
|
|
|
|
|
ret.append(strChr);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
escaped = false;
|
|
|
|
|
|
|
|
|
|
if (strChr == escapeChr)
|
|
|
|
|
{
|
|
|
|
|
escaped = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret.append(strChr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mkPath(const QString &path)
|
|
|
|
|
{
|
|
|
|
|
if (!QDir().exists(path))
|
|
|
|
|
{
|
|
|
|
|
QDir().mkpath(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList parseArgs(const QByteArray &data, int maxArgs, int *pos)
|
|
|
|
|
{
|
|
|
|
|
QStringList ret;
|
|
|
|
|
QString arg;
|
|
|
|
|
QString line = fromTEXT(data);
|
|
|
|
|
bool inDQuotes = false;
|
|
|
|
|
bool inSQuotes = false;
|
|
|
|
|
bool escaped = false;
|
|
|
|
|
|
|
|
|
|
if (pos != nullptr) *pos = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < line.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (pos != nullptr) *pos += (TXT_CODEC_BITS / 8);
|
|
|
|
|
|
|
|
|
|
if ((line[i] == '\'') && !inDQuotes && !escaped)
|
|
|
|
|
{
|
|
|
|
|
// single quote '
|
|
|
|
|
|
|
|
|
|
inSQuotes = !inSQuotes;
|
|
|
|
|
}
|
|
|
|
|
else if ((line[i] == '\"') && !inSQuotes && !escaped)
|
|
|
|
|
{
|
|
|
|
|
// double quote "
|
|
|
|
|
|
|
|
|
|
inDQuotes = !inDQuotes;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
escaped = false;
|
|
|
|
|
|
|
|
|
|
if (line[i].isSpace() && !inDQuotes && !inSQuotes)
|
|
|
|
|
{
|
|
|
|
|
// space
|
|
|
|
|
|
|
|
|
|
if (!arg.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
ret.append(arg);
|
|
|
|
|
arg.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((line[i] == '\\') && ((i + 1) < line.size()))
|
|
|
|
|
{
|
|
|
|
|
if ((line[i + 1] == '\'') || (line[i + 1] == '\"'))
|
|
|
|
|
{
|
|
|
|
|
escaped = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
arg.append(line[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
arg.append(line[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((ret.size() >= maxArgs) && (maxArgs != -1))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!arg.isEmpty() && !inDQuotes && !inSQuotes)
|
|
|
|
|
{
|
|
|
|
|
ret.append(arg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString getParam(const QString &key, const QStringList &args)
|
|
|
|
|
{
|
|
|
|
|
// this can be used by command objects to pick out parameters
|
|
|
|
|
// from a command line that are pointed by a name identifier
|
|
|
|
|
// example: -i /etc/some_file, this function should pick out
|
|
|
|
|
// "/etc/some_file" from args if "-i" is passed into key.
|
|
|
|
|
|
|
|
|
|
QString ret;
|
|
|
|
|
|
|
|
|
|
int pos = args.indexOf(QRegExp(key, Qt::CaseInsensitive));
|
|
|
|
|
|
|
|
|
|
if (pos != -1)
|
|
|
|
|
{
|
|
|
|
|
// key found.
|
|
|
|
|
|
|
|
|
|
if ((pos + 1) <= (args.size() - 1))
|
|
|
|
|
{
|
|
|
|
|
// check ahead to make sure pos + 1 will not go out
|
|
|
|
|
// of range.
|
|
|
|
|
|
|
|
|
|
if (!args[pos + 1].startsWith("-"))
|
|
|
|
|
{
|
|
|
|
|
// the "-" used throughout this application
|
|
|
|
|
// indicates an argument so the above 'if'
|
|
|
|
|
// statement will check to make sure it does
|
|
|
|
|
// not return another argument as a parameter
|
|
|
|
|
// in case a back-to-back "-arg -arg" is
|
|
|
|
|
// present.
|
|
|
|
|
|
|
|
|
|
ret = args[pos + 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool argExists(const QString &key, const QStringList &args)
|
|
|
|
|
{
|
|
|
|
|
return args.contains(key, Qt::CaseInsensitive);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SessionCarrier::SessionCarrier(Session *session) : QObject()
|
|
|
|
|
{
|
|
|
|
|
sessionObj = session;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
IdleTimer::IdleTimer(QObject *parent) : QTimer(parent)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
setSingleShot(true);
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
void IdleTimer::detectWrite(qint64)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
start();
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
void IdleTimer::attach(QIODevice *dev, int msec)
|
2019-09-06 23:43:07 -04:00
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
setInterval(msec);
|
2019-09-06 23:43:07 -04:00
|
|
|
|
2019-11-08 22:06:09 -05:00
|
|
|
connect(dev, SIGNAL(readyRead()), this, SLOT(start()));
|
|
|
|
|
connect(dev, SIGNAL(bytesWritten(qint64)), this, SLOT(detectWrite(qint64)));
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ShellIPC::ShellIPC(const QStringList &args, QObject *parent) : QLocalSocket(parent)
|
|
|
|
|
{
|
|
|
|
|
arguments = args;
|
|
|
|
|
|
|
|
|
|
connect(this, SIGNAL(connected()), this, SLOT(hostConnected()));
|
|
|
|
|
connect(this, SIGNAL(disconnected()), this, SIGNAL(closeInstance()));
|
|
|
|
|
connect(this, SIGNAL(readyRead()), this, SLOT(dataIn()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ShellIPC::connectToHost()
|
|
|
|
|
{
|
2019-11-08 22:06:09 -05:00
|
|
|
connectToServer(HOST_CONTROL_PIPE);
|
2019-09-06 23:43:07 -04:00
|
|
|
|
|
|
|
|
if (!waitForConnected())
|
|
|
|
|
{
|
2020-01-29 12:29:01 -05:00
|
|
|
if (QFileInfo(QDir::tempPath() + "/" + HOST_CONTROL_PIPE).exists())
|
|
|
|
|
{
|
|
|
|
|
QTextStream(stdout) << "" << endl << "Permission denied." << endl << endl;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
QTextStream(stdout) << "" << endl << "Host instance not running." << endl << endl;
|
|
|
|
|
}
|
2019-09-06 23:43:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return state() == QLocalSocket::ConnectedState;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ShellIPC::hostConnected()
|
|
|
|
|
{
|
|
|
|
|
write(toTEXT(arguments.join(' ')));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ShellIPC::dataIn()
|
|
|
|
|
{
|
|
|
|
|
QTextStream(stdout) << fromTEXT(readAll());
|
|
|
|
|
|
|
|
|
|
emit closeInstance();
|
|
|
|
|
}
|
2019-11-08 22:06:09 -05:00
|
|
|
|
|
|
|
|
quint64 Serial::serialIndex = 0;
|