Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Lachu:SystemServices
Lachu-PackageKit
0011-Seperate-executable-now-be-responsible-for...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0011-Seperate-executable-now-be-responsible-for-handling-.patch of Package Lachu-PackageKit
From d9dadaf51390d8f37f694a07cbeafb659a264069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20Lach?= <slawek@lach.art.pl> Date: Tue, 6 Oct 2020 15:36:06 +0200 Subject: [PATCH 11/46] - Seperate executable now be responsible for handling UI part of dependency handling - Remove dependency of libdbus and libBonsoleClient from zypp backend and moved it to dependency helper - Added dependency helper directory - Added helpers directory to project --- backends/zypp/meson.build | 6 +- backends/zypp/pk-backend-zypp.cpp | 422 +++++++++----------- helpers/dependency-solving-helper.cpp | 552 ++++++++++++++++++++++++++ helpers/meson.build | 22 + meson.build | 1 + src/pk-backend-job.c | 12 + src/pk-backend-job.h | 6 + src/pk-backend.h | 1 - src/pk-scheduler.c | 2 +- 9 files changed, 777 insertions(+), 247 deletions(-) create mode 100644 helpers/dependency-solving-helper.cpp create mode 100644 helpers/meson.build diff --git a/backends/zypp/meson.build b/backends/zypp/meson.build index 248e82342..94e6b53d6 100644 --- a/backends/zypp/meson.build +++ b/backends/zypp/meson.build @@ -15,13 +15,12 @@ shared_module( dependencies: [ packagekit_glib2_dep, zypp_dep, - gmodule_dep, - dependency('libbonsole'), - dependency('dbus-1'), + gmodule_dep ], cpp_args: [ '-DPK_COMPILATION=1', '-DG_LOG_DOMAIN="PackageKit-Zypp"', + '-DLIBEXECDIR="@0@"'.format(join_paths(get_option('prefix'), get_option('libexecdir'))), '-Wall', '-Woverloaded-virtual', '-Wnon-virtual-dtor' @@ -29,6 +28,7 @@ shared_module( c_args: [ '-Wno-deprecated', '-D_FILE_OFFSET_BITS=64', + '-DLIBEXECDIR="@0@"'.format(join_paths(get_option('prefix'), get_option('libexecdir'))), ], install: true, install_dir: pk_plugin_dir, diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp index 30ef8a86f..0d407d10a 100644 --- a/backends/zypp/pk-backend-zypp.cpp +++ b/backends/zypp/pk-backend-zypp.cpp @@ -24,8 +24,6 @@ #include "config.h" -#include <bonsole_client.h> -#include <dbus/dbus.h> #include <iterator> #include <list> @@ -110,6 +108,17 @@ struct problem { string selected; }; +struct backend_job_private { + + ResolverProblemList::iterator it; + ProblemSolutionList* sol_it; + std::list<std::string> to_install; + std::list<std::string> to_remove; + + std::list<struct problem> problems; + +}; + typedef enum { INSTALL, REMOVE, @@ -566,6 +575,7 @@ class PkBackendZYppPrivate { std::vector<std::string> signatures; EventDirector eventDirector; PkBackendJob *currentJob; +#if 0 bool isBonsoleInit; ResolverProblemList::iterator it; ProblemSolutionList* sol_it; @@ -578,7 +588,7 @@ class PkBackendZYppPrivate { std::list<struct problem> problems; bool first_run; - +#endif pthread_mutex_t zypp_mutex; }; @@ -1532,7 +1542,7 @@ static void add_resolution_to_zypp(struct msg_proc_helper *helper) helper->resolver->applySolutions(*helper->solution_list); } - +#if 0 static void show_solutions(const char *msg_, intptr_t usr_p) { char *buffer, *prev, *curr, *prev2, *prev3; @@ -1789,7 +1799,7 @@ static void message_proc(const char *msg__, intptr_t usr_p) free(msg_); } - +#endif static char *get_record(int fd, char *buffer) { int count; @@ -1849,8 +1859,9 @@ static char *get_record(int fd, char *buffer) } static gboolean -load_transaction_from_history(const char *type, const char *file) +load_transaction_from_history(const char *type, const char *file, struct backend_job_private *priv_) { + char *buffer = NULL; int fd = open(file, O_RDONLY); @@ -1894,8 +1905,8 @@ load_transaction_from_history(const char *type, const char *file) free(buffer); buffer = NULL; - priv->to_install.clear(); - priv->to_remove.clear(); + priv_->to_install.clear(); + priv_->to_remove.clear(); while ((buffer = get_record(fd, buffer)) && ('\0' != buffer[0])) { @@ -1904,7 +1915,7 @@ load_transaction_from_history(const char *type, const char *file) close(fd); return FALSE; } - priv->to_install.push_back(buffer); + priv_->to_install.push_back(buffer); free(buffer); buffer = NULL; } @@ -1922,7 +1933,7 @@ load_transaction_from_history(const char *type, const char *file) close(fd); return FALSE; } - priv->to_remove.push_back(buffer); + priv_->to_remove.push_back(buffer); free(buffer); buffer = NULL; } @@ -1979,7 +1990,7 @@ load_transaction_from_history(const char *type, const char *file) free(buffer); buffer = NULL; - priv->problems.push_back(problem); + priv_->problems.push_back(problem); } if (NULL != buffer) { @@ -2099,13 +2110,46 @@ static void save_transaction_to_cache(const char *type, const char *file, struct } close(fd); } +gboolean +dependency_handle_selection(GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + #if 0 + ProblemSolutionList::const_iterator it2; + ResolverProblemList::iterator it = helper->problems.begin(); + std::advance( + it, + problem_number); + ResolverProblem problem = **it; + + it2 = problem.solutions().begin(); + std::advance( + it2, + solution_number); + ProblemSolution solution = **it2; + + struct problem prob; + prob.kind = problem.description(); + //prob.solutions = + prob.selected = get_full_resolution_text(solution); + + it2 = problem.solutions().begin(); + + for (; it2 != problem.solutions().end(); ++it2) { + + prob.solutions.push_back(get_full_resolution_text(**it2)); +} +helper->problems2.push_back(prob); +#endif + + + return TRUE; +} static gboolean zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gboolean force, PkBitfield transaction_flags) { - bool changed_fds = false; - int fd = -1; - int dup_0, dup_1, dup_2; char *path_to_cache = NULL; MIL << force << " " << pk_filter_bitfield_to_string(transaction_flags) << endl; @@ -2113,11 +2157,11 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job)); - int len = snprintf(NULL, 0, "/var/local/lib/PackageKit/solutions-cache-%s", backend->sender) + 1; + int len = snprintf(NULL, 0, "/var/local/lib/PackageKit/solutions-cache-%s", job->sender) + 1; path_to_cache = (char*) malloc(len); - snprintf(path_to_cache, len, "/var/local/lib/PackageKit/solutions-cache-%s", backend->sender); + snprintf(path_to_cache, len, "/var/local/lib/PackageKit/solutions-cache-%s", job->sender); try { if (force) @@ -2134,40 +2178,47 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo ResPool pool = ResPool::instance (); + if (!zypp->resolver ()->resolvePool ()) { + struct backend_job_private *rjob = (struct backend_job_private*) pk_backend_job_get_priv_data (job); - - priv->to_install = std::list<std::string>(); - priv->to_remove = std::list<std::string>(); - priv->problems = std::list<struct problem> (); + if (NULL == rjob) { + + rjob = new (struct backend_job_private)(); + pk_backend_job_set_priv_data(job, rjob); + + } + rjob->to_install = std::list<std::string>(); + rjob->to_remove = std::list<std::string>(); + rjob->problems = std::list<struct problem> (); ResObject::Kind kind = ResTraits<Package>::kind; - priv->first_run = true; // Adding packages selected by user - while (!zypp->resolver ()->resolvePool ()) { ResolverProblemList problems = zypp->resolver ()->problems (); gchar * emsg = NULL, * tempmsg = NULL; ResolverProblemList::iterator it = problems.begin (); + std::list<std::string> to_remove; + std::list<std::string> to_install; + + + bool changed = false; // Adding additional packages (selected by zypper) to separated field - - if (priv->first_run) { - + { + // if (Test if simulation) { // TODO: SL. S.L. Fill me - load_transaction_from_history("Install", path_to_cache); + load_transaction_from_history("Install", path_to_cache, rjob); transaction_problems.problems = problems; transaction_problems.it = problems.begin(); transaction_problems.resolver = zypp->resolver (); transaction_problems.solution_list = new ProblemSolutionList(); - transaction_problems.problems2 = priv->problems;//std::list<struct problem> {};//priv->problems; - priv->first_run = false; + transaction_problems.problems2 = rjob->problems;//std::list<struct problem> {};//priv->problems; ResPool::byKind_iterator itb = pool.byKindBegin (kind); ResPool::byKind_iterator ite = pool.byKindEnd (kind); - std::list<std::string> to_remove; - std::list<std::string> to_install; + std::list<std::string>::iterator it; @@ -2188,15 +2239,13 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo } } - bool changed = false; - - if (priv->to_remove.size() != to_remove.size()) { + if (rjob->to_remove.size() != to_remove.size()) { changed = true; } - if (!changed && priv->to_remove.size() > 0) { - for (it = priv->to_remove.begin(); it != priv->to_remove.end(); ++it) { + if (!changed && rjob->to_remove.size() > 0) { + for (it = rjob->to_remove.begin(); it != rjob->to_remove.end(); ++it) { std::list<string>::iterator it2; for (it2 = to_remove.begin(); it2 != to_remove.end(); ++it2) { @@ -2214,20 +2263,20 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo } } - if (it != priv->to_remove.end()) { + if (it != rjob->to_remove.end()) { changed = true; } } - if (priv->to_install.size() != to_install.size()) { + if (rjob->to_install.size() != to_install.size()) { changed = true; } - if (!changed && priv->to_install.size() > 0) { + if (!changed && rjob->to_install.size() > 0) { - for (it = priv->to_install.begin(); it != priv->to_install.end(); ++it) { + for (it = rjob->to_install.begin(); it != rjob->to_install.end(); ++it) { std::list<string>::iterator it2; @@ -2248,41 +2297,21 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo } if (!changed - && it != priv->to_install.end() + && it != rjob->to_install.end() ) { changed = true; } - if (changed) { - if (priv->sol_it) { - - delete priv->sol_it; - } - - priv->problems = std::list<struct problem> (); - - priv->sol_it = new ProblemSolutionList(); - priv->to_install = to_install; - priv->to_remove = to_remove; - } - else { - add_resolution_to_zypp(&transaction_problems); - /* Save resolution to file */ - save_transaction_to_cache("Install", path_to_cache, &transaction_problems, - priv->to_install, priv->to_remove); - - } - continue; + - } - + } // Manual intervention required to resolve dependencies // TODO: Figure out what we need to do with PackageKit // to pull off interactive problem solving. - + // TODO: Add support for passing request could be handled interactively if (force) { @@ -2311,215 +2340,133 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo goto exit; } - if (! priv->isBonsoleInit ) { - // I don't known it doesn't mess up - we shouldn't write to the same socket as parent? - // Should we share dbus name with parent? - // And also... What if we modify system during questions answer? - // So I exclude code bellow - // But it solves one big problem - locking PK during dependency resolving -#if 0 - if (0 < fork()) { - - goto exit; - } -#endif - DBusConnection *bus_connection; - DBusError error; - - dbus_error_init(&error); - bus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); - if (bus_connection == NULL) { - if (dbus_error_is_set(&error)) { - fprintf(stderr,"Error occurred, while trying to connect: %s\n", error.message); - } - else { - fprintf(stderr,"Error occurred, while trying to connect\n"); - } - dbus_error_free(&error); - exit(1); + + if (changed) { + if (rjob->sol_it) { + + // delete job->sol_it; } + rjob->problems = std::list<struct problem> (); - char *sender = backend->sender; - char *server, *cookie; - DBusPendingCall* pending; - DBusMessage* reply; - DBusMessageIter args; + // rjob->sol_it = new ProblemSolutionList(); + rjob->to_install = to_install; + rjob->to_remove = to_remove; + pid_t child_pid; - DBusMessage* msg = dbus_message_new_method_call("pl.art.lach.slawek.apps.DaemonUI","/pl/art/lach/slawek/apps/DaemonUI", "pl.art.lach.slawek.apps.DaemonUI.client", "getListenerNameForClient"); - - if (msg == NULL) { - - goto exit; - } + int fds[2]; + int fds2[2]; - dbus_message_iter_init_append(msg, &args); + int input, output; - if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sender)) { + if (pipe(fds) < 0) { - fprintf(stderr, "Out Of Memory!\n"); - exit(1); + perror("Error while pipe creating"); } - - if (!dbus_connection_send_with_reply(bus_connection, msg, &pending, -1)) - { - dbus_message_unref(msg); - goto exit; + else if (pipe(fds2) < 0) { + + perror("Error while pipe creating"); } - dbus_connection_flush(bus_connection); - dbus_message_unref(msg); - dbus_pending_call_block(pending); - reply = dbus_pending_call_steal_reply(pending); - dbus_pending_call_unref(pending); - - if (NULL == reply) { - - puts("Error: No reply"); - goto exit; - } + child_pid = fork(); + - if(dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + if (0 == child_pid) { - puts("Error"); - char *emsg; - if (!dbus_message_get_args(reply, &error, DBUS_TYPE_STRING, &emsg, DBUS_TYPE_INVALID)) { + close(fds[0]); + close(fds2[1]); - puts("No error message provided"); - goto exit; - } + int length; + char *comm_ch_output; + char *comm_ch_input; - puts(emsg); - goto exit; - } - - dbus_error_init(&error); - dbus_message_get_args(reply, &error, DBUS_TYPE_STRING, &server, DBUS_TYPE_STRING, &cookie, DBUS_TYPE_INVALID); - if (dbus_error_is_set(&error)) { + length = snprintf(NULL, 0, "%d", fds[1]) + 1; + comm_ch_output = (char*) malloc(length); + snprintf(comm_ch_output, length, "%d", fds[1]); - puts(error.message); - goto exit; - } - - - msg = dbus_message_new_method_call("pl.art.lach.slawek.apps.DaemonUI","/pl/art/lach/slawek/apps/DaemonUI", "pl.art.lach.slawek.apps.DaemonUI.client", "getRealTTYForClient"); - - if (msg == NULL) { + length = snprintf(NULL, 0, "%d", fds2[0]) + 1; + comm_ch_input = (char*) malloc(length); + snprintf(comm_ch_input, length, "%d", fds2[0]); - goto exit; - } - - - dbus_message_iter_init_append(msg, &args); - - if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sender)) { + execlp(LIBEXECDIR "/dependency-solving-helper", LIBEXECDIR "/dependency-solving-helper", "--comm-channel-input", comm_ch_input,"--comm-channel-output", comm_ch_output, NULL); + + write(STDOUT_FILENO, "ERR: Unable to start dependency solver\n", sizeof("Unable to start dependency solver\n") - 1); + exit(1); - fprintf(stderr, "Out Of Memory!\n"); - exit(1); } - - if (!dbus_connection_send_with_reply(bus_connection, msg, &pending, -1)) + // TODO: SL S.L. READ DOCUMENTATION + else if (-1 == child_pid) { - dbus_message_unref(msg); - goto exit; + perror("Cannot spawn interactive dependency solver"); + + close(fds[0]); + close(fds2[1]); + close(fds[1]); + close(fds2[0]); + + pk_backend_job_error_code (job, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, "Cannot spawn interactive dependency solver"); } - dbus_connection_flush(bus_connection); - dbus_message_unref(msg); - - dbus_pending_call_block(pending); - reply = dbus_pending_call_steal_reply(pending); - dbus_pending_call_unref(pending); - - if (NULL == reply) { + else { + + close(fds[1]); + close(fds2[0]); + GIOChannel *chann = g_io_channel_unix_new (fds[0]); + g_io_add_watch(chann, G_IO_IN, dependency_handle_selection, &transaction_problems); + + output = fds2[1]; + input = fds[0]; - puts("Error: No reply"); - goto exit; } - - if(dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + { + ResolverProblemList::iterator it; + ProblemSolutionList::const_iterator sol_it; + const char *string; + write(output, job->sender, strlen(job->sender) + 1); - puts("Error"); - char *emsg; - if (!dbus_message_get_args(reply, &error, DBUS_TYPE_STRING, &emsg, DBUS_TYPE_INVALID)) { + for (it = transaction_problems.problems.begin(); it != transaction_problems.problems.end(); ++it) { - puts("No error message provided"); - goto exit; + string = (*it)->description ().c_str (); + puts(string); + write(output, string, strlen(string)+1); + for (sol_it = (**it).solutions().begin(); sol_it != (**it).solutions().end(); ++sol_it) { + + + string = (*sol_it)->description ().c_str (); + puts(string); + write(output, string, strlen(string)+1); + string = (*sol_it)->details ().c_str (); + puts(string); + write(output, string, strlen(string)+1); + write(output, "", sizeof("")); + + } + write(output, "", sizeof("")); } - puts(emsg); - goto exit; - } - - dbus_bool_t error_1; - - dup_0 = dup_1 = dup_2 = -1; - dbus_error_init(&error); - dbus_message_get_args(reply, &error, DBUS_TYPE_BOOLEAN, &error_1, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID); - if (dbus_error_is_set(&error)) { - - puts(error.message); + write(output, "", sizeof("")); goto exit; - } - - dup_0 = dup(0); - dup_1 = dup(1); - dup_2 = dup(2); - close(0); - close(1); - close(2); - changed_fds = true; - - if (!error_1 && -1 != fd) { - - - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - } - setenv("HOME", "/root", 0); - setenv("LANG", "EN_US", 0); - - setenv("BONSOLE_DBUS_SCOPE", "SYSTEM_BUS", 1); - setenv("BONSOLE_RUN_MODE", "ALWAYS_TRY_TO_LOGIN", 1); - setenv("BONSOLE_DBUS_NAME", server, 1); - setenv("BONSOLE_COOKIE", cookie, 1); - - int argc = 1; - char *argv[2] = {(char*)"packagekitd", (char*)NULL}; - - if (0 != bonsole_client_init(&argc, argv)) exit(1); + } + } + else { + add_resolution_to_zypp(&transaction_problems); + /* Save resolution to file */ + save_transaction_to_cache("Install", path_to_cache, &transaction_problems, + rjob->to_install, rjob->to_remove); - priv->isBonsoleInit = true; } - #if 0 - if (!priv->sol_it->empty()) { - - zypp->resolver()->applySolutions(*priv->sol_it); - continue; - } -#endif - transaction_problems.problems = problems; - transaction_problems.it = problems.begin(); - transaction_problems.resolver = zypp->resolver (); - transaction_problems.solution_list = NULL; - - bonsole_reset_document(nullptr); - show_solutions("", (intptr_t)(void*) &transaction_problems); - bonsole_main_loop(0, message_proc, (intptr_t)(void*)&transaction_problems); - add_resolution_to_zypp(&transaction_problems); // Save resolution to file save_transaction_to_cache("Install", path_to_cache, &transaction_problems, priv->to_install, priv->to_remove); - } - +#endif + } switch (type) { case INSTALL: pk_backend_job_set_status (job, PK_STATUS_ENUM_INSTALL); @@ -2640,6 +2587,7 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo goto exit; } + pk_backend_job_set_percentage(job, 100); ret = TRUE; @@ -2653,13 +2601,6 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo exit: - if (changed_fds) { - - - dup2(dup_0, 0); - dup2(dup_1, 1); - dup2(dup_2, 2); - } if (path_to_cache) free(path_to_cache); @@ -2871,10 +2812,7 @@ pk_backend_initialize (GKeyFile *conf, PkBackend *backend) { /* create private area */ priv = new PkBackendZYppPrivate; - priv->isBonsoleInit = false; - priv->sol_it = NULL; priv->currentJob = 0; - priv->first_run = true; priv->zypp_mutex = PTHREAD_MUTEX_INITIALIZER; zypp_logging (); diff --git a/helpers/dependency-solving-helper.cpp b/helpers/dependency-solving-helper.cpp new file mode 100644 index 000000000..f2f33048a --- /dev/null +++ b/helpers/dependency-solving-helper.cpp @@ -0,0 +1,552 @@ +#include <stdlib.h> +#include <stddef.h> +#include <unistd.h> +#include <string.h> + +#include <bonsole_client.h> +#include <dbus/dbus.h> +static char *get_record(int fd) +{ + static char *buffer = NULL; + static int curr = 0; + static int loaded = 0; + int count = 0; + int buff_len = 0; + bool done = false; + int curr2 = curr; + + while (loaded >= curr2 + 1) { + + ++curr2; + + if ('\0' == buffer[curr2]) { + + curr = curr2; + return &buffer[curr2+1]; + } + + } + + buff_len += 512; + buffer = (char*)realloc(buffer, buff_len); + + if (NULL == buffer) { + + return NULL; + } + + while ((count = read(fd, buffer, buff_len - 1 - loaded)) > 0) { + + + curr = loaded; + loaded += count; + while ('\0' != buffer[curr] && curr < loaded) { + + ++curr; + } + + if (curr < loaded && '\0' == buffer[curr]) { + + done = true; + break; + } + + buff_len += 512; + buffer = (char*)realloc(buffer, buff_len); + + if (NULL == buffer) { + + count = 0; + break; + } + }; + + if (!done && 0 > count) { + + perror("Error while read from pipe"); + free(buffer); + close(fd); + return NULL; + } + + //buffer[loaded] = '\0'; + + return buffer; + +} + +static bool show_solutions(int fd) +{ + char *buffer, *prev, *curr, *prev2, *prev3; + int length, length2; + int problem, solution; + xmlNodePtr root, text, anchor, message, form, checkbox; + + xmlDocPtr a = bonsole_window(nullptr); + root = xmlDocGetRootElement(a); + + + form = xmlNewNode(NULL, BAD_CAST "form"); + xmlSetProp(form, BAD_CAST "action",BAD_CAST "app:update"); + xmlAddChild(root, form); + + problem = 0; + solution = 0; + buffer = NULL; + + while ((buffer = get_record(fd)) && ('\0' != buffer[0])) { + + + puts(buffer); + text = xmlNewText(BAD_CAST buffer); + + xmlAddChild(form, text); + + while ((buffer = get_record(fd)) && ('\0' != buffer[0])) { + + puts("A"); + puts(buffer); + checkbox = xmlNewNode(NULL, BAD_CAST "checkbox"); + text = xmlNewText(BAD_CAST buffer); + xmlAddChild(checkbox, text); + + xmlAddChild(form, checkbox); + + if ((buffer = get_record(fd)) && ('\0' != buffer[0])) { + + char *prev = buffer; + char *curr = buffer; + + while ('\0' != *curr) { + + if ('\n' == *curr) { + + *curr = '\0'; + text = xmlNewText(BAD_CAST prev); + xmlAddChild(form, text); + text = xmlNewNode(NULL, BAD_CAST "br"); + xmlAddChild(form, text); + prev = curr + 1; + } + + ++curr; + } + + text = xmlNewText(BAD_CAST prev); + xmlAddChild(checkbox, text); + + length = snprintf(NULL, 0, "%d_%d", problem, solution) + 1; + buffer = (char*) malloc(length); + snprintf(buffer, length, "%d_%d", problem, solution); + + xmlSetProp(checkbox, BAD_CAST "name", BAD_CAST buffer); + + buffer = NULL; + } + + ++solution; + + } + ++problem; + } + + + if (0 == problem) + return false; + bonsole_window_release(nullptr); + bonsole_flush_changes(nullptr); + + return true; +} + +static void message_proc(const char *msg__, intptr_t usr_p) +{ + char *buffer, *prev, *curr, *prev2, *prev3, *spec; + int length, length2; + int problem, solution; + xmlNodePtr root, text, anchor, message, form, checkbox; + + char *msg_ = bonsole_message_unescape_string(msg__, 0); + + if (0 == strncmp("update?", msg_, sizeof("update?") - 1)) { + + bonsole_reset_document(nullptr); + xmlDocPtr a = bonsole_window(nullptr); + root = xmlDocGetRootElement(a); + spec = msg_; + buffer = spec; + length = 0; + while ('\0' != *buffer) { + + if ('&' == *buffer) { + + ++length; + *buffer = '\0'; + } + ++buffer; + } + ++length; + buffer = &spec[sizeof("update?") - 1]; + + while (0 < length) { + + prev = buffer; + do { + + ++buffer; + } while ('_' != *buffer); + + *buffer = '\0'; + ++buffer; + do { + ++buffer; + } while ('=' != *buffer); + + + ++buffer; + if ('\0' != buffer[0] && 0 != strcmp(buffer, "1")) { + + --length; + do { + ++buffer; + } while ('\0' != *buffer); + + continue; + } + + while ('\0' != *buffer) { + ++buffer; + } + + ++buffer; + curr = prev; + prev = buffer; + + length2 = length - 1; + while (0 < length2) { + prev2 = buffer; + + + + do { + + ++buffer; + } while ('_' != *buffer); + + *buffer = '\0'; + ++buffer; + + + if (0 != strcmp(curr, prev2)) { + + --length2; + do { + ++buffer; + } while ('\0' != *buffer); + + continue; + } + + do { + ++buffer; + } while ('=' != *buffer); + + + ++buffer; + if ('\0' != buffer[0] && 0 != strcmp(buffer, "1")) { + + --length2; + do { + ++buffer; + } while ('\0' != *buffer); + + ++buffer; + if ('\0' != *buffer) { + + ++buffer; + } + continue; + } + message = xmlNewNode(NULL, BAD_CAST "message"); + text = xmlNewText(BAD_CAST "You checked two different solutions for one problem"); + xmlAddChild(message, text); + xmlAddChild(root, message); + + bonsole_window_release(nullptr); + show_solutions(usr_p); + + return; + + } + do { + ++buffer; + } while ('\0' != *buffer); + int problem_number, solution_number; + + problem_number = atoi(curr); + while ('\0' != *curr) ++curr; + prev3 = ++curr; + while ('\0' != *curr && '=' != *curr) ++curr; + *curr = '\0'; + solution_number = atoi(prev3); + //++solution_number; + + + + free(spec); + + + --length; + } + + + + bonsole_window_release(nullptr); + bonsole_flush_changes(nullptr); + + bonsole_quit_loop(nullptr); + } + + free(msg_); +} + + +int main(int argc, char **argv) +{ + int curr; + int input, output, fd; + int dup_0, dup_1, dup_2; + + output = input = -1; + + for (curr = 1; curr < argc; ++curr) { + + if (0 == strcmp(argv[curr], "--comm-channel-input")) { + + if (argc - 1 <= curr) { + + exit(1); + } + + input = atoi(argv[curr+1]); + curr++; + } + else if (0 == strcmp(argv[curr], "--comm-channel-output")) { + + if (argc - 1 <= curr) { + + exit(1); + } + + output = atoi(argv[curr+1]); + curr++; + } + else { + + exit(1); + } + } + + char *sender = get_record(input); + + dup_0 = dup(0); + dup_1 = dup(1); + dup_2 = dup(2); + + DBusConnection *bus_connection; + DBusError error; + + dbus_error_init(&error); + bus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (bus_connection == NULL) { + if (dbus_error_is_set(&error)) { + fprintf(stderr,"Error occurred, while trying to connect: %s\n", error.message); + } + else { + fprintf(stderr,"Error occurred, while trying to connect\n"); + } + dbus_error_free(&error); + exit(1); + } + + + char *server, *cookie; + DBusPendingCall* pending; + DBusMessage* reply; + DBusMessageIter args; + + + DBusMessage* msg = dbus_message_new_method_call("pl.art.lach.slawek.apps.DaemonUI","/pl/art/lach/slawek/apps/DaemonUI", "pl.art.lach.slawek.apps.DaemonUI.client", "getListenerNameForClient"); + + if (msg == NULL) { + + goto exit; + } + + + dbus_message_iter_init_append(msg, &args); + + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sender)) { + + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + + if (!dbus_connection_send_with_reply(bus_connection, msg, &pending, -1)) + { + dbus_message_unref(msg); + goto exit; + } + dbus_connection_flush(bus_connection); + dbus_message_unref(msg); + + dbus_pending_call_block(pending); + reply = dbus_pending_call_steal_reply(pending); + dbus_pending_call_unref(pending); + + if (NULL == reply) { + + puts("Error: No reply"); + goto exit; + } + + if(dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + + puts("Error"); + char *emsg; + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_STRING, &emsg, DBUS_TYPE_INVALID)) { + + puts("No error message provided"); + goto exit; + } + + puts(emsg); + goto exit; + } + + dbus_error_init(&error); + dbus_message_get_args(reply, &error, DBUS_TYPE_STRING, &server, DBUS_TYPE_STRING, &cookie, DBUS_TYPE_INVALID); + if (dbus_error_is_set(&error)) { + + puts(error.message); + goto exit; + } + + + msg = dbus_message_new_method_call("pl.art.lach.slawek.apps.DaemonUI","/pl/art/lach/slawek/apps/DaemonUI", "pl.art.lach.slawek.apps.DaemonUI.client", "getRealTTYForClient"); + + if (msg == NULL) { + + goto exit; + } + + + dbus_message_iter_init_append(msg, &args); + + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sender)) { + + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + + if (!dbus_connection_send_with_reply(bus_connection, msg, &pending, -1)) + { + dbus_message_unref(msg); + goto exit; + } + dbus_connection_flush(bus_connection); + dbus_message_unref(msg); + + dbus_pending_call_block(pending); + reply = dbus_pending_call_steal_reply(pending); + dbus_pending_call_unref(pending); + + if (NULL == reply) { + + puts("Error: No reply"); + goto exit; + } + + if(dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + + puts("Error"); + char *emsg; + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_STRING, &emsg, DBUS_TYPE_INVALID)) { + + puts("No error message provided"); + goto exit; + } + + puts(emsg); + goto exit; + } + dbus_bool_t error_1; + + dup_0 = dup_1 = dup_2 = -1; + dbus_error_init(&error); + dbus_message_get_args(reply, &error, DBUS_TYPE_BOOLEAN, &error_1, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID); + if (dbus_error_is_set(&error)) { + + puts(error.message); + goto exit; + } + +#if 1 + dup_0 = dup(0); + dup_1 = dup(1); + dup_2 = dup(2); + close(0); + close(1); + close(2); + + + if (!error_1 && -1 != fd) { + + + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + } +#endif + setenv("HOME", "/root", 0); + setenv("LANG", "EN_US", 0); + + setenv("BONSOLE_DBUS_SCOPE", "SYSTEM_BUS", 1); + setenv("BONSOLE_RUN_MODE", "ALWAYS_TRY_TO_LOGIN", 1); + setenv("BONSOLE_DBUS_NAME", server, 1); + setenv("BONSOLE_COOKIE", cookie, 1); + { + int argc = 1; + char *argv[2] = {(char*)"packagekitd", (char*)NULL}; + + if (0 != bonsole_client_init(&argc, argv)) exit(1); + } + +#if 0 +transaction_problems.problems = problems; +transaction_problems.it = problems.begin(); +transaction_problems.resolver = zypp->resolver (); +transaction_problems.solution_list = NULL; +#endif +do { +bonsole_reset_document(nullptr); +if (!show_solutions( input)) { + + break; +} +bonsole_main_loop(0, message_proc, output); +} while (true); +#if 0 +add_resolution_to_zypp(&transaction_problems); + +// Save resolution to file +save_transaction_to_cache("Install", path_to_cache, &transaction_problems, + priv->to_install, priv->to_remove); +#endif +exit: + dup2(dup_0, 0); + dup2(dup_1, 1); + dup2(dup_2, 2); + return EXIT_SUCCESS; +} diff --git a/helpers/meson.build b/helpers/meson.build new file mode 100644 index 000000000..77575ec2a --- /dev/null +++ b/helpers/meson.build @@ -0,0 +1,22 @@ +packagekit_src_include = include_directories('.') + +helper_exec = executable( + 'dependency-solving-helper', + 'dependency-solving-helper.cpp', + dependencies: [ + dependency('libbonsole'), + dependency('dbus-1'), + dependency('libxslt'), + ], + install: true, + install_dir: get_option('libexecdir'), + cxx_args: [ + '-DLIBDIR="@0@"'.format(join_paths(get_option('prefix'), get_option('libdir'))), + '-DSYSCONFDIR="@0@"'.format(get_option('sysconfdir')), + '-DVERSION="@0@"'.format(meson.project_version()), + '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()), + '-DPACKAGE_LOCALE_DIR="@0@"'.format(package_locale_dir), + '-DLIBEXECDIR="@0@"'.format(join_paths(get_option('prefix'), get_option('libexecdir'))), + + ] +) diff --git a/meson.build b/meson.build index c0db907ea..0d40589f1 100644 --- a/meson.build +++ b/meson.build @@ -146,3 +146,4 @@ subdir('client') subdir('backends') subdir('contrib') subdir('docs') +subdir('helpers') diff --git a/src/pk-backend-job.c b/src/pk-backend-job.c index 538595dd6..e6ed7ec6c 100644 --- a/src/pk-backend-job.c +++ b/src/pk-backend-job.c @@ -1562,6 +1562,16 @@ pk_backend_job_get_allow_cancel (PkBackendJob *job) return job->priv->allow_cancel; } +void *pk_backend_job_get_priv_data (PkBackendJob *job) +{ + return job->private_data; +} + + +void pk_backend_job_set_priv_data (PkBackendJob *job, void *a) +{ + job->private_data = a; +} /** * pk_backend_job_set_exit_code: * @@ -1696,6 +1706,8 @@ pk_backend_job_init (PkBackendJob *job) job->priv->status = PK_STATUS_ENUM_UNKNOWN; job->priv->emitted = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); + + job->private_data = NULL; } /** diff --git a/src/pk-backend-job.h b/src/pk-backend-job.h index 67ffac692..b83906059 100644 --- a/src/pk-backend-job.h +++ b/src/pk-backend-job.h @@ -67,6 +67,9 @@ typedef struct { GObject parent; PkBackendJobPrivate *priv; + + char *sender; + void *private_data; } PkBackendJob; typedef struct @@ -252,6 +255,9 @@ void pk_backend_job_set_started (PkBackendJob *job, gboolean started); gboolean pk_backend_job_get_started (PkBackendJob *job); +void *pk_backend_job_get_priv_data (PkBackendJob *job); +void pk_backend_job_set_priv_data (PkBackendJob *job, void *a); + G_END_DECLS #endif /* __PK_BACKEND_JOB_H */ diff --git a/src/pk-backend.h b/src/pk-backend.h index 4ffc0ec21..a3ab20414 100644 --- a/src/pk-backend.h +++ b/src/pk-backend.h @@ -52,7 +52,6 @@ typedef struct { GObject parent; PkBackendPrivate *priv; - char *sender; } PkBackend; typedef struct diff --git a/src/pk-scheduler.c b/src/pk-scheduler.c index 9ada99831..4980104e7 100644 --- a/src/pk-scheduler.c +++ b/src/pk-scheduler.c @@ -686,7 +686,7 @@ pk_scheduler_create (PkScheduler *scheduler, } /* Set the sender id */ - pk_transaction_get_backend(item->transaction)->sender = strdup(sender); + pk_transaction_get_backend_job(item->transaction)->sender = strdup(sender); /* the client only has a finite amount of time to use the object, else it's destroyed */ item->commit_id = g_timeout_add_seconds (PK_SCHEDULER_CREATE_COMMIT_TIMEOUT, -- 2.32.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor