Compare commits

...

4 Commits

Author SHA1 Message Date
Alf Gaida
cb95c92327 Adding upstream version 0.9.0+20151029. 2015-10-31 11:16:51 +01:00
Alf Gaida
588579f00e Adding upstream version 0.9.0+20151024. 2015-10-24 14:29:06 +02:00
Alf Gaida
d286267068 Adding upstream version 0.9.0+20150908. 2015-09-23 00:02:08 +02:00
Alf Gaida
442af30319 Adding upstream version 0.9.0+20150831. 2015-09-04 01:22:16 +02:00
17 changed files with 934 additions and 200 deletions

1
.gitignore vendored
View File

@ -1 +0,0 @@
build

View File

@ -4,5 +4,5 @@ Upstream Authors:
Copyright: Copyright:
Copyright (c) 2015 LXQt team Copyright (c) 2015 LXQt team
License: LGPL-2.1 License: LGPL-2.1+
The full text of the licenses can be found in the 'COPYING' file. The full text of the licenses can be found in the 'COPYING' file.

View File

@ -16,12 +16,16 @@ find_package(lxqt REQUIRED QUIET)
include(LXQtCompilerSettings NO_POLICY_SCOPE) include(LXQtCompilerSettings NO_POLICY_SCOPE)
include(LXQtTranslate) include(LXQtTranslate)
set ( LINK_LXSU "lxsu")
set ( LINK_LXSUDO "lxsudo")
set ( HDRS set ( HDRS
passworddialog.h passworddialog.h
) )
set ( SRCS set ( SRCS
passworddialog.cpp passworddialog.cpp
sudo.cpp
main.cpp main.cpp
) )
@ -56,27 +60,48 @@ add_executable(lxqt-sudo
target_link_libraries(lxqt-sudo target_link_libraries(lxqt-sudo
Qt5::Widgets Qt5::Widgets
util
lxqt lxqt
) )
target_compile_definitions(lxqt-sudo target_compile_definitions(lxqt-sudo
PRIVATE "LXQTSUDO_SUDO=\"sudo\"" PRIVATE "LXQTSUDO_SUDO=\"sudo\""
PRIVATE "LXQTSUDO_SU=\"su\""
PRIVATE "LXQTSUDO=\"lxqt-sudo\"" PRIVATE "LXQTSUDO=\"lxqt-sudo\""
PRIVATE "LXQTSUDO_LXSU=\"${LINK_LXSU}\""
PRIVATE "LXQTSUDO_LXSUDO=\"${LINK_LXSUDO}\""
PRIVATE "LXQT_VERSION=\"${LXQT_VERSION}\"" PRIVATE "LXQT_VERSION=\"${LXQT_VERSION}\""
) )
add_custom_command(TARGET lxqt-sudo POST_BUILD
COMMAND ln -f -s lxqt-sudo "${LINK_LXSU}"
WORKING_DIRECTORY .
COMMENT "Creating ${LINK_LXSU} symlink"
)
add_custom_command(TARGET lxqt-sudo POST_BUILD
COMMAND ln -f -s lxqt-sudo "${LINK_LXSUDO}"
WORKING_DIRECTORY .
COMMENT "Creating ${LINK_LXSUDO} symlink"
)
install(TARGETS install(TARGETS
lxqt-sudo lxqt-sudo
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
COMPONENT Runtime COMPONENT Runtime
) )
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${LINK_LXSU}" "${CMAKE_CURRENT_BINARY_DIR}/${LINK_LXSUDO}"
DESTINATION "${CMAKE_INSTALL_BINDIR}"
COMPONENT Runtime
)
install(FILES install(FILES
${DESKTOP_FILES} ${DESKTOP_FILES}
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
COMPONENT Runtime COMPONENT Runtime
) )
install(FILES install(FILES
man/lxqt-sudo.1 man/lxqt-sudo.1 "man/${LINK_LXSU}.1" "man/${LINK_LXSUDO}.1"
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1" DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
COMPONENT Runtime COMPONENT Runtime
) )

149
main.cpp
View File

