aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/function/gpg/GpgCommandExecutor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/function/gpg/GpgCommandExecutor.cpp')
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp190
1 files changed, 127 insertions, 63 deletions
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index dd8a500e..72988a55 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -41,26 +41,25 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
-> Thread::Task * {
const auto &cmd = context.cmd;
const auto &arguments = context.arguments;
- const auto &interact_function = context.int_func;
- const auto &cmd_executor_callback = context.cb_func;
+ const auto &int_func = context.int_func;
+ const auto &cb = context.cb_func;
- Thread::Task::TaskCallback result_callback =
- [cmd](int /*rtn*/, const DataObjectPtr &data_object) {
- LOG_D() << "data object args count of cmd executor result callback:"
- << data_object->GetObjectSize();
+ Thread::Task::TaskCallback result_callback = [cmd](int /*rtn*/,
+ const DataObjectPtr &obj) {
+ LOG_D() << "data object args count of cmd executor result callback:"
+ << obj->GetObjectSize();
- if (!data_object->Check<int, QString, GpgCommandExecutorCallback>()) {
- FLOG_W("data object checking failed");
- return;
- }
+ if (!obj->Check<int, QByteArray, GpgCommandExecutorCallback>()) {
+ FLOG_W("data object checking failed");
+ return;
+ }
- auto exit_code = ExtractParams<int>(data_object, 0);
- auto process_stdout = ExtractParams<QString>(data_object, 1);
- auto callback =
- ExtractParams<GpgCommandExecutorCallback>(data_object, 2);
+ auto code = ExtractParams<int>(obj, 0);
+ auto out = ExtractParams<QByteArray>(obj, 1);
+ auto cb = ExtractParams<GpgCommandExecutorCallback>(obj, 2);
- callback(exit_code, process_stdout, {});
- };
+ cb(code, out, {});
+ };
Thread::Task::TaskRunnable runner =
[](const DataObjectPtr &data_object) -> int {
@@ -82,71 +81,67 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
const QString joined_argument = arguments.join(" ");
// create process
- auto *cmd_process = new QProcess();
+ auto *pcs = new QProcess();
// move to current thread
//
- cmd_process->moveToThread(QThread::currentThread());
+ pcs->moveToThread(QThread::currentThread());
// set process channel mode
// this is to make sure we can get all output from stdout and stderr
- cmd_process->setProcessChannelMode(QProcess::MergedChannels);
- cmd_process->setProgram(cmd);
+ pcs->setProcessChannelMode(QProcess::MergedChannels);
+ pcs->setProgram(cmd);
// set arguments
QStringList q_arguments;
for (const auto &argument : arguments) {
q_arguments.append(argument);
}
- cmd_process->setArguments(q_arguments);
+ pcs->setArguments(q_arguments);
+ QObject::connect(pcs, &QProcess::started, [cmd, joined_argument]() -> void {
+ LOG_D() << "\n== Process Execute Started ==\nCommand: " << cmd
+ << "\nArguments: " << joined_argument
+ << " \n========================";
+ });
+ QObject::connect(pcs, &QProcess::readyReadStandardOutput,
+ [interact_func, pcs]() { interact_func(pcs); });
QObject::connect(
- cmd_process, &QProcess::started, [cmd, joined_argument]() -> void {
- LOG_D() << "\n== Process Execute Started ==\nCommand: " << cmd
- << "\nArguments: " << joined_argument
- << " \n========================";
+ pcs, &QProcess::errorOccurred, [=](QProcess::ProcessError error) {
+ LOG_W() << "caught error while executing command: " << cmd
+ << joined_argument << ", error:" << error;
});
- QObject::connect(
- cmd_process, &QProcess::readyReadStandardOutput,
- [interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- LOG_W()
- << "caught error while executing command: " << cmd
- << joined_argument << ", error:" << error;
- });
LOG_D() << "\n== Process Execute Ready ==\nCommand: " << cmd
<< "\nArguments: " << joined_argument
<< "\n========================";
- cmd_process->start();
- cmd_process->waitForFinished();
+ pcs->start();
+ pcs->waitForFinished();
- QString process_stdout = cmd_process->readAllStandardOutput();
- int exit_code = cmd_process->exitCode();
+ auto out = pcs->readAllStandardOutput();
+ auto code = pcs->exitCode();
LOG_D() << "\n==== Process Execution Summary ====\n"
<< "Command: " << cmd << "\n"
<< "Arguments: " << joined_argument << "\n"
- << "Exit Code: " << exit_code << "\n"
+ << "Exit Code: " << code << "\n"
<< "---- Standard Output ----\n"
- << process_stdout << "\n"
+ << out << "\n"
<< "===============================";
- cmd_process->close();
- cmd_process->deleteLater();
+ pcs->close();
+ pcs->deleteLater();
- data_object->Swap({exit_code, process_stdout, callback});
+ data_object->Swap({code, out, callback});
return 0;
};
return new Thread::Task(
std::move(runner),
QString("GpgCommamdExecutor(%1){%2}").arg(cmd).arg(arguments.join(' ')),
- TransferParams(cmd, arguments, interact_function, cmd_executor_callback),
- std::move(result_callback));
+ TransferParams(cmd, arguments, int_func, cb), std::move(result_callback));
}
-void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
+void GpgCommandExecutor::ExecuteSync(const ExecuteContext &context) {
Thread::Task *task = BuildTaskFromExecCtx(context);
QPointer<Thread::Task> p_t = task;
@@ -174,8 +169,9 @@ void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
looper->deleteLater();
}
-void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
- for (auto &context : contexts) {
+void GpgCommandExecutor::ExecuteConcurrentlyAsync(
+ const ExecuteContexts &contexts) {
+ for (const auto &context : contexts) {
Thread::Task *task = BuildTaskFromExecCtx(context);
if (context.task_runner != nullptr) {
@@ -189,12 +185,13 @@ void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
}
}
-void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
+void GpgCommandExecutor::ExecuteConcurrentlySync(
+ const ExecuteContexts &contexts) {
QEventLoop looper;
auto remaining_tasks = contexts.size();
Thread::TaskRunnerPtr target_task_runner = nullptr;
- for (auto &context : contexts) {
+ for (const auto &context : contexts) {
const auto &cmd = context.cmd;
LOG_D() << "gpg concurrently called cmd: " << cmd;
@@ -235,24 +232,30 @@ GpgCommandExecutor::ExecuteContext::ExecuteContext(
int_func(std::move(int_func)),
task_runner(std::move(task_runner)) {}
+GpgCommandExecutor::ExecuteContext::ExecuteContext(
+ QStringList arguments, GpgCommandExecutorCallback callback,
+ Module::TaskRunnerPtr task_runner, GpgCommandExecutorInterator int_func)
+ : arguments(std::move(arguments)),
+ cb_func(std::move(callback)),
+ int_func(std::move(int_func)),
+ task_runner(std::move(task_runner)) {}
+
GpgCommandExecutor::GpgCommandExecutor(int channel)
: GpgFrontend::SingletonFunctionObject<GpgCommandExecutor>(channel) {}
-void GpgCommandExecutor::GpgExecuteSync(const ExecuteContext &context) {
- const auto gpg_path = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.app_path", QString{});
-
- if (context.cmd.isEmpty() && gpg_path.isEmpty()) {
+auto PrepareContext(const GpgContext &ctx_, const QString &path,
+ const GpgCommandExecutor::ExecuteContext &context)
+ -> std::tuple<bool, GpgCommandExecutor::ExecuteContext> {
+ if (context.cmd.isEmpty() && path.isEmpty()) {
LOG_E() << "failed to execute gpg command, gpg binary path is empty.";
- return;
+ return {false, {}};
}
- LOG_D() << "got gpg binary path:" << gpg_path;
- LOG_D() << "context channel:" << GetChannel()
+ LOG_D() << "got path:" << path << "context channel:" << ctx_.GetChannel()
<< "home path: " << ctx_.HomeDirectory();
- ExecuteContext ctx = {
- context.cmd.isEmpty() ? gpg_path : context.cmd,
+ GpgCommandExecutor::ExecuteContext ctx = {
+ context.cmd.isEmpty() ? path : context.cmd,
context.arguments,
context.cb_func,
context.task_runner,
@@ -260,10 +263,71 @@ void GpgCommandExecutor::GpgExecuteSync(const ExecuteContext &context) {
};
if (!ctx.arguments.contains("--homedir") && !ctx_.HomeDirectory().isEmpty()) {
- ctx.arguments.append("--homedir");
- ctx.arguments.append(ctx_.HomeDirectory());
+ ctx.arguments.prepend(QDir::toNativeSeparators((ctx_.HomeDirectory())));
+ ctx.arguments.prepend("--homedir");
+ }
+
+ return {true, ctx};
+}
+
+auto PrepareExecuteSyncContext(const GpgContext &ctx_, const QString &path,
+ const GpgCommandExecutor::ExecuteContext
+ &context) -> std::tuple<int, QString> {
+ auto ctx = context;
+
+ int pcs_exit_code;
+ QString pcs_stdout;
+
+ // proxy
+ ctx.cb_func = [&](int exit_code, const QString &out, const QString &) {
+ pcs_exit_code = exit_code;
+ pcs_stdout = out;
+ };
+
+ auto [ret, ctx2] = PrepareContext(ctx_, path, ctx);
+ if (ret) {
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(ctx2);
+ return {pcs_exit_code, pcs_stdout};
}
+ return {-1, "invalid context"};
+}
+
+void PrepareExecuteAsyncContext(
+ const GpgContext &ctx_, const QString &path,
+ const GpgCommandExecutor::ExecuteContext &context) {
+ auto [ret, ctx] = PrepareContext(ctx_, path, context);
+ GpgFrontend::GpgCommandExecutor::ExecuteConcurrentlyAsync({ctx});
+}
+
+auto GpgCommandExecutor::GpgExecuteSync(const ExecuteContext &context)
+ -> std::tuple<int, QString> {
+ return PrepareExecuteSyncContext(ctx_,
+ Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{}),
+ context);
+}
+
+auto GpgCommandExecutor::GpgConfExecuteSync(const ExecuteContext &context)
+
+ -> std::tuple<int, QString> {
+ return PrepareExecuteSyncContext(
+ ctx_,
+ Module::RetrieveRTValueTypedOrDefault<>("core", "gpgme.ctx.gpgconf_path",
+ QString{}),
+ context);
+}
+
+void GpgCommandExecutor::GpgExecuteAsync(const ExecuteContext &context) {
+ PrepareExecuteAsyncContext(ctx_,
+ Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{}),
+ context);
+}
- return ExecuteSync(ctx);
+void GpgCommandExecutor::GpgConfExecuteAsync(const ExecuteContext &context) {
+ PrepareExecuteAsyncContext(ctx_,
+ Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{}),
+ context);
}
} // namespace GpgFrontend \ No newline at end of file