2022-03-22 15:48:08 +08:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) Copyright 2021 KylinSoft Co., Ltd.
|
|
|
|
|
*
|
|
|
|
|
* This program 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, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
|
2021-11-15 15:16:40 +08:00
|
|
|
#include "lockchecker.h"
|
|
|
|
|
#include "loginedusers.h"
|
|
|
|
|
#include <sys/file.h>
|
|
|
|
|
#include <pwd.h>
|
|
|
|
|
#include <QString>
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QDBusMetaType>
|
|
|
|
|
#include <QDBusReply>
|
|
|
|
|
#include <QDBusInterface>
|
|
|
|
|
|
|
|
|
|
#define SYSTEMD_SERVICE "org.freedesktop.login1"
|
|
|
|
|
#define SYSTEMD_PATH "/org/freedesktop/login1"
|
|
|
|
|
#define SYSTEMD_INTERFACE "org.freedesktop.login1.Manager"
|
|
|
|
|
|
|
|
|
|
LockChecker::LockChecker()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LockChecker::~LockChecker()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-22 15:48:08 +08:00
|
|
|
int LockChecker::checkLock()
|
|
|
|
|
{
|
2021-11-15 15:16:40 +08:00
|
|
|
bool lockfile = false;
|
|
|
|
|
bool lockuser = false;
|
|
|
|
|
|
|
|
|
|
QFile file_backup("/tmp/lock/kylin-backup.lock");
|
|
|
|
|
QFile file_update("/tmp/lock/kylin-update.lock");
|
2022-03-22 15:48:08 +08:00
|
|
|
if (file_backup.exists()) {
|
2021-11-15 15:16:40 +08:00
|
|
|
int fd_backup = open(QString("/tmp/lock/kylin-backup.lock").toUtf8().data(), O_RDONLY);
|
|
|
|
|
int b = flock(fd_backup, LOCK_EX|LOCK_NB);
|
|
|
|
|
qDebug() << "b" << b;
|
2022-03-22 15:48:08 +08:00
|
|
|
if (b < 0) {
|
2021-11-15 15:16:40 +08:00
|
|
|
lockfile = true;
|
|
|
|
|
QString file_user = getName(&file_backup);
|
2022-03-22 15:48:08 +08:00
|
|
|
if (file_user == qgetenv("USER")) {
|
2021-11-15 15:16:40 +08:00
|
|
|
lockuser = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
file_backup.close();
|
2022-03-22 15:48:08 +08:00
|
|
|
if (flock(fd_backup, LOCK_UN) == 0) {
|
2021-11-15 15:16:40 +08:00
|
|
|
qDebug() << "unlock sucess.";
|
2022-03-22 15:48:08 +08:00
|
|
|
} else {
|
2021-11-15 15:16:40 +08:00
|
|
|
qDebug() << "unlock fail.";
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-22 15:48:08 +08:00
|
|
|
if (file_update.exists()) {
|
|
|
|
|
int fd_update = open(QString("/tmp/lock/kylin-update.lock").toUtf8().data(), O_RDONLY);
|
|
|
|
|
int c = flock(fd_update, LOCK_EX|LOCK_NB);
|
|
|
|
|
qDebug() << "c" << c;
|
|
|
|
|
if (c < 0) {
|
|
|
|
|
lockfile = true;
|
|
|
|
|
QString file_user = getName(&file_update);
|
|
|
|
|
if (file_user == qgetenv("USER")) {
|
|
|
|
|
lockuser = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
file_backup.close();
|
|
|
|
|
if (flock(fd_update, LOCK_UN) == 0) {
|
|
|
|
|
qDebug() << "unlock sucess.";
|
|
|
|
|
} else {
|
|
|
|
|
qDebug() << "unlock fail.";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (lockfile) {
|
2021-11-15 15:16:40 +08:00
|
|
|
if(lockuser)
|
|
|
|
|
return 2;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-22 15:48:08 +08:00
|
|
|
QStringList LockChecker::getLoginedUsers()
|
|
|
|
|
{
|
2021-11-15 15:16:40 +08:00
|
|
|
QStringList loginedUser;
|
|
|
|
|
qRegisterMetaType<LoginedUsers>("LoginedUsers");
|
|
|
|
|
qDBusRegisterMetaType<LoginedUsers>();
|
|
|
|
|
QDBusInterface loginInterface(SYSTEMD_SERVICE,
|
|
|
|
|
SYSTEMD_PATH,
|
|
|
|
|
SYSTEMD_INTERFACE,
|
|
|
|
|
QDBusConnection::systemBus());
|
|
|
|
|
|
|
|
|
|
if (loginInterface.isValid()) {
|
|
|
|
|
qDebug() << "create interface success";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QDBusMessage result = loginInterface.call("ListUsers");
|
|
|
|
|
QList<QVariant> outArgs = result.arguments();
|
|
|
|
|
QVariant first = outArgs.at(0);
|
|
|
|
|
QDBusArgument dbvFirst = first.value<QDBusArgument>();
|
|
|
|
|
QVariant vFirst = dbvFirst.asVariant();
|
|
|
|
|
const QDBusArgument &dbusArgs = vFirst.value<QDBusArgument>();
|
|
|
|
|
|
|
|
|
|
QVector<LoginedUsers> loginedUsers;
|
|
|
|
|
|
|
|
|
|
dbusArgs.beginArray();
|
|
|
|
|
while (!dbusArgs.atEnd()) {
|
|
|
|
|
LoginedUsers user;
|
|
|
|
|
dbusArgs >> user;
|
|
|
|
|
loginedUsers.push_back(user);
|
|
|
|
|
}
|
|
|
|
|
dbusArgs.endArray();
|
|
|
|
|
|
|
|
|
|
for (LoginedUsers user : loginedUsers) {
|
|
|
|
|
|
|
|
|
|
QDBusInterface userPertyInterface("org.freedesktop.login1",
|
|
|
|
|
user.objpath.path(),
|
|
|
|
|
"org.freedesktop.DBus.Properties",
|
|
|
|
|
QDBusConnection::systemBus());
|
|
|
|
|
|
|
|
|
|
QDBusReply<QVariant> reply = userPertyInterface.call("Get", "org.freedesktop.login1.User", "State");
|
|
|
|
|
if (reply.isValid()) {
|
|
|
|
|
QString status = reply.value().toString();
|
|
|
|
|
if ("closing" != status) {
|
|
|
|
|
loginedUser.append(user.userName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return loginedUser;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*只获取mode为block的inhibitors*/
|
2022-03-22 15:48:08 +08:00
|
|
|
QVector<Inhibitor> LockChecker::getInhibitors()
|
|
|
|
|
{
|
2021-11-15 15:16:40 +08:00
|
|
|
QVector<Inhibitor> inhibitors;
|
|
|
|
|
qRegisterMetaType<Inhibitor>("Inhibitorss");
|
|
|
|
|
qDBusRegisterMetaType<Inhibitor>();
|
|
|
|
|
QDBusInterface loginInterface(SYSTEMD_SERVICE,
|
|
|
|
|
SYSTEMD_PATH,
|
|
|
|
|
SYSTEMD_INTERFACE,
|
|
|
|
|
QDBusConnection::systemBus());
|
|
|
|
|
|
|
|
|
|
if (loginInterface.isValid()) {
|
|
|
|
|
qDebug() << "create interface success";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QDBusMessage result = loginInterface.call("ListInhibitors");
|
|
|
|
|
QList<QVariant> outArgs = result.arguments();
|
|
|
|
|
QVariant first = outArgs.at(0);
|
|
|
|
|
QDBusArgument dbvFirst = first.value<QDBusArgument>();
|
|
|
|
|
QVariant vFirst = dbvFirst.asVariant();
|
|
|
|
|
const QDBusArgument &dbusArgs = vFirst.value<QDBusArgument>();
|
|
|
|
|
|
|
|
|
|
dbusArgs.beginArray();
|
|
|
|
|
while (!dbusArgs.atEnd()) {
|
|
|
|
|
Inhibitor inhibtor;
|
|
|
|
|
dbusArgs >> inhibtor;
|
|
|
|
|
|
|
|
|
|
if (inhibtor.action == QString("shutdown") || inhibtor.action == QString("sleep")) {
|
|
|
|
|
if (inhibtor.mode == QString("block")) {
|
|
|
|
|
inhibitors.push_back(inhibtor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
dbusArgs.endArray();
|
|
|
|
|
|
|
|
|
|
return inhibitors;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool LockChecker::isSleepBlocked()
|
|
|
|
|
{
|
|
|
|
|
QVector<Inhibitor> inhibitors = getInhibitors();
|
|
|
|
|
for (auto iter = inhibitors.begin(); iter != inhibitors.end(); ++iter) {
|
|
|
|
|
if (iter->action == QString("sleep")) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool LockChecker::isShutdownBlocked()
|
|
|
|
|
{
|
|
|
|
|
QVector<Inhibitor> inhibitors = getInhibitors();
|
|
|
|
|
for (auto iter = inhibitors.begin(); iter != inhibitors.end(); ++iter) {
|
|
|
|
|
if (iter->action == QString("shutdown")) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LockChecker::getSleepInhibitors(QStringList &sleepInhibitors, QStringList &sleepInhibitorsReason)
|
|
|
|
|
{
|
|
|
|
|
QVector<Inhibitor> inhibitors = getInhibitors();
|
|
|
|
|
if (inhibitors.size() > 0) {
|
|
|
|
|
for (auto iter = inhibitors.begin(); iter != inhibitors.end(); ++iter) {
|
|
|
|
|
if (iter->action == QString("sleep")) {//获取阻止睡眠的应用名和原因
|
|
|
|
|
QString name = iter->name;
|
|
|
|
|
sleepInhibitors.append(std::move(name));
|
|
|
|
|
QString reason = iter->reason;
|
|
|
|
|
sleepInhibitorsReason.append(std::move(reason));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LockChecker::getShutdownInhibitors(QStringList &shutdownInhibitors, QStringList &shutdownInhibitorsReason)
|
|
|
|
|
{
|
|
|
|
|
QVector<Inhibitor> inhibitors = getInhibitors();
|
|
|
|
|
if (inhibitors.size() > 0) {
|
|
|
|
|
for (auto iter = inhibitors.begin(); iter != inhibitors.end(); ++iter) {
|
|
|
|
|
if (iter->action == QString("shutdown")) {//获取阻止关机和重启的应用名和原因
|
|
|
|
|
QString name = iter->name;
|
|
|
|
|
shutdownInhibitors.append(std::move(name));
|
|
|
|
|
QString reason = iter->reason;
|
|
|
|
|
shutdownInhibitorsReason.append(std::move(reason));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-22 15:48:08 +08:00
|
|
|
QString LockChecker::getName(QFile *a)
|
|
|
|
|
{
|
2021-11-15 15:16:40 +08:00
|
|
|
QString user = getenv("USER");
|
|
|
|
|
if (a->exists()) {
|
|
|
|
|
a->open(QIODevice::ReadOnly|QIODevice::Text);
|
|
|
|
|
QTextStream fileStream(a);
|
|
|
|
|
int k = 0;
|
|
|
|
|
while (!fileStream.atEnd()) {
|
|
|
|
|
QString line = fileStream.readLine();
|
|
|
|
|
if (k == 0) {
|
|
|
|
|
QString a = line;
|
|
|
|
|
qDebug() << "uid="<<a;
|
|
|
|
|
struct passwd *user1;
|
|
|
|
|
user1 = getpwuid(a.toInt());
|
|
|
|
|
qDebug() << "name=" << user1->pw_name << ",uid=" << user1->pw_uid;
|
|
|
|
|
if (user1->pw_name == NULL) {
|
|
|
|
|
return user;
|
|
|
|
|
}
|
|
|
|
|
user = user1->pw_name;
|
|
|
|
|
}
|
|
|
|
|
k++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return user;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int LockChecker::getCachedUsers()
|
|
|
|
|
{
|
|
|
|
|
QDBusInterface loginInterface("org.freedesktop.Accounts",
|
|
|
|
|
"/org/freedesktop/Accounts",
|
|
|
|
|
"org.freedesktop.Accounts",
|
|
|
|
|
QDBusConnection::systemBus());
|
|
|
|
|
|
|
|
|
|
if (loginInterface.isValid()) {
|
|
|
|
|
qDebug() << "create interface success";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QDBusMessage ret = loginInterface.call("ListCachedUsers");
|
|
|
|
|
QList<QVariant> outArgs = ret.arguments();
|
|
|
|
|
QVariant first = outArgs.at(0);
|
|
|
|
|
const QDBusArgument &dbusArgs = first.value<QDBusArgument>();
|
|
|
|
|
QDBusObjectPath path;
|
|
|
|
|
dbusArgs.beginArray();
|
|
|
|
|
int userNum = 0;
|
|
|
|
|
while (!dbusArgs.atEnd()) {
|
|
|
|
|
dbusArgs >> path;
|
|
|
|
|
userNum++;
|
|
|
|
|
}
|
|
|
|
|
dbusArgs.endArray();
|
|
|
|
|
qDebug() << userNum;
|
|
|
|
|
|
|
|
|
|
return userNum;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-22 15:48:08 +08:00
|
|
|
QDBusArgument &operator<<(QDBusArgument &argument, const Inhibitor &mystruct)
|
2021-12-08 09:17:41 +08:00
|
|
|
{
|
2021-11-15 15:16:40 +08:00
|
|
|
argument.beginStructure();
|
|
|
|
|
argument << mystruct.action << mystruct.name << mystruct.reason << mystruct.mode << mystruct.uid << mystruct.pid;
|
|
|
|
|
argument.endStructure();
|
|
|
|
|
return argument;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-22 15:48:08 +08:00
|
|
|
const QDBusArgument &operator>>(const QDBusArgument &argument, Inhibitor &mystruct)
|
|
|
|
|
{
|
2021-11-15 15:16:40 +08:00
|
|
|
argument.beginStructure();
|
|
|
|
|
argument >> mystruct.action >> mystruct.name >> mystruct.reason >> mystruct.mode >> mystruct.uid >> mystruct.pid;
|
|
|
|
|
argument.endStructure();
|
|
|
|
|
return argument;
|
|
|
|
|
}
|