@ -26,151 +26,12 @@
* END_COMMON_COPYRIGHT_HEADER */ * END_COMMON_COPYRIGHT_HEADER */
#include <LXQt/Application> #include <LXQt/Application>
#include "passworddialog.h" #include "sudo.h"
#include <QFileInfo>
#include <QDir>
#include <QProcess>
#include <QTimer>
#include <QMessageBox>
#include <QSocketNotifier>
#include <sstream>
#include <QDebug>
const QString app_master{QStringLiteral(LXQTSUDO)};
const QString app_version{QStringLiteral(LXQT_VERSION)};
const QString sudo_prog{QStringLiteral(LXQTSUDO_SUDO)};
const QString sudo_pwd_prompt{QStringLiteral("Password:\n")};
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, true);
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) int main(int argc, char **argv)
{ {
return master(argc, argv); LXQt::Application app(argc, argv, true);
app.setQuitOnLastWindowClosed(false);
Sudo s;
return s.main();
} }

View File

@ -1,17 +1,32 @@
.TH lxqt-sudo 1 "" "" "LXQt\ Module" .TH lxqt-sudo 1 "" "" "LXQt\ Module"
.SH NAME .SH NAME
\fBlxqt-sudo\fR \- execute a command as privileged user \fBlxqt-sudo\fR, \fBlxsu\fR \- execute a command as privileged user
.SH SYNOPSIS .SH SYNOPSIS
\fBlxqt-sudo\fR \fIcommand\fR [\fIarguments\fR] \fBlxqt-sudo\fR \fIoption\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 .br
When invoked it simply spawns child \fIsudo\fR process with requested \fIcommand\fR (and \fIarguments\fR). If \fIsudo\fR requests user's password, \fBlxsu\fR [\fIoption\fR] [\fIcommand\fR [\fIarguments\fR]]
the GUI password dialog is shown and (after submit) the password is provided to \fIsudo\fR. .br
\fBlxsudo\fR [\fIoption\fR] [\fIcommand\fR [\fIarguments\fR]]
.SH DESCRIPTION
\fBlxqt-sudo\fR (and symlinks \fBlxsu\fR, \fBlxsudo\fR) is a graphical QT frontend for plain \fBsudo(8)\fR or \fBsu(1)\fR (for requesting optional password in GUI fashion).
.br
When invoked it simply spawns child \fIsudo\fR or \fIsu\fR process with requested \fIcommand\fR (and optional \fIarguments\fR). If \fIsudo\fR/\fIsu\fR requests user's password,
the GUI password dialog is shown and (after submit) the password is provided to backend.
.br
.SH OPTIONS
\fBoption\fR is one of:
.br
-h|--help Print help.
.br
-v|--version Print version information.
.br
-s|--su Use \fIsu\fR as backend (default for \fBlxqt-sudo\fR & \fBlxsudo\fR is \fIsudo\fR, for \fBlxsu\fR is \fIsu\fR).
.br
-d|--sudo Use \fIsudo\fR as backend (default for \fBlxqt-sudo\fR & \fBlxsudo\fR is \fIsudo\fR, for \fBlxsu\fR is \fIsu\fR).
.SH "REPORTING BUGS" .SH "REPORTING BUGS"
Report bugs to https://github.com/lxde/lxqt/issues Report bugs to https://github.com/lxde/lxqt/issues
.SH "SEE ALSO" .SH "SEE ALSO"
\fBsudo(8)\fR \fBsudo(8)\fR \fBsu(1)\fR
.SH AUTHOR .SH AUTHOR
This manual page was created by \fBPalo Kisa\fR \fI<palo.kisa@gmail.com>\fR This manual page was created by \fBPalo Kisa\fR \fI<palo.kisa@gmail.com>\fR
for \fBLXQt\fR project. for \fBLXQt\fR project.

1
man/lxsu.1 Symbolic link
View File

@ -0,0 +1 @@
lxqt-sudo.1

1
man/lxsudo.1 Symbolic link
View File

@ -0,0 +1 @@
lxqt-sudo.1

View File

@ -34,9 +34,6 @@ namespace Ui {
class PasswordDialog; class PasswordDialog;
} }
class Communication;
class QProcess;
class PasswordDialog : public QDialog class PasswordDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT

312
sudo.cpp Normal file
View File

