Adding upstream version 0.9.0.

Signed-off-by: Andrew Lee (李健秋) <ajqlee@debian.org>
ubuntu/cosmic upstream/0.9.0
Andrew Lee (李健秋) 10 years ago
commit b47113e5df
No known key found for this signature in database
GPG Key ID: 9D0633E1B6250985

1
.gitignore vendored

@ -0,0 +1 @@
build

@ -0,0 +1,84 @@
cmake_minimum_required(VERSION 2.8.11)
project(lxqt-sudo)
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(FATAL "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. C++11 support is required")
endif()
find_package(Qt5Widgets REQUIRED QUIET)
find_package(lxqt REQUIRED QUIET)
include(${LXQT_USE_FILE})
include(LXQtTranslate)
include_directories (
${CMAKE_CURRENT_BINARY_DIR}
${LXQT_INCLUDE_DIRS}
)
add_definitions("-DLXQTSUDO_INSTALL_DIR=\"${CMAKE_INSTALL_PREFIX}/bin\""
"-DLXQTSUDO_SUDO=\"sudo\""
"-DLXQTSUDO=\"lxqt-sudo\""
"-DLXQT_VERSION=\"${LXQT_VERSION}\""
)
set ( HDRS
passworddialog.h
)
set ( SRCS
passworddialog.cpp
main.cpp
)
set ( MOCS
passworddialog.h
)
set( UIS
passworddialog.ui
)
qt5_wrap_cpp(MOC_OBJECTS ${MOCS})
qt5_wrap_ui(UI_HEADERS ${UIS})
# Translations **********************************
lxqt_translate_ts(QM_FILES
UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS}
SOURCES
${HDRS}
${SRCS}
${UIS}
INSTALL_DIR
"${LXQT_TRANSLATIONS_DIR}/${PROJECT_NAME}"
)
lxqt_app_translation_loader(SRCS ${PROJECT_NAME})
#************************************************
add_executable(lxqt-sudo
${SRCS}
${UI_HEADERS}
${MOC_OBJECTS}
${DESKTOP_FILES}
${QM_FILES}
)
target_link_libraries(lxqt-sudo
Qt5::Widgets
${LXQT_LIBRARIES}
)
install(TARGETS lxqt-sudo RUNTIME DESTINATION bin)
install(FILES ${DESKTOP_FILES} DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
install(FILES man/lxqt-sudo.1 DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1")

@ -0,0 +1,193 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://lxqt.org
*
* Copyright: 2015 LXQt team
* Authors:
* Palo Kisa <palo.kisa@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#include <LXQt/Application>
#include "passworddialog.h"
#include <QFileInfo>
#include <QDir>
#include <QProcess>
#include <QTimer>
#include <QMessageBox>
#include <QSocketNotifier>
#include <signal.h>
#include <sstream>
#include <QDebug>
const QString app_master{QStringLiteral(LXQTSUDO)};
const QString app_version{QStringLiteral(LXQT_VERSION)};
const QString install_dir{QStringLiteral(LXQTSUDO_INSTALL_DIR)};
const QString sudo_prog{QStringLiteral(LXQTSUDO_SUDO)};
const QString sudo_pwd_prompt{QStringLiteral("Password:\n")};
void termSignalHandler(int signal)
{
if (QApplication::instance())
QApplication::instance()->quit();
}
void usage(QString const & err = QString())
{
if (!err.isEmpty())
QTextStream(stderr) << err << '\n';
QTextStream(stdout)
<< QObject::tr("Usage: %1 command [arguments...]\n\n"
"GUI frontend for %2\n\n"
"Arguments:\n"
" command Command to run.\n"
" arguments Optional arguments for command.\n\n").arg(app_master).arg(sudo_prog);
if (!err.isEmpty())
QMessageBox(QMessageBox::Critical, app_master, err, QMessageBox::Ok).exec();
}
void version()
{
QTextStream(stdout)
<< QObject::tr("%1 version %2\n").arg(app_master).arg(app_version);
}
int master(int argc, char **argv)
{
//master
LxQt::Application app(argc, argv);
app.setQuitOnLastWindowClosed(false);
if (1 >= argc)
{
usage(QObject::tr("%1: no command to run provided!").arg(app_master));
return 1;
} else
{
//simple help check
std::string arg1(argv[1]);
if ("-h" == arg1 || "--help" == arg1)
{
usage();
return 0;
} else if ("-v" == arg1 || "--version" == arg1)
{
version();
return 0;
}
//any other arguments we simply forward to sudo
}
QStringList args = app.arguments();
//check for provided command is done before
args.removeAt(0);
PasswordDialog dlg(args);
dlg.setModal(true);
app.setActiveWindow(&dlg);
QScopedPointer<QProcess> sudo{new QProcess};
QObject::connect(&dlg, &QDialog::finished, [&sudo, &dlg] (int result)
{
if (QDialog::Accepted == result)
{
sudo->write(QByteArray{}.append(dlg.password().append('\n')));
} else
{
sudo->terminate();
if (!sudo->waitForFinished(1000))
sudo->kill();
}
});
//start background process -> sudo
sudo->setProcessChannelMode(QProcess::ForwardedOutputChannel);
sudo->setReadChannel(QProcess::StandardError);
QString last_line;
int ret;
QObject::connect(sudo.data(), static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)
, [&app, &ret, &last_line, &dlg] (int exitCode, QProcess::ExitStatus exitStatus)
{
ret = QProcess::NormalExit == exitStatus ? exitCode : 255;
if (0 != ret && last_line.startsWith(QStringLiteral("%1:").arg(sudo_prog)))
QMessageBox(QMessageBox::Critical, dlg.windowTitle()
, QObject::tr("Child '%1' process failed!\n%2").arg(sudo_prog).arg(last_line), QMessageBox::Ok).exec();
app.quit();
});
QObject::connect(sudo.data(), &QProcess::readyReadStandardError, [&sudo, &dlg, &last_line]
{
QByteArray err = sudo->readAllStandardError();
if (sudo_pwd_prompt == err.constData())
{
dlg.show();
return;
}
QTextStream{stderr, QIODevice::WriteOnly} << err;
int nl_pos = err.lastIndexOf('\n');
if (-1 == nl_pos)
last_line += err;
else
{
if (err.endsWith('\n'))
err.remove(err.size() - 1, 1);
nl_pos = err.lastIndexOf('\n');
if (-1 != nl_pos)
err.remove(0, nl_pos + 1);
last_line = err;
}
});
//forward all stdin to child
QTextStream std_in{stdin, QIODevice::ReadOnly};
QSocketNotifier stdin_watcher{0/*stdin*/, QSocketNotifier::Read};
QObject::connect(&stdin_watcher, &QSocketNotifier::activated, [&std_in, &sudo]
{
QString line{std_in.readLine()};
if (!std_in.atEnd())
line += QLatin1Char('\n');
sudo->write(line.toStdString().c_str());
if (std_in.atEnd())
sudo->closeWriteChannel();
});
sudo->start(sudo_prog, QStringList() << QStringLiteral("-S")
<< QStringLiteral("-p") << sudo_pwd_prompt
<< args);
app.exec();
sudo->waitForFinished(-1);
return ret;
}
int main(int argc, char **argv)
{
// Quit gracefully
::signal(SIGALRM, termSignalHandler);
::signal(SIGTERM, termSignalHandler);
::signal(SIGINT, termSignalHandler);
::signal(SIGQUIT, termSignalHandler);
::signal(SIGHUP, termSignalHandler);
::signal(SIGSTOP, termSignalHandler);
::signal(SIGTSTP, termSignalHandler);
return master(argc, argv);
}

@ -0,0 +1,17 @@
.TH lxqt-sudo 1 "" "" "LXQt\ Module"
.SH NAME
\fBlxqt-sudo\fR \- execute a command as privileged user
.SH SYNOPSIS
\fBlxqt-sudo\fR \fIcommand\fR [\fIarguments\fR]
.SH DESCRIPTION
\fBlxqt-sudo\fR is a graphical QT frontend for plain \fBsudo(8)\fR (for requesting optional password in GUI fashion).
.br
When invoked it simply spawns child \fIsudo\fR process with requested \fIcommand\fR (and \fIarguments\fR). If \fIsudo\fR requests user's password,
the GUI password dialog is shown and (after submit) the password is provided to \fIsudo\fR.
.SH "REPORTING BUGS"
Report bugs to https://github.com/lxde/lxqt/issues
.SH "SEE ALSO"
\fBsudo(8)\fR
.SH AUTHOR
This manual page was created by \fBPalo Kisa\fR \fI<palo.kisa@gmail.com>\fR
for \fBLXQt\fR project.

@ -0,0 +1,62 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://lxqt.org
*
* Copyright: 2015 LXQt team
* Authors:
* Palo Kisa <palo.kisa@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#include "passworddialog.h"
#include "ui_passworddialog.h"
PasswordDialog::PasswordDialog(QStringList argv
, QWidget * parent/* = 0*/
, Qt::WindowFlags f/* = 0*/)
: QDialog(parent, f)
, ui(new Ui::PasswordDialog)
{
ui->setupUi(this);
ui->commandL->setText(argv.join(QStringLiteral(" ")));
QString cmd;
if (0 < argv.size())
cmd = argv[0];
ui->descriptionL->setText(tr("<b>%1</b> needs administrative privileges.\nPlease enter your password.").arg(cmd));
ui->iconL->setPixmap(QIcon::fromTheme("dialog-password").pixmap(64, 64));
setWindowIcon(QIcon::fromTheme("security-high"));
}
PasswordDialog::~PasswordDialog()
{
}
void PasswordDialog::showEvent(QShowEvent * event)
{
ui->errorL->setText(tr("Attempt #%1").arg(++mAttempt));
return QDialog::showEvent(event);
}
QString PasswordDialog::password() const
{
return ui->passwordLE->text();
}

@ -0,0 +1,59 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://lxqt.org
*
* Copyright: 2015 LXQt team
* Authors:
* Palo Kisa <palo.kisa@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef PASSWORDDIALOG_H
#define PASSWORDDIALOG_H
#include <QDialog>
namespace Ui {
class PasswordDialog;
}
class Communication;
class QProcess;
class PasswordDialog : public QDialog
{
Q_OBJECT
public:
PasswordDialog(QStringList argv
, QWidget * parent = 0
, Qt::WindowFlags f = 0);
~PasswordDialog();
virtual void showEvent(QShowEvent * event) override;
QString password() const;
private:
QScopedPointer<Ui::PasswordDialog> ui;
int mAttempt = 0;
};
#endif // PASSWORDDIALOG_H

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PasswordDialog</class>
<widget class="QDialog" name="PasswordDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>200</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>LXQt sudo</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QLabel" name="iconL">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" alignment="Qt::AlignVCenter">
<widget class="QLabel" name="descriptionL">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="errorL">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="commandL">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="descCommandL">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Command:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="descPasswordL">
<property name="text">
<string>Password:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="passwordLE">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PasswordDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PasswordDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0">
<context>
<name>PasswordDialog</name>
<message>
<location filename="../passworddialog.ui" line="20"/>
<location filename="../build/ui_passworddialog.h" line="129"/>
<source>LXQt sudo</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../passworddialog.ui" line="77"/>
<location filename="../build/ui_passworddialog.h" line="134"/>
<source>Command:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="43"/>
<source>&lt;b&gt;%1&lt;/b&gt; needs administrative privileges.
Please enter your password.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="54"/>
<source>Attempt #%1</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<location filename="../main.cpp" line="57"/>
<source>Usage: %1 command [arguments...]
GUI frontend for %2
Arguments:
command Command to run.
arguments Optional arguments for command.
</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="69"/>
<source>%1 version %2
</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="80"/>
<source>%1: no command to run provided!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="131"/>
<source>Child &apos;%1&apos; process failed!
%2</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0">
<context>
<name>PasswordDialog</name>
<message>
<location filename="../passworddialog.ui" line="20"/>
<location filename="../build/ui_passworddialog.h" line="129"/>
<source>LXQt sudo</source>
<translation>LXQt sudo</translation>
</message>
<message>
<location filename="../passworddialog.ui" line="77"/>
<location filename="../build/ui_passworddialog.h" line="134"/>
<source>Command:</source>
<translation>Príkaz:</translation>
</message>
<message>
<location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source>
<translation>Heslo:</translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="43"/>
<source>&lt;b&gt;%1&lt;/b&gt; needs administrative privileges.
Please enter your password.</source>
<translation>&lt;b&gt;%1&lt;/b&gt; vyžaduje práva administrátora.
Prosím, zadajte svoje heslo.</translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="54"/>
<source>Attempt #%1</source>
<translation>Pokus č. %1</translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<location filename="../main.cpp" line="57"/>
<source>Usage: %1 command [arguments...]
GUI frontend for %2
Arguments:
command Command to run.
arguments Optional arguments for command.
</source>
<translation>Použitie: %1 command [arguments...]
GUI frontend pre %2
Parametre:
command Príkaz na spustenie.
arguments Parametre príkazu.
</translation>
</message>
<message>
<location filename="../main.cpp" line="69"/>
<source>%1 version %2
</source>
<translation>%1 verzia %2
</translation>
</message>
<message>
<location filename="../main.cpp" line="80"/>
<source>%1: no command to run provided!</source>
<translation>%1: žiaden príkaz na spustenie!</translation>
</message>
<message>
<location filename="../main.cpp" line="131"/>
<source>Child &apos;%1&apos; process failed!
%2</source>
<translation>Dcérsky &apos;%1&apos; process zlyhal!
%2</translation>
</message>
</context>
</TS>
Loading…
Cancel
Save