|
Packit |
8ea169 |
#include <dbus/dbus.h>
|
|
Packit |
8ea169 |
#include <gio/gio.h>
|
|
Packit |
8ea169 |
#include <stdlib.h>
|
|
Packit |
8ea169 |
#include <sys/types.h>
|
|
Packit |
8ea169 |
#include <pwd.h>
|
|
Packit |
8ea169 |
#include <grp.h>
|
|
Packit |
8ea169 |
#include "libabrt.h"
|
|
Packit |
8ea169 |
#include "abrt-polkit.h"
|
|
Packit |
8ea169 |
#include "abrt_glib.h"
|
|
Packit |
8ea169 |
#include <libreport/dump_dir.h>
|
|
Packit |
8ea169 |
#include "problem_api.h"
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
#include "abrt_problems2_entry.h"
|
|
Packit |
8ea169 |
#include "abrt_problems2_service.h"
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static GMainLoop *loop;
|
|
Packit |
8ea169 |
static guint g_timeout_source;
|
|
Packit |
8ea169 |
/* default, settable with -t: */
|
|
Packit |
8ea169 |
static unsigned g_timeout_value = 120;
|
|
Packit |
8ea169 |
static guint g_signal_crash;
|
|
Packit |
8ea169 |
static guint g_signal_dup_crash;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* ---------------------------------------------------------------------------------------------------- */
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static GDBusNodeInfo *introspection_data = NULL;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Introspection data for the service we are exporting */
|
|
Packit |
8ea169 |
static const gchar introspection_xml[] =
|
|
Packit |
8ea169 |
"<node>"
|
|
Packit |
8ea169 |
" <interface name='"ABRT_DBUS_IFACE"'>"
|
|
Packit |
8ea169 |
" <method name='NewProblem'>"
|
|
Packit |
8ea169 |
" <arg type='a{ss}' name='problem_data' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='s' name='problem_id' direction='out'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='GetProblems'>"
|
|
Packit |
8ea169 |
" <arg type='as' name='response' direction='out'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='GetAllProblems'>"
|
|
Packit |
8ea169 |
" <arg type='as' name='response' direction='out'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='GetForeignProblems'>"
|
|
Packit |
8ea169 |
" <arg type='as' name='response' direction='out'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='GetInfo'>"
|
|
Packit |
8ea169 |
" <arg type='s' name='problem_dir' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='as' name='element_names' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='a{ss}' name='response' direction='out'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='SetElement'>"
|
|
Packit |
8ea169 |
" <arg type='s' name='problem_dir' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='s' name='name' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='s' name='value' direction='in'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='DeleteElement'>"
|
|
Packit |
8ea169 |
" <arg type='s' name='problem_dir' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='s' name='name' direction='in'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='TestElementExists'>"
|
|
Packit |
8ea169 |
" <arg type='s' name='problem_dir' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='s' name='name' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='b' name='response' direction='out'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='GetProblemData'>"
|
|
Packit |
8ea169 |
" <arg type='s' name='problem_dir' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='a{s(its)}' name='problem_data' direction='out'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='ChownProblemDir'>"
|
|
Packit |
8ea169 |
" <arg type='s' name='problem_dir' direction='in'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='DeleteProblem'>"
|
|
Packit |
8ea169 |
" <arg type='as' name='problem_dir' direction='in'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='FindProblemByElementInTimeRange'>"
|
|
Packit |
8ea169 |
" <arg type='s' name='element' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='s' name='value' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='x' name='timestamp_from' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='x' name='timestamp_to' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='b' name='all_users' direction='in'/>"
|
|
Packit |
8ea169 |
" <arg type='as' name='response' direction='out'/>"
|
|
Packit |
8ea169 |
" </method>"
|
|
Packit |
8ea169 |
" <method name='Quit' />"
|
|
Packit |
8ea169 |
" </interface>"
|
|
Packit |
8ea169 |
"</node>";
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* ---------------------------------------------------------------------------------------------------- */
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* forward */
|
|
Packit |
8ea169 |
static gboolean on_timeout_cb(gpointer user_data);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void kill_timeout(void)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (g_timeout_source == 0)
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
log_info("Removing timeout");
|
|
Packit |
8ea169 |
guint tm = g_timeout_source;
|
|
Packit |
8ea169 |
g_timeout_source = 0;
|
|
Packit |
8ea169 |
g_source_remove(tm);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void run_timeout(void)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (g_timeout_source != 0)
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
log_info("Setting a new timeout");
|
|
Packit |
8ea169 |
g_timeout_source = g_timeout_add_seconds(g_timeout_value, on_timeout_cb, NULL);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
bool allowed_problem_dir(const char *dir_name)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (!dir_is_in_dump_location(dir_name))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
error_msg("Bad problem directory name '%s', should start with: '%s'", dir_name, g_settings_dump_location);
|
|
Packit |
8ea169 |
return false;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (!dir_has_correct_permissions(dir_name, DD_PERM_DAEMONS))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
error_msg("Problem directory '%s' has invalid owner, groop or mode", dir_name);
|
|
Packit |
8ea169 |
return false;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return true;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
bool allowed_problem_element(GDBusMethodInvocation *invocation, const char *element)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (str_is_correct_filename(element))
|
|
Packit |
8ea169 |
return true;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
log_notice("'%s' is not a valid element name", element);
|
|
Packit |
8ea169 |
char *error = xasprintf(_("'%s' is not a valid element name"), element);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.InvalidElement",
|
|
Packit |
8ea169 |
error);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
free(error);
|
|
Packit |
8ea169 |
return false;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static char *handle_new_problem(GVariant *problem_info, uid_t caller_uid, char **error)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
char *problem_id = NULL;
|
|
Packit |
8ea169 |
problem_data_t *pd = problem_data_new();
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GVariantIter *iter;
|
|
Packit |
8ea169 |
g_variant_get(problem_info, "a{ss}", &iter);
|
|
Packit |
8ea169 |
gchar *key, *value;
|
|
Packit |
8ea169 |
while (g_variant_iter_loop(iter, "{ss}", &key, &value))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (allowed_new_user_problem_entry(caller_uid, key, value) == false)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
*error = xasprintf("You are not allowed to create element '%s' containing '%s'", key, value);
|
|
Packit |
8ea169 |
goto finito;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
problem_data_add_text_editable(pd, key, value);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (caller_uid != 0 || problem_data_get_content_or_NULL(pd, FILENAME_UID) == NULL)
|
|
Packit |
8ea169 |
{ /* set uid field to caller's uid if caller is not root or root doesn't pass own uid */
|
|
Packit |
8ea169 |
log_info("Adding UID %d to problem data", caller_uid);
|
|
Packit |
8ea169 |
char buf[sizeof(uid_t) * 3 + 2];
|
|
Packit |
8ea169 |
snprintf(buf, sizeof(buf), "%d", caller_uid);
|
|
Packit |
8ea169 |
problem_data_add_text_noteditable(pd, FILENAME_UID, buf);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* At least it should generate local problem identifier UUID */
|
|
Packit |
8ea169 |
problem_data_add_basics(pd);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
problem_id = problem_data_save(pd);
|
|
Packit |
8ea169 |
if (problem_id)
|
|
Packit |
8ea169 |
notify_new_path(problem_id);
|
|
Packit |
8ea169 |
else if (error)
|
|
Packit |
8ea169 |
*error = xasprintf("Cannot create a new problem");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
finito:
|
|
Packit |
8ea169 |
problem_data_free(pd);
|
|
Packit |
8ea169 |
return problem_id;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void return_InvalidProblemDir_error(GDBusMethodInvocation *invocation, const char *dir_name)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
char *msg = xasprintf(_("'%s' is not a valid problem directory"), dir_name);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.InvalidProblemDir",
|
|
Packit |
8ea169 |
msg);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
free(msg);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
enum {
|
|
Packit |
8ea169 |
OPEN_FAIL_NO_REPLY = 1 << 0,
|
|
Packit |
8ea169 |
OPEN_AUTH_ASK = 1 << 1,
|
|
Packit |
8ea169 |
OPEN_AUTH_FAIL = 1 << 2,
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static struct dump_dir *open_dump_directory(GDBusMethodInvocation *invocation,
|
|
Packit |
8ea169 |
const gchar *caller, uid_t caller_uid, const char *problem_dir, int dd_flags, int flags)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (!allowed_problem_dir(problem_dir))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_warning("UID=%d attempted to access not allowed problem directory '%s'",
|
|
Packit |
8ea169 |
caller_uid, problem_dir);
|
|
Packit |
8ea169 |
if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Packit |
8ea169 |
return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Packit |
8ea169 |
return NULL;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct dump_dir *dd = dd_opendir(problem_dir, DD_OPEN_FD_ONLY);
|
|
Packit |
8ea169 |
if (dd == NULL)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
perror_msg("can't open problem directory '%s'", problem_dir);
|
|
Packit |
8ea169 |
if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Packit |
8ea169 |
return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Packit |
8ea169 |
return NULL;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (!dd_accessible_by_uid(dd, caller_uid))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (errno == ENOTDIR)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("Requested directory does not exist '%s'", problem_dir);
|
|
Packit |
8ea169 |
if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Packit |
8ea169 |
return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
return NULL;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if ( !(flags & OPEN_AUTH_ASK)
|
|
Packit |
8ea169 |
|| polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("not authorized");
|
|
Packit |
8ea169 |
if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.AuthFailure",
|
|
Packit |
8ea169 |
_("Not Authorized"));
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
return NULL;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
dd = dd_fdopendir(dd, dd_flags);
|
|
Packit |
8ea169 |
if (dd == NULL)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("Can't open the problem '%s' with flags %x0", problem_dir, dd_flags);
|
|
Packit |
8ea169 |
if (!(flags & OPEN_FAIL_NO_REPLY))
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.Failure",
|
|
Packit |
8ea169 |
_("Can't open the problem"));
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
return dd;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/*
|
|
Packit |
8ea169 |
* Checks element's rights and does not open directory if element is protected.
|
|
Packit |
8ea169 |
* Checks problem's rights and does not open directory if user hasn't got
|
|
Packit |
8ea169 |
* access to a problem.
|
|
Packit |
8ea169 |
*
|
|
Packit |
8ea169 |
* Returns a dump directory opend for writing or NULL.
|
|
Packit |
8ea169 |
*
|
|
Packit |
8ea169 |
* If any operation from the above listed fails, immediately returns D-Bus
|
|
Packit |
8ea169 |
* error to a D-Bus caller.
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
static struct dump_dir *open_directory_for_modification_of_element(
|
|
Packit |
8ea169 |
GDBusMethodInvocation *invocation,
|
|
Packit |
8ea169 |
uid_t caller_uid,
|
|
Packit |
8ea169 |
const char *problem_id,
|
|
Packit |
8ea169 |
const char *element)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
static const char *const protected_elements[] = {
|
|
Packit |
8ea169 |
FILENAME_TIME,
|
|
Packit |
8ea169 |
FILENAME_UID,
|
|
Packit |
8ea169 |
NULL,
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
for (const char *const *protected = protected_elements; *protected; ++protected)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (strcmp(*protected, element) == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("'%s' element of '%s' can't be modified", element, problem_id);
|
|
Packit |
8ea169 |
char *error = xasprintf(_("'%s' element can't be modified"), element);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.ProtectedElement",
|
|
Packit |
8ea169 |
error);
|
|
Packit |
8ea169 |
free(error);
|
|
Packit |
8ea169 |
return NULL;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return open_dump_directory(invocation, /*caller*/NULL, caller_uid, problem_id, /*Read/Write*/0,
|
|
Packit |
8ea169 |
OPEN_AUTH_FAIL);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/*
|
|
Packit |
8ea169 |
* Lists problems which have given element and were seen in given time interval
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct field_and_time_range {
|
|
Packit |
8ea169 |
GList *list;
|
|
Packit |
8ea169 |
const char *element;
|
|
Packit |
8ea169 |
const char *value;
|
|
Packit |
8ea169 |
unsigned long timestamp_from;
|
|
Packit |
8ea169 |
unsigned long timestamp_to;
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static int add_dirname_to_GList_if_matches(struct dump_dir *dd, void *arg)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
struct field_and_time_range *me = arg;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
char *field_data = dd_load_text(dd, me->element);
|
|
Packit |
8ea169 |
int brk = (strcmp(field_data, me->value) != 0);
|
|
Packit |
8ea169 |
free(field_data);
|
|
Packit |
8ea169 |
if (brk)
|
|
Packit |
8ea169 |
return 0;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
field_data = dd_load_text(dd, FILENAME_LAST_OCCURRENCE);
|
|
Packit |
8ea169 |
long val = atol(field_data);
|
|
Packit |
8ea169 |
free(field_data);
|
|
Packit |
8ea169 |
if (val < me->timestamp_from || val > me->timestamp_to)
|
|
Packit |
8ea169 |
return 0;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
me->list = g_list_prepend(me->list, xstrdup(dd->dd_dirname));
|
|
Packit |
8ea169 |
return 0;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static GList *get_problem_dirs_for_element_in_time(uid_t uid,
|
|
Packit |
8ea169 |
const char *element,
|
|
Packit |
8ea169 |
const char *value,
|
|
Packit |
8ea169 |
unsigned long timestamp_from,
|
|
Packit |
8ea169 |
unsigned long timestamp_to)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (timestamp_to == 0) /* not sure this is possible, but... */
|
|
Packit |
8ea169 |
timestamp_to = time(NULL);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct field_and_time_range me = {
|
|
Packit |
8ea169 |
.list = NULL,
|
|
Packit |
8ea169 |
.element = element,
|
|
Packit |
8ea169 |
.value = value,
|
|
Packit |
8ea169 |
.timestamp_from = timestamp_from,
|
|
Packit |
8ea169 |
.timestamp_to = timestamp_to,
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
for_each_problem_in_dir(g_settings_dump_location, uid, add_dirname_to_GList_if_matches, &me);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return g_list_reverse(me.list);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void handle_method_call(GDBusConnection *connection,
|
|
Packit |
8ea169 |
const gchar *caller,
|
|
Packit |
8ea169 |
const gchar *object_path,
|
|
Packit |
8ea169 |
const gchar *interface_name,
|
|
Packit |
8ea169 |
const gchar *method_name,
|
|
Packit |
8ea169 |
GVariant *parameters,
|
|
Packit |
8ea169 |
GDBusMethodInvocation *invocation,
|
|
Packit |
8ea169 |
gpointer user_data)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
uid_t caller_uid;
|
|
Packit |
8ea169 |
GVariant *response;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GError *error = NULL;
|
|
Packit |
8ea169 |
caller_uid = abrt_p2_service_caller_uid(ABRT_P2_SERVICE(user_data), caller, &error);
|
|
Packit |
8ea169 |
if (caller_uid == (uid_t) -1)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_gerror(invocation, error);
|
|
Packit |
8ea169 |
g_error_free(error);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
log_notice("caller_uid:%ld method:'%s'", (long)caller_uid, method_name);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "NewProblem") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
char *error = NULL;
|
|
Packit |
8ea169 |
char *problem_id = handle_new_problem(g_variant_get_child_value(parameters, 0), caller_uid, &error);
|
|
Packit |
8ea169 |
if (!problem_id)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.Failure",
|
|
Packit |
8ea169 |
error);
|
|
Packit |
8ea169 |
free(error);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
/* else */
|
|
Packit |
8ea169 |
response = g_variant_new("(s)", problem_id);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, response);
|
|
Packit |
8ea169 |
free(problem_id);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "GetProblems") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
GList *dirs = get_problem_dirs_for_uid(caller_uid, g_settings_dump_location);
|
|
Packit |
8ea169 |
response = variant_from_string_list(dirs);
|
|
Packit |
8ea169 |
list_free_with_free(dirs);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, response);
|
|
Packit |
8ea169 |
//I was told that g_dbus_method frees the response
|
|
Packit |
8ea169 |
//g_variant_unref(response);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "GetAllProblems") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/*
|
|
Packit |
8ea169 |
- so, we have UID,
|
|
Packit |
8ea169 |
- if it's 0, then we don't have to check anything and just return all directories
|
|
Packit |
8ea169 |
- if uid != 0 then we want to ask for authorization
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
if (caller_uid != 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") == PolkitYes)
|
|
Packit |
8ea169 |
caller_uid = 0;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GList * dirs = get_problem_dirs_for_uid(caller_uid, g_settings_dump_location);
|
|
Packit |
8ea169 |
response = variant_from_string_list(dirs);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
list_free_with_free(dirs);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, response);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "GetForeignProblems") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
GList * dirs = get_problem_dirs_not_accessible_by_uid(caller_uid, g_settings_dump_location);
|
|
Packit |
8ea169 |
response = variant_from_string_list(dirs);
|
|
Packit |
8ea169 |
list_free_with_free(dirs);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, response);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "ChownProblemDir") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const gchar *problem_dir;
|
|
Packit |
8ea169 |
g_variant_get(parameters, "(&s)", &problem_dir);
|
|
Packit |
8ea169 |
log_notice("problem_dir:'%s'", problem_dir);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (!allowed_problem_dir(problem_dir))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct dump_dir *dd = dd_opendir(problem_dir, DD_OPEN_FD_ONLY);
|
|
Packit |
8ea169 |
if (dd == NULL)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
perror_msg("can't open problem directory '%s'", problem_dir);
|
|
Packit |
8ea169 |
return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
int ddstat = dd_stat_for_uid(dd, caller_uid);
|
|
Packit |
8ea169 |
if (ddstat < 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (errno == ENOTDIR)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("requested directory does not exist '%s'", problem_dir);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
else
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
perror_msg("can't get stat of '%s'", problem_dir);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* It might happen that we will do chowing even if the UID is alreay fs
|
|
Packit |
8ea169 |
* owner, but DD_STAT_OWNED_BY_UID no longer denotes fs owner and this
|
|
Packit |
8ea169 |
* method has to ensure file system ownership for the uid.
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if ((ddstat & DD_STAT_ACCESSIBLE_BY_UID) == 0 &&
|
|
Packit |
8ea169 |
polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("not authorized");
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.AuthFailure",
|
|
Packit |
8ea169 |
_("Not Authorized"));
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
dd = dd_fdopendir(dd, DD_OPEN_READONLY | DD_FAIL_QUIETLY_EACCES);
|
|
Packit |
8ea169 |
if (!dd)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
return_InvalidProblemDir_error(invocation, problem_dir);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
int chown_res = dd_chown(dd, caller_uid);
|
|
Packit |
8ea169 |
if (chown_res != 0)
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.ChownError",
|
|
Packit |
8ea169 |
_("Chowning directory failed. Check system logs for more details."));
|
|
Packit |
8ea169 |
else
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, NULL);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "GetInfo") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* Parameter tuple is (sas) */
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Get 1st param - problem dir name */
|
|
Packit |
8ea169 |
const gchar *problem_dir;
|
|
Packit |
8ea169 |
g_variant_get_child(parameters, 0, "&s", &problem_dir);
|
|
Packit |
8ea169 |
log_notice("problem_dir:'%s'", problem_dir);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct dump_dir *dd = open_dump_directory(invocation, caller, caller_uid,
|
|
Packit |
8ea169 |
problem_dir, DD_OPEN_READONLY | DD_FAIL_QUIETLY_EACCES , OPEN_AUTH_ASK);
|
|
Packit |
8ea169 |
if (!dd)
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Get 2nd param - vector of element names */
|
|
Packit |
8ea169 |
GVariant *array = g_variant_get_child_value(parameters, 1);
|
|
Packit |
8ea169 |
GList *elements = string_list_from_variant(array);
|
|
Packit |
8ea169 |
g_variant_unref(array);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GVariantBuilder *builder = NULL;
|
|
Packit |
8ea169 |
for (GList *l = elements; l; l = l->next)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const char *element_name = (const char*)l->data;
|
|
Packit |
8ea169 |
char *value = dd_load_text_ext(dd, element_name, 0
|
|
Packit |
8ea169 |
| DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
|
|
Packit |
8ea169 |
| DD_FAIL_QUIETLY_ENOENT
|
|
Packit |
8ea169 |
| DD_FAIL_QUIETLY_EACCES);
|
|
Packit |
8ea169 |
log_notice("element '%s' %s", element_name, value ? "fetched" : "not found");
|
|
Packit |
8ea169 |
if (value)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (!builder)
|
|
Packit |
8ea169 |
builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* g_variant_builder_add makes a copy. No need to xstrdup here */
|
|
Packit |
8ea169 |
g_variant_builder_add(builder, "{ss}", element_name, value);
|
|
Packit |
8ea169 |
free(value);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
list_free_with_free(elements);
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
/* It is OK to call g_variant_new("(a{ss})", NULL) because */
|
|
Packit |
8ea169 |
/* G_VARIANT_TYPE_TUPLE allows NULL value */
|
|
Packit |
8ea169 |
GVariant *response = g_variant_new("(a{ss})", builder);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (builder)
|
|
Packit |
8ea169 |
g_variant_builder_unref(builder);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
log_info("GetInfo: returning value for '%s'", problem_dir);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, response);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "GetProblemData") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* Parameter tuple is (s) */
|
|
Packit |
8ea169 |
const char *problem_id;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_variant_get(parameters, "(&s)", &problem_id);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct dump_dir *dd = open_dump_directory(invocation, caller, caller_uid,
|
|
Packit |
8ea169 |
problem_id, DD_OPEN_READONLY, OPEN_AUTH_ASK);
|
|
Packit |
8ea169 |
if (!dd)
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
problem_data_t *pd = create_problem_data_from_dump_dir(dd);
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GVariantBuilder *response_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GHashTableIter pd_iter;
|
|
Packit |
8ea169 |
char *element_name;
|
|
Packit |
8ea169 |
struct problem_item *element_info;
|
|
Packit |
8ea169 |
g_hash_table_iter_init(&pd_iter, pd);
|
|
Packit |
8ea169 |
while (g_hash_table_iter_next(&pd_iter, (void**)&element_name, (void**)&element_info))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
unsigned long size = 0;
|
|
Packit |
8ea169 |
if (problem_item_get_size(element_info, &size) != 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("Can't get stat of : '%s'", element_info->content);
|
|
Packit |
8ea169 |
continue;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_variant_builder_add(response_builder, "{s(its)}",
|
|
Packit |
8ea169 |
element_name,
|
|
Packit |
8ea169 |
(gint32)element_info->flags,
|
|
Packit |
8ea169 |
(guint64)size,
|
|
Packit |
8ea169 |
element_info->content);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GVariant *response = g_variant_new("(a{s(its)})", response_builder);
|
|
Packit |
8ea169 |
g_variant_builder_unref(response_builder);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
problem_data_free(pd);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, response);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "SetElement") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const char *problem_id;
|
|
Packit |
8ea169 |
const char *element;
|
|
Packit |
8ea169 |
const char *value;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_variant_get(parameters, "(&s&s&s)", &problem_id, &element, &value);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (!allowed_problem_element(invocation, element))
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct dump_dir *dd = open_directory_for_modification_of_element(
|
|
Packit |
8ea169 |
invocation, caller_uid, problem_id, element);
|
|
Packit |
8ea169 |
if (!dd)
|
|
Packit |
8ea169 |
/* Already logged from open_directory_for_modification_of_element() */
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Is it good idea to make it static? Is it possible to change the max size while a single run? */
|
|
Packit |
8ea169 |
const double max_dir_size = g_settings_nMaxCrashReportsSize * (1024 * 1024);
|
|
Packit |
8ea169 |
const long item_size = dd_get_item_size(dd, element);
|
|
Packit |
8ea169 |
if (item_size < 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("Can't get size of '%s/%s'", problem_id, element);
|
|
Packit |
8ea169 |
char *error = xasprintf(_("Can't get size of '%s'"), element);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.Failure",
|
|
Packit |
8ea169 |
error);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
const double requested_size = (double)strlen(value) - item_size;
|
|
Packit |
8ea169 |
/* Don't want to check the size limit in case of reducing of size */
|
|
Packit |
8ea169 |
if (requested_size > 0
|
|
Packit |
8ea169 |
&& requested_size > (max_dir_size - get_dirsize(g_settings_dump_location)))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("No problem space left in '%s' (requested Bytes %f)", problem_id, requested_size);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.Failure",
|
|
Packit |
8ea169 |
_("No problem space left"));
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
else
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
dd_save_text(dd, element, value);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, NULL);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "DeleteElement") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const char *problem_id;
|
|
Packit |
8ea169 |
const char *element;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_variant_get(parameters, "(&s&s)", &problem_id, &element);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (!allowed_problem_element(invocation, element))
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct dump_dir *dd = open_directory_for_modification_of_element(
|
|
Packit |
8ea169 |
invocation, caller_uid, problem_id, element);
|
|
Packit |
8ea169 |
if (!dd)
|
|
Packit |
8ea169 |
/* Already logged from open_directory_for_modification_of_element() */
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
const int res = dd_delete_item(dd, element);
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (res != 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_notice("Can't delete the element '%s' from the problem directory '%s'", element, problem_id);
|
|
Packit |
8ea169 |
char *error = xasprintf(_("Can't delete the element '%s' from the problem directory '%s'"), element, problem_id);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_dbus_error(invocation,
|
|
Packit |
8ea169 |
"org.freedesktop.problems.Failure",
|
|
Packit |
8ea169 |
error);
|
|
Packit |
8ea169 |
free(error);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, NULL);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "TestElementExists") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const char *problem_id;
|
|
Packit |
8ea169 |
const char *element;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_variant_get(parameters, "(&s&s)", &problem_id, &element);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (!allowed_problem_element(invocation, element))
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct dump_dir *dd = open_dump_directory(invocation, caller, caller_uid,
|
|
Packit |
8ea169 |
problem_id, DD_OPEN_READONLY, OPEN_AUTH_ASK);
|
|
Packit |
8ea169 |
if (!dd)
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
int ret = dd_exist(dd, element);
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GVariant *response = g_variant_new("(b)", ret);
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, response);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "DeleteProblem") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* Dbus parameters are always tuples.
|
|
Packit |
8ea169 |
* In this case, it's (as) - a tuple of one element (array of strings).
|
|
Packit |
8ea169 |
* Need to fetch the array:
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
GVariant *array = g_variant_get_child_value(parameters, 0);
|
|
Packit |
8ea169 |
GList *problem_dirs = string_list_from_variant(array);
|
|
Packit |
8ea169 |
g_variant_unref(array);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
for (GList *l = problem_dirs; l; l = l->next)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const char *dir_name = (const char*)l->data;
|
|
Packit |
8ea169 |
log_notice("dir_name:'%s'", dir_name);
|
|
Packit |
8ea169 |
if (!allowed_problem_dir(dir_name))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
return_InvalidProblemDir_error(invocation, dir_name);
|
|
Packit |
8ea169 |
goto ret;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
for (GList *l = problem_dirs; l; l = l->next)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const char *dir_name = (const char*)l->data;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
struct dump_dir *dd = open_dump_directory(invocation, caller, caller_uid,
|
|
Packit |
8ea169 |
dir_name, /*Read/Write*/0, OPEN_FAIL_NO_REPLY | OPEN_AUTH_ASK);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (dd)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (dd_delete(dd) != 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
error_msg("Failed to delete problem directory '%s'", dir_name);
|
|
Packit |
8ea169 |
dd_close(dd);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, NULL);
|
|
Packit |
8ea169 |
ret:
|
|
Packit |
8ea169 |
list_free_with_free(problem_dirs);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "FindProblemByElementInTimeRange") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const gchar *element;
|
|
Packit |
8ea169 |
const gchar *value;
|
|
Packit |
8ea169 |
glong timestamp_from;
|
|
Packit |
8ea169 |
glong timestamp_to;
|
|
Packit |
8ea169 |
gboolean all;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_variant_get_child(parameters, 0, "&s", &element);
|
|
Packit |
8ea169 |
g_variant_get_child(parameters, 1, "&s", &value);
|
|
Packit |
8ea169 |
g_variant_get_child(parameters, 2, "x", ×tamp_from);
|
|
Packit |
8ea169 |
g_variant_get_child(parameters, 3, "x", ×tamp_to);
|
|
Packit |
8ea169 |
g_variant_get_child(parameters, 4, "b", &all;;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (!allowed_problem_element(invocation, element))
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (all && polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") == PolkitYes)
|
|
Packit |
8ea169 |
caller_uid = 0;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GList *dirs = get_problem_dirs_for_element_in_time(caller_uid, element, value, timestamp_from,
|
|
Packit |
8ea169 |
timestamp_to);
|
|
Packit |
8ea169 |
response = variant_from_string_list(dirs);
|
|
Packit |
8ea169 |
list_free_with_free(dirs);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, response);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (g_strcmp0(method_name, "Quit") == 0)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
g_dbus_method_invocation_return_value(invocation, NULL);
|
|
Packit |
8ea169 |
g_main_loop_quit(loop);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void handle_abrtd_problem_signals(GDBusConnection *connection,
|
|
Packit |
8ea169 |
const gchar *sender_name,
|
|
Packit |
8ea169 |
const gchar *object_path,
|
|
Packit |
8ea169 |
const gchar *interface_name,
|
|
Packit |
8ea169 |
const gchar *signal_name,
|
|
Packit |
8ea169 |
GVariant *parameters,
|
|
Packit |
8ea169 |
gpointer user_data)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const char *dir;
|
|
Packit |
8ea169 |
g_variant_get (parameters, "(&s)", &dir;;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
log_debug("Caught '%s' signal from abrtd: '%s'", signal_name, dir);
|
|
Packit |
8ea169 |
AbrtP2Service *service = ABRT_P2_SERVICE(user_data);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GError *error = NULL;
|
|
Packit |
8ea169 |
AbrtP2Object *obj = abrt_p2_service_get_entry_for_problem(service,
|
|
Packit |
8ea169 |
dir,
|
|
Packit |
8ea169 |
ABRT_P2_SERVICE_ENTRY_LOOKUP_OPTIONAL,
|
|
Packit |
8ea169 |
&error);
|
|
Packit |
8ea169 |
if (error)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_warning("Cannot notify '%s': failed to find entry: %s", dir, error->message);
|
|
Packit |
8ea169 |
g_error_free(error);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (obj == NULL)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
AbrtP2Entry *entry = abrt_p2_entry_new_with_state(xstrdup(dir), ABRT_P2_ENTRY_STATE_COMPLETE);
|
|
Packit |
8ea169 |
if (entry == NULL)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_warning("Cannot notify '%s': failed to access data", dir);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
obj = abrt_p2_service_register_entry(service, entry, &error);
|
|
Packit |
8ea169 |
if (error)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_warning("Cannot notify '%s': failed to register entry: %s", dir, error->message);
|
|
Packit |
8ea169 |
g_error_free(error);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
AbrtP2Entry *entry = ABRT_P2_ENTRY(abrt_p2_object_get_node(obj));
|
|
Packit |
8ea169 |
if (abrt_p2_entry_state(entry) != ABRT_P2_ENTRY_STATE_COMPLETE)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_debug("Not notifying temporary/deleted problem directory: %s", dir);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
abrt_p2_service_notify_entry_object(service, obj, &error);
|
|
Packit |
8ea169 |
if (error)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
log_warning("Failed to notify '%s': %s", dir, error->message);
|
|
Packit |
8ea169 |
g_error_free(error);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static gboolean on_timeout_cb(gpointer user_data)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
g_main_loop_quit(loop);
|
|
Packit |
8ea169 |
return TRUE;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static const GDBusInterfaceVTable interface_vtable =
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
.method_call = handle_method_call,
|
|
Packit |
8ea169 |
.get_property = NULL,
|
|
Packit |
8ea169 |
.set_property = NULL,
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void on_bus_acquired(GDBusConnection *connection,
|
|
Packit |
8ea169 |
const gchar *name,
|
|
Packit |
8ea169 |
gpointer user_data)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
guint registration_id;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
registration_id = g_dbus_connection_register_object(connection,
|
|
Packit |
8ea169 |
ABRT_DBUS_OBJECT,
|
|
Packit |
8ea169 |
introspection_data->interfaces[0],
|
|
Packit |
8ea169 |
&interface_vtable,
|
|
Packit |
8ea169 |
user_data,
|
|
Packit |
8ea169 |
NULL, /* user_data_free_func */
|
|
Packit |
8ea169 |
NULL); /* GError** */
|
|
Packit |
8ea169 |
g_assert(registration_id > 0);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GError *error = NULL;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
int r = abrt_p2_service_register_objects(ABRT_P2_SERVICE(user_data), connection, &error);
|
|
Packit |
8ea169 |
if (r == 0 || r == -EALREADY)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
g_signal_crash = g_dbus_connection_signal_subscribe(connection,
|
|
Packit |
8ea169 |
NULL,
|
|
Packit |
8ea169 |
"org.freedesktop.Problems2",
|
|
Packit |
8ea169 |
"ImportProblem",
|
|
Packit |
8ea169 |
"/org/freedesktop/Problems2",
|
|
Packit |
8ea169 |
NULL,
|
|
Packit |
8ea169 |
G_DBUS_SIGNAL_FLAGS_NONE,
|
|
Packit |
8ea169 |
handle_abrtd_problem_signals,
|
|
Packit |
8ea169 |
user_data, NULL);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_signal_dup_crash = g_dbus_connection_signal_subscribe(connection,
|
|
Packit |
8ea169 |
NULL,
|
|
Packit |
8ea169 |
"org.freedesktop.Problems2",
|
|
Packit |
8ea169 |
"ReloadProblem",
|
|
Packit |
8ea169 |
"/org/freedesktop/Problems2",
|
|
Packit |
8ea169 |
NULL,
|
|
Packit |
8ea169 |
G_DBUS_SIGNAL_FLAGS_NONE,
|
|
Packit |
8ea169 |
handle_abrtd_problem_signals,
|
|
Packit |
8ea169 |
user_data, NULL);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
run_timeout();
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
error_msg("Failed to register Problems2 Objects: %s", error->message);
|
|
Packit |
8ea169 |
g_error_free(error);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_main_loop_quit(loop);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* not used
|
|
Packit |
8ea169 |
static void on_name_acquired (GDBusConnection *connection,
|
|
Packit |
8ea169 |
const gchar *name,
|
|
Packit |
8ea169 |
gpointer user_data)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void on_name_lost(GDBusConnection *connection,
|
|
Packit |
8ea169 |
const gchar *name,
|
|
Packit |
8ea169 |
gpointer user_data)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
g_print(_("The name '%s' has been lost, please check if other "
|
|
Packit |
8ea169 |
"service owning the name is not running.\n"), name);
|
|
Packit |
8ea169 |
exit(1);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
void configure_problems2_service(AbrtP2Service *p2_service)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
struct env_option {
|
|
Packit |
8ea169 |
const char *name;
|
|
Packit |
8ea169 |
void (*setter_unsigned)(AbrtP2Service *s, uid_t u, unsigned v);
|
|
Packit |
8ea169 |
void (*setter_off_t)(AbrtP2Service *s, uid_t u, off_t v);
|
|
Packit |
8ea169 |
} env_options[] = {
|
|
Packit |
8ea169 |
{ .name = "ABRT_DBUS_USER_CLIENTS",
|
|
Packit |
8ea169 |
.setter_unsigned = abrt_p2_service_set_user_clients_limit,
|
|
Packit |
8ea169 |
},
|
|
Packit |
8ea169 |
{ .name = "ABRT_DBUS_ELEMENTS_LIMIT",
|
|
Packit |
8ea169 |
.setter_unsigned = abrt_p2_service_set_elements_limit,
|
|
Packit |
8ea169 |
},
|
|
Packit |
8ea169 |
{ .name = "ABRT_DBUS_PROBLEMS_LIMIT",
|
|
Packit |
8ea169 |
.setter_unsigned = abrt_p2_service_set_user_problems_limit,
|
|
Packit |
8ea169 |
},
|
|
Packit |
8ea169 |
{ .name = "ABRT_DBUS_NEW_PROBLEM_THROTTLING_MAGNITUDE",
|
|
Packit |
8ea169 |
.setter_unsigned = abrt_p2_service_set_new_problem_throttling_magnitude,
|
|
Packit |
8ea169 |
},
|
|
Packit |
8ea169 |
{ .name = "ABRT_DBUS_NEW_PROBLEMS_BATCH",
|
|
Packit |
8ea169 |
.setter_unsigned = abrt_p2_service_set_new_problems_batch,
|
|
Packit |
8ea169 |
},
|
|
Packit |
8ea169 |
{ .name = "ABRT_DBUS_DATA_SIZE_LIMIT",
|
|
Packit |
8ea169 |
.setter_off_t = abrt_p2_service_set_data_size_limit,
|
|
Packit |
8ea169 |
},
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
for (size_t i = 0; i < sizeof(env_options)/sizeof(env_options[0]); ++i)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const char *value = getenv(env_options[i].name);
|
|
Packit |
8ea169 |
if (value == NULL)
|
|
Packit |
8ea169 |
continue;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
errno = 0;
|
|
Packit |
8ea169 |
char *end = NULL;
|
|
Packit |
8ea169 |
const unsigned long limit = strtoul(value, &end, 10);
|
|
Packit |
8ea169 |
if (errno || value == end || *end != '\0')
|
|
Packit |
8ea169 |
error_msg_and_die("not a number in environment '%s': %s", env_options[i].name, value);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (env_options[i].setter_unsigned)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (limit > UINT_MAX)
|
|
Packit |
8ea169 |
error_msg_and_die("an out of range number in environment '%s': %s", env_options[i].name, value);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
env_options[i].setter_unsigned(p2_service, (uid_t)-1, (unsigned int)limit);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
else if (env_options[i].setter_off_t)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const off_t off_t_limit = limit;
|
|
Packit |
8ea169 |
env_options[i].setter_off_t(p2_service, (uid_t)-1, off_t_limit);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
else
|
|
Packit |
8ea169 |
error_msg_and_die("Bug: invalid parser of environment values");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
log_debug("Used environment variable: %s", env_options[i].name);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
int main(int argc, char *argv[])
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* I18n */
|
|
Packit |
8ea169 |
setlocale(LC_ALL, "");
|
|
Packit |
8ea169 |
#if ENABLE_NLS
|
|
Packit |
8ea169 |
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
Packit |
8ea169 |
textdomain(PACKAGE);
|
|
Packit |
8ea169 |
#endif
|
|
Packit |
8ea169 |
guint owner_id;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
abrt_init(argv);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
const char *program_usage_string = _(
|
|
Packit |
8ea169 |
"& [options]"
|
|
Packit |
8ea169 |
);
|
|
Packit |
8ea169 |
enum {
|
|
Packit |
8ea169 |
OPT_v = 1 << 0,
|
|
Packit |
8ea169 |
OPT_t = 1 << 1,
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
/* Keep enum above and order of options below in sync! */
|
|
Packit |
8ea169 |
struct options program_options[] = {
|
|
Packit |
8ea169 |
OPT__VERBOSE(&g_verbose),
|
|
Packit |
8ea169 |
OPT_INTEGER('t', NULL, &g_timeout_value, _("Exit after NUM seconds of inactivity")),
|
|
Packit |
8ea169 |
OPT_END()
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
/*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
export_abrt_envvars(0);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* When dbus daemon starts us, it doesn't set PATH
|
|
Packit |
8ea169 |
* (I saw it set only DBUS_STARTER_ADDRESS and DBUS_STARTER_BUS_TYPE).
|
|
Packit |
8ea169 |
* In this case, set something sane:
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
const char *env_path = getenv("PATH");
|
|
Packit |
8ea169 |
if (!env_path || !env_path[0])
|
|
Packit |
8ea169 |
putenv((char*)"PATH=/usr/sbin:/usr/bin:/sbin:/bin");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
msg_prefix = "abrt-dbus"; /* for log_warning(), error_msg() and such */
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (getuid() != 0)
|
|
Packit |
8ea169 |
error_msg_and_die(_("This program must be run as root."));
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
glib_init();
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* We are lazy here - we don't want to manually provide
|
|
Packit |
8ea169 |
* the introspection data structures - so we just build
|
|
Packit |
8ea169 |
* them from XML.
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
GError *err = NULL;
|
|
Packit |
8ea169 |
introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &err;;
|
|
Packit |
8ea169 |
if (err != NULL)
|
|
Packit |
8ea169 |
error_msg_and_die("Invalid D-Bus interface: %s", err->message);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
AbrtP2Service *p2_service = abrt_p2_service_new(&err;;
|
|
Packit |
8ea169 |
if (p2_service == NULL)
|
|
Packit |
8ea169 |
error_msg_and_die("Failed to initialize Problems2 service: %s", err->message);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_signal_connect(p2_service, "new-client-connected", G_CALLBACK(kill_timeout), NULL);
|
|
Packit |
8ea169 |
g_signal_connect(p2_service, "all-clients-disconnected", G_CALLBACK(run_timeout), NULL);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
DBusConnection *con = dbus_connection_open("org.freedesktop.DBus", NULL);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* FIXME: I'm sorry but I'm not able to find out why the maximum message
|
|
Packit |
8ea169 |
* length limit is around 200kiB but the official configuration says
|
|
Packit |
8ea169 |
* something about 128MiB. Is it a bug in this code? */
|
|
Packit |
8ea169 |
/*long max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;*/
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
long max_message_unix_fds = 16;
|
|
Packit |
8ea169 |
if (con != NULL)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/*max_message_size = dbus_connection_get_max_message_size(con);*/
|
|
Packit |
8ea169 |
max_message_unix_fds = dbus_connection_get_max_message_unix_fds(con);
|
|
Packit |
8ea169 |
dbus_connection_close(con);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
/*abrt_p2_service_set_max_message_size(p2_service, max_message_size);*/
|
|
Packit |
8ea169 |
abrt_p2_service_set_max_message_size(p2_service, 200000L);
|
|
Packit |
8ea169 |
abrt_p2_service_set_max_message_unix_fds(p2_service, max_message_unix_fds);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
configure_problems2_service(p2_service);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
|
|
Packit |
8ea169 |
ABRT_DBUS_NAME,
|
|
Packit |
8ea169 |
G_BUS_NAME_OWNER_FLAGS_NONE,
|
|
Packit |
8ea169 |
on_bus_acquired,
|
|
Packit |
8ea169 |
NULL,
|
|
Packit |
8ea169 |
on_name_lost,
|
|
Packit |
8ea169 |
p2_service,
|
|
Packit |
8ea169 |
g_object_unref);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* initialize the g_settings_dump_location */
|
|
Packit |
8ea169 |
load_abrt_conf();
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
loop = g_main_loop_new(NULL, FALSE);
|
|
Packit |
8ea169 |
g_main_loop_run(loop);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
log_notice("Cleaning up");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_bus_unown_name(owner_id);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_dbus_node_info_unref(introspection_data);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
free_abrt_conf_data();
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return 0;
|
|
Packit |
8ea169 |
}
|