@ -0,0 +1,312 @@
/* 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 "sudo.h"
#include "passworddialog.h"
#include <LXQt/Application>
#include <QTextStream>
#include <QMessageBox>
#include <QFileInfo>
#include <QSocketNotifier>
#include <QDebug>
#include <QThread>
#include <pty.h>
#include <unistd.h>
#include <memory>
#include <csignal>
#include <sys/wait.h>
#include <fcntl.h>
namespace
{
const QString app_master{QStringLiteral(LXQTSUDO)};
const QString app_version{QStringLiteral(LXQT_VERSION)};
const QString app_lxsu{QStringLiteral(LXQTSUDO_LXSU)};
const QString app_lxsudo{QStringLiteral(LXQTSUDO_LXSUDO)};
const QString su_prog{QStringLiteral(LXQTSUDO_SU)};
const QString sudo_prog{QStringLiteral(LXQTSUDO_SUDO)};
const QString pwd_prompt_end{QStringLiteral(": ")};
const QChar nl{QLatin1Char('\n')};
void usage(QString const & err = QString())
{
if (!err.isEmpty())
QTextStream(stderr) << err << '\n';
QTextStream(stdout)
<< QObject::tr("Usage: %1 option [command [arguments...]]\n\n"
"GUI frontend for %2/%3\n\n"
"Arguments:\n"
" option:\n"
" -h|--help Print this help.\n"
" -v|--version Print version information.\n"
" -s|--su Use %3(1) as backend.\n"
" -d|--sudo Use %2(8) as backend.\n"
" command Command to run.\n"
" arguments Optional arguments for command.\n\n").arg(app_master).arg(sudo_prog).arg(su_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);
}
inline void env_workarounds()
{
//cleanup environment
//pcmanfm-qt will not start if the DBUS_SESSION_BUS_ADDRESS is preserved
unsetenv("DBUS_SESSION_BUS_ADDRESS");
}
}
Sudo::Sudo()
: mArgs{lxqtApp->arguments()}
, mBackend{BACK_NONE}
{
QString cmd = QFileInfo(mArgs[0]).fileName();
mArgs.removeAt(0);
if (app_lxsu == cmd)
mBackend = BACK_SU;
else if (app_lxsudo == cmd || app_master == cmd)
mBackend = BACK_SUDO;
}
Sudo::~Sudo()
{
}
int Sudo::main()
{
if (0 < mArgs.size())
{
//simple option check
QString const & arg1 = mArgs[0];
if ("-h" == arg1 || "--help" == arg1)
{
usage();
return 0;
} else if ("-v" == arg1 || "--version" == arg1)
{
version();
return 0;
} else if ("-s" == arg1 || "--su" == arg1)
{
mBackend = BACK_SU;
mArgs.removeAt(0);
} else if ("-d" == arg1 || "--sudo" == arg1)
{
mBackend = BACK_SUDO;
mArgs.removeAt(0);
}
}
//any other arguments we simply forward to su/sudo
if (1 > mArgs.size())
{
usage(tr("%1: no command to run provided!").arg(app_master));
return 1;
}
if (BACK_NONE == mBackend)
{
//we were invoked through unknown link (or renamed binary)
usage(tr("%1: no backend chosen!").arg(app_master));
return 1;
} else if (BACK_SU == mBackend && 1 < mArgs.size())
{
QString cmd = mArgs.replaceInStrings(QRegExp(QStringLiteral("^(.*)$")), "'\\1'").join(QStringLiteral(" "));
QTextStream(stderr) << tr("%1: warning - got multiple arguments for %2 backend, squashing into one: %3")
.arg(app_master).arg(su_prog).arg(cmd);
mArgs.erase(++mArgs.begin(), mArgs.end());
mArgs[0] = std::move(cmd);
}
mDlg.reset(new PasswordDialog{mArgs});
mDlg->setModal(true);
lxqtApp->setActiveWindow(mDlg.data());
mChildPid = forkpty(&mPwdFd, nullptr, nullptr, nullptr);
if (0 == mChildPid)
child(); //never returns
else if (-1 == mChildPid)
QMessageBox(QMessageBox::Critical, mDlg->windowTitle()
, tr("Failed to fork: %1").arg(strerror(errno)), QMessageBox::Ok).exec();
else
return parent();
return 1;
}
void Sudo::child()
{
int params_cnt = 2 //1. su/sudo & last nullptr
+ 1 //-c for su | -E for sudo
+ mArgs.size();
std::unique_ptr<char const *[]> params{new char const *[params_cnt]};
const char ** param_arg = params.get() + 1;
std::string program;
if (BACK_SU == mBackend)
{
program = su_prog.toStdString();
*(param_arg++) = "-c"; //run command
} else
{
program = sudo_prog.toStdString();
*(param_arg++) = "-E"; //preserve environment
}
params[0] = program.c_str();
std::vector<std::string> arguments;
for (const auto & a : mArgs)
arguments.push_back(a.toStdString());
for (const auto & a : arguments)
*(param_arg++) = a.c_str();
*param_arg = nullptr;
env_workarounds();
setsid(); //session leader
execvp(params[0], const_cast<char **>(params.get()));
//exec never returns in case of success
QTextStream{stderr, QIODevice::WriteOnly} << tr("%1: Failed to exec '%2': %3\n").arg(app_master).arg(params[0]).arg(strerror(errno));
exit(1);
}
void Sudo::stopChild()
{
close(mPwdFd);
kill(mChildPid, SIGINT);
int res, status;
for (int cnt = 10; 0 == (res = waitpid(mChildPid, &status, WNOHANG)) && 0 < cnt; --cnt)
QThread::msleep(100);
if (0 == res)
{
kill(mChildPid, SIGKILL);
mRet = 1;
} else
{
mRet = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
}
mChildPid = -1;
}
int Sudo::parent()
{
//set the FD as non-blocking
if (0 != fcntl(mPwdFd, F_SETFL, O_NONBLOCK))
{
QMessageBox(QMessageBox::Critical, mDlg->windowTitle()
, tr("Failed to set non-block: %1").arg(strerror(errno)), QMessageBox::Ok).exec();
return 1;
}
FILE * pwd_f = fdopen(mPwdFd, "r+");
if (nullptr == pwd_f)
{
QMessageBox(QMessageBox::Critical, mDlg->windowTitle()
, tr("Failed to fdopen: %1").arg(strerror(errno)), QMessageBox::Ok).exec();
return 1;
}
QTextStream child_str{pwd_f};
QObject::connect(mDlg.data(), &QDialog::finished, [&] (int result)
{
if (QDialog::Accepted == result)
{
child_str << mDlg->password().append(nl);
child_str.flush();
} else
{
stopChild();
lxqtApp->quit();
}
});
QString last_line;
QScopedPointer<QSocketNotifier> pwd_watcher{new QSocketNotifier{mPwdFd, QSocketNotifier::Read}};
QObject::connect(pwd_watcher.data(), &QSocketNotifier::activated, [&]
{
QString line = child_str.readAll();
if (line.isEmpty())
{
pwd_watcher.reset(nullptr);
QString const & prog = BACK_SU == mBackend ? su_prog : sudo_prog;
if (last_line.startsWith(QStringLiteral("%1:").arg(prog)))
{
pwd_watcher.reset(nullptr); //stop the notifications events
stopChild();
QMessageBox(QMessageBox::Critical, mDlg->windowTitle()
, tr("Child '%1' process failed!\n%2").arg(prog).arg(last_line), QMessageBox::Ok).exec();
}
lxqtApp->quit();
} else
{
if (line.endsWith(pwd_prompt_end))
{
//if now echo is turned off, su/sudo requests password
struct termios tios;
//loop to be sure we don't miss the flag (we can afford such small delay in "normal" output processing)
for (size_t cnt = 10; 0 < cnt && 0 == tcgetattr(mPwdFd, &tios) && (ECHO & tios.c_lflag); --cnt)
QThread::msleep(10);
if (!(ECHO & tios.c_lflag))
{
mDlg->show();
return;
}
}
QTextStream{stderr, QIODevice::WriteOnly} << line;
//assuming text oriented output
QStringList lines = line.split(nl, QString::SkipEmptyParts);
last_line = lines.isEmpty() ? QString() : lines.back();
}
});
lxqtApp->exec();
if (0 < mChildPid)
{
int res, status;
res = waitpid(mChildPid, &status, 0);
mRet = (mChildPid == res && WIFEXITED(status)) ? WEXITSTATUS(status) : 1;
}
return mRet;
}

71
sudo.h Normal file
View File

@ -0,0 +1,71 @@
/* 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 SUDO_H
#define SUDO_H
#include <QObject>
#include <QScopedPointer>
#include <QStringList>
class PasswordDialog;
class Sudo : public QObject
{
Q_OBJECT
public:
enum backend_t
{
BACK_NONE
, BACK_SUDO
, BACK_SU
};
public:
Sudo();
~Sudo();
int main();
private:
//parent methods
int parent();
void stopChild();
//child methods
void child();
private:
QScopedPointer<PasswordDialog> mDlg;
QStringList mArgs;
backend_t mBackend;
int mChildPid;
int mPwdFd;
int mRet;
};
#endif //SUDO_H

View File

@ -1,23 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS> <!DOCTYPE TS>
<TS version="2.0"> <TS version="2.1">
<context> <context>
<name>PasswordDialog</name> <name>PasswordDialog</name>
<message> <message>
<location filename="../passworddialog.ui" line="20"/> <location filename="../passworddialog.ui" line="20"/>
<location filename="../build/ui_passworddialog.h" line="129"/>
<source>LXQt sudo</source> <source>LXQt sudo</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../passworddialog.ui" line="77"/> <location filename="../passworddialog.ui" line="77"/>
<location filename="../build/ui_passworddialog.h" line="134"/>
<source>Command:</source> <source>Command:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../passworddialog.ui" line="84"/> <location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source> <source>Password:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -36,12 +33,17 @@ Please enter your password.</source>
<context> <context>
<name>QObject</name> <name>QObject</name>
<message> <message>
<location filename="../main.cpp" line="57"/> <location filename="../sudo.cpp" line="63"/>
<source>Usage: %1 command [arguments...] <source>Usage: %1 option [command [arguments...]]
GUI frontend for %2 GUI frontend for %2/%3
Arguments: Arguments:
option:
-h|--help Print this help.
-v|--version Print version information.
-s|--su Use %3(1) as backend.
-d|--sudo Use %2(8) as backend.
command Command to run. command Command to run.
arguments Optional arguments for command. arguments Optional arguments for command.
@ -49,18 +51,52 @@ Arguments:
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="69"/> <location filename="../sudo.cpp" line="80"/>
<source>%1 version %2 <source>%1 version %2
</source> </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context>
<context>
<name>Sudo</name>
<message> <message>
<location filename="../main.cpp" line="80"/> <location filename="../sudo.cpp" line="128"/>
<source>%1: no command to run provided!</source> <source>%1: no command to run provided!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="131"/> <location filename="../sudo.cpp" line="135"/>
<source>%1: no backend chosen!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sudo.cpp" line="140"/>
<source>%1: warning - got multiple arguments for %2 backend, squashing into one: %3</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sudo.cpp" line="155"/>
<source>Failed to fork: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sudo.cpp" line="193"/>
<source>%1: Failed to exec &apos;%2&apos;: %3
</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sudo.cpp" line="222"/>
<source>Failed to set non-block: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sudo.cpp" line="230"/>
<source>Failed to fdopen: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sudo.cpp" line="263"/>
<source>Child &apos;%1&apos; process failed! <source>Child &apos;%1&apos; process failed!
%2</source> %2</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>

View File

@ -1,23 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS> <!DOCTYPE TS>
<TS version="2.0"> <TS version="2.1" language="de">
<context> <context>
<name>PasswordDialog</name> <name>PasswordDialog</name>
<message> <message>
<location filename="../passworddialog.ui" line="20"/> <location filename="../passworddialog.ui" line="20"/>
<location filename="../build/ui_passworddialog.h" line="129"/>
<source>LXQt sudo</source> <source>LXQt sudo</source>
<translation>LXQt sudo</translation> <translation>LXQt sudo</translation>
</message> </message>
<message> <message>
<location filename="../passworddialog.ui" line="77"/> <location filename="../passworddialog.ui" line="77"/>
<location filename="../build/ui_passworddialog.h" line="134"/>
<source>Command:</source> <source>Command:</source>
<translation>Befehl:</translation> <translation>Befehl:</translation>
</message> </message>
<message> <message>
<location filename="../passworddialog.ui" line="84"/> <location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source> <source>Password:</source>
<translation>Kennwort:</translation> <translation>Kennwort:</translation>
</message> </message>
@ -37,43 +34,88 @@ Bitte Kennwort eingeben.</translation>
<context> <context>
<name>QObject</name> <name>QObject</name>
<message> <message>
<location filename="../main.cpp" line="57"/> <location filename="../sudo.cpp" line="63"/>
<source>Usage: %1 command [arguments...] <source>Usage: %1 option [command [arguments...]]
GUI frontend for %2 GUI frontend for %2/%3
Arguments: Arguments:
option:
-h|--help Print this help.
-v|--version Print version information.
-s|--su Use %3(1) as backend.
-d|--sudo Use %2(8) as backend.
command Command to run. command Command to run.
arguments Optional arguments for command. arguments Optional arguments for command.
</source> </source>
<translation>Verwendung: %1 command [arguments...] <translation>Verwendung: %1 Option [Befehl [Argumente...]]
graphische Benutzeroberfläche für %2 Graphische Benutzeroberfläche für %2/%3
Argumente: Argumente:
command auszuführender Befehl Option:
arguments Argumente zum auszuführenden Befehl -h|--help Gibt diese Hilfe aus.
-v|--version Ausgabe der Versionsinformation.
-s|--su Verwendet %3(1) als Backend.
-d|--sudo Verwendet %2(8) als Backend.
Befehl Auszuführender Befehl.
Argumente Argumente zum auszuführenden Befehl.
</translation> </translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="69"/> <location filename="../sudo.cpp" line="80"/>
<source>%1 version %2 <source>%1 version %2
</source> </source>
<translation>%1 Version %2 <translation>%1 Version %2
</translation> </translation>
</message> </message>
</context>
<context>
<name>Sudo</name>
<message> <message>
<location filename="../main.cpp" line="80"/> <location filename="../sudo.cpp" line="128"/>
<source>%1: no command to run provided!</source> <source>%1: no command to run provided!</source>
<translation>%1: kein auszuführender Befehl angegeben!</translation> <translation>%1: kein auszuführender Befehl angegeben!</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="131"/> <location filename="../sudo.cpp" line="135"/>
<source>%1: no backend chosen!</source>
<translation>%1: kein Backend gewählt!</translation>
</message>
<message>
<location filename="../sudo.cpp" line="140"/>
<source>%1: warning - got multiple arguments for %2 backend, squashing into one: %3</source>
<translation>%1: Warnung - mehrere Argumente für Backend %2 erhalten. %3 wird verwendet</translation>
</message>
<message>
<location filename="../sudo.cpp" line="155"/>
<source>Failed to fork: %1</source>
<translation>Abspalten des Prozesses fehlgeschlagen: %1</translation>
</message>
<message>
<location filename="../sudo.cpp" line="193"/>
<source>%1: Failed to exec &apos;%2&apos;: %3
</source>
<translation>%1: Ausführen von &apos;%2&apos; fehlgeschlagen:
%3</translation>
</message>
<message>
<location filename="../sudo.cpp" line="222"/>
<source>Failed to set non-block: %1</source>
<translation>Das Setzen von der Option O_NONBLOCK schlug fehl: %1</translation>
</message>
<message>
<location filename="../sudo.cpp" line="230"/>
<source>Failed to fdopen: %1</source>
<translation>Das Öffnen schlug fehl: %1</translation>
</message>
<message>
<location filename="../sudo.cpp" line="263"/>
<source>Child &apos;%1&apos; process failed! <source>Child &apos;%1&apos; process failed!
%2</source> %2</source>
<translation>nachgeordneter Prozess &apos;%1&apos; ist fehlgeschlagen! <translation>Nachgeordneter Prozess &apos;%1&apos; ist fehlgeschlagen!
%2</translation> %2</translation>
</message> </message>
</context> </context>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="el">
<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>Εντολή:</translation>
</message>
<message>
<location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source>
<translation>Κωδικός πρόσβασης:</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; απαιτεί προνόμια διαχειριστή.
Παρακαλώ εισαγάγετε τον κωδικό πρόσβασης.</translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="54"/>
<source>Attempt #%1</source>
<translation>Προσπάθεια #%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>Χρήση: %1 εντολή [ορίσματα...]
Περιβάλλον συστήματος υποστήριξης του %2
Ορίσματα:
εντολή Η εντολή προς εκτέλεση.
ορίσματα Προαιρετικά ορίσματα για την εντολή.
</translation>
</message>
<message>
<location filename="../main.cpp" line="69"/>
<source>%1 version %2
</source>
<translation>%1 έκδοση %2
</translation>
</message>
<message>
<location filename="../main.cpp" line="80"/>
<source>%1: no command to run provided!</source>
<translation>%1: δεν παρείχατε κάποια εντολή προς εκτέλεση!</translation>
</message>
<message>
<location filename="../main.cpp" line="131"/>
<source>Child &apos;%1&apos; process failed!
%2</source>
<translation>Η θυγατρική διεργασία «%1» απέτυχε!
%2</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="it">
<context>
<name>Communication</name>
<message>
<location filename="../communication.cpp" line="85"/>
<source>%1: Communication - unable to create shared memory(%2B), </source>
<translation>%1: Comunicazione - non è stato possibile creare memoria condivisa(%2B), </translation>
</message>
<message>
<location filename="../communication.cpp" line="183"/>
<source>%1: Communication - password is too long(%2) for aquired shared memory(%3), has to be cut-off...
</source>
<translation>%1: Comunicazione - password troppo lunga(%2) per acquisire memoria condivisa(%3) deve essere accorciata...
</translation>
</message>
</context>
<context>
<name>PasswordDialog</name>
<message>
<location filename="../passworddialog.ui" line="20"/>
<location filename="../build/ui_passworddialog.h" line="129"/>
<source>LXQt sudo</source>
<translation></translation>
</message>
<message>
<location filename="../passworddialog.ui" line="77"/>
<location filename="../build/ui_passworddialog.h" line="134"/>
<source>Command:</source>
<translation>Comando:</translation>
</message>
<message>
<location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source>
<translation></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; richiede privilegi di amministratore.
Per favore inserire la password.</translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="53"/>
<source>Attempt #%1</source>
<translation>Tentativo #%1</translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<location filename="../main.cpp" line="58"/>
<source>Usage: %1 command [arguments...]
GUI frontend for %2
Arguments:
command Command to run.
arguments Optional arguments for command.
</source>
<translation>Uso: %1 comando [argomenti...]
Frontend grafico per %2
Argomenti:
comando Comando da eseguire.
argomenti Argomenti opzionali per il comando.
</translation>
</message>
<message>
<location filename="../main.cpp" line="70"/>
<source>%1 version %2
</source>
<translation>%1 versione %2
</translation>
</message>
<message>
<location filename="../main.cpp" line="81"/>
<source>%1: no command to run provided!</source>
<translation>%1: non è stato immesso nessun comando da eseguire!</translation>
</message>
<message>
<location filename="../main.cpp" line="156"/>
<source>Child &apos;%1&apos; process failed!
%2</source>
<translation>Sottoprocesso %1 fallito!
%2</translation>
</message>
</context>
</TS>

View File

@ -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>Komenda:</translation>
</message>
<message>
<location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source>
<translation>Hasło:</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; potrzebuje uprawnień administratora.
Proszę wprowadź hasło.</translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="54"/>
<source>Attempt #%1</source>
<translation>Próba #%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>Sposób użycia: %1 komenda [argumenty...]
Graficzna nakładka na %2
Argumenty:
komenda Komenda do wykonania.
argumenty Opcjonalne argumenty dla komendy.
</translation>
</message>
<message>
<location filename="../main.cpp" line="69"/>
<source>%1 version %2
</source>
<translation>%1 wersja %2
</translation>
</message>
<message>
<location filename="../main.cpp" line="80"/>
<source>%1: no command to run provided!</source>
<translation>%1: nie podano komendy do wykonania!</translation>
</message>
<message>
<location filename="../main.cpp" line="131"/>
<source>Child &apos;%1&apos; process failed!
%2</source>
<translation>Wykonanie procesu &apos;%1&apos; nie powiodło się!
%2</translation>
</message>
</context>
</TS>

View File

@ -1,23 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS> <!DOCTYPE TS>
<TS version="2.0"> <TS version="2.1" language="sk">
<context> <context>
<name>PasswordDialog</name> <name>PasswordDialog</name>
<message> <message>
<location filename="../passworddialog.ui" line="20"/> <location filename="../passworddialog.ui" line="20"/>
<location filename="../build/ui_passworddialog.h" line="129"/>
<source>LXQt sudo</source> <source>LXQt sudo</source>
<translation>LXQt sudo</translation> <translation>LXQt sudo</translation>
</message> </message>
<message> <message>
<location filename="../passworddialog.ui" line="77"/> <location filename="../passworddialog.ui" line="77"/>
<location filename="../build/ui_passworddialog.h" line="134"/>
<source>Command:</source> <source>Command:</source>
<translation>Príkaz:</translation> <translation>Príkaz:</translation>
</message> </message>
<message> <message>
<location filename="../passworddialog.ui" line="84"/> <location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source> <source>Password:</source>
<translation>Heslo:</translation> <translation>Heslo:</translation>
</message> </message>
@ -37,40 +34,84 @@ Prosím, zadajte svoje heslo.</translation>
<context> <context>
<name>QObject</name> <name>QObject</name>
<message> <message>
<location filename="../main.cpp" line="57"/> <location filename="../sudo.cpp" line="63"/>
<source>Usage: %1 command [arguments...] <source>Usage: %1 option [command [arguments...]]
GUI frontend for %2 GUI frontend for %2/%3
Arguments: Arguments:
option:
-h|--help Print this help.
-v|--version Print version information.
-s|--su Use %3(1) as backend.
-d|--sudo Use %2(8) as backend.
command Command to run. command Command to run.
arguments Optional arguments for command. arguments Optional arguments for command.
</source> </source>
<translation>Použitie: %1 command [arguments...] <translation>Použitie: %1 option [command [arguments...]]
GUI frontend pre %2 GUI frontend pre %2/%3
Parametre: Parametre:
option:
-h|--help Zobraziť pomoc.
-v|--version Zobraziť verziu.
-s|--su Použiť %3(1) ako backend.
-d|--sudo Použíť %2(8) ako backend.
command Príkaz na spustenie. command Príkaz na spustenie.
arguments Parametre príkazu. arguments Parametre príkazu.
</translation> </translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="69"/> <location filename="../sudo.cpp" line="80"/>
<source>%1 version %2 <source>%1 version %2
</source> </source>
<translation>%1 verzia %2 <translation>%1 verzia %2
</translation> </translation>
</message> </message>
</context>
<context>
<name>Sudo</name>
<message> <message>
<location filename="../main.cpp" line="80"/> <location filename="../sudo.cpp" line="128"/>
<source>%1: no command to run provided!</source> <source>%1: no command to run provided!</source>
<translation>%1: žiaden príkaz na spustenie!</translation> <translation>%1: žiaden príkaz na spustenie!</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="131"/> <location filename="../sudo.cpp" line="135"/>
<source>%1: no backend chosen!</source>
<translation>%1: nevybratý backend!</translation>
</message>
<message>
<location filename="../sudo.cpp" line="140"/>
<source>%1: warning - got multiple arguments for %2 backend, squashing into one: %3</source>
<translation>%1: upozornenie - zadaných viacero parametrov pre %2 backend, zlúčené do jedného: %3</translation>
</message>
<message>
<location filename="../sudo.cpp" line="155"/>
<source>Failed to fork: %1</source>
<translation>Zlyhal fork: %1</translation>
</message>
<message>
<location filename="../sudo.cpp" line="193"/>
<source>%1: Failed to exec &apos;%2&apos;: %3
</source>
<translation>%1: Zlyhal exec &apos;%2&apos;: %3</translation>
</message>
<message>
<location filename="../sudo.cpp" line="222"/>
<source>Failed to set non-block: %1</source>
<translation>Zlyhalo nastavenie non-block: %1</translation>
</message>
<message>
<location filename="../sudo.cpp" line="230"/>
<source>Failed to fdopen: %1</source>
<translation>Zlyhal fdopen: %1</translation>
</message>
<message>
<location filename="../sudo.cpp" line="263"/>
<source>Child &apos;%1&apos; process failed! <source>Child &apos;%1&apos; process failed!
%2</source> %2</source>
<translation>Dcérsky &apos;%1&apos; process zlyhal! <translation>Dcérsky &apos;%1&apos; process zlyhal!

View File

@ -0,0 +1,79 @@
<?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></translation>
</message>
<message>
<location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source>
<translation></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;
</translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="54"/>
<source>Attempt #%1</source>
<translation> %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>%1 [...]
%2
</translation>
</message>
<message>
<location filename="../main.cpp" line="69"/>
<source>%1 version %2
</source>
<translation>%1 %s</translation>
</message>
<message>
<location filename="../main.cpp" line="80"/>
<source>%1: no command to run provided!</source>
<translation>%1</translation>
</message>
<message>
<location filename="../main.cpp" line="131"/>
<source>Child &apos;%1&apos; process failed!
%2</source>
<translation>&apos;%1&apos;
%2</translation>
</message>
</context>
</TS>