Jiri Moskovcak <[email protected]> writes:
> ---
> src/gui-gtk/Makefile.am | 6 +-
> src/gui-gtk/main.c | 206
> +++++++++++++++++++++++++++++++++--------------
> 2 files changed, 151 insertions(+), 61 deletions(-)
>
> diff --git a/src/gui-gtk/main.c b/src/gui-gtk/main.c
> index f34ff3f..777d9df 100644
> --- a/src/gui-gtk/main.c
> +++ b/src/gui-gtk/main.c
> @@ -19,11 +19,13 @@
> #include <gtk/gtk.h>
> #include <gdk/gdkkeysyms.h>
> #include <sys/inotify.h>
> +#include <gio/gio.h> //dbus
> #if HAVE_LOCALE_H
> # include <locale.h>
> #endif
> #include <internal_libreport_gtk.h>
> #include "libabrt.h"
> +#include "abrt-dbus.h"
>
> #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 22
> # define GDK_KEY_Delete GDK_Delete
> @@ -31,6 +33,7 @@
> #endif
>
> static void scan_dirs_and_add_to_dirlist(void);
> +static void rescan_and_refresh(void);
>
>
> static const char help_uri[] = "http://docs.fedoraproject.org/en-US/"
> @@ -59,6 +62,8 @@ enum
> NUM_COLUMNS
> };
>
> +gint g_authorize; /* wheter to try to authorize when getting list of
> problems */
also static
> //FIXME: maybe we can use strrchr and make this faster...
> static char *get_last_line(const char* msg)
> {
> @@ -84,22 +89,60 @@ static char *get_last_line(const char* msg)
> return xstrndup(start, end - start);
> }
>
> -static void add_directory_to_dirlist(const char *dirname)
> +static problem_data_t* get_problem_data_dbus(const char *problem_dir_path,
> GError *error)
> +{
> + problem_data_t *pd;
> + char *key, *val;
> +
> + GDBusProxy *proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
> + G_DBUS_PROXY_FLAGS_NONE,
> + NULL,
> + ABRT_DBUS_NAME,
> + ABRT_DBUS_OBJECT,
> + ABRT_DBUS_IFACE,
> + NULL,
> + &error);
> +
> + GVariant *result = g_dbus_proxy_call_sync(proxy,
> + "GetInfo",
> + g_variant_new("(s)",
> problem_dir_path),
> + G_DBUS_CALL_FLAGS_NONE,
> + -1,
> + NULL,
> + &error);
> +
> + pd = new_problem_data();
> +
> + GVariantIter *iter;
> + g_variant_get(result, "(a{ss})", &iter);
> + while (g_variant_iter_loop(iter, "{ss}", &key, &val))
> + {
> + add_to_problem_data(pd, key, val);
> + }
> + return pd;
> +}
> +
> +static void add_directory_to_dirlist(gpointer dir, gpointer data)
why gpointer dir? use const char *dir
> {
> + const char *dirname = (const char *)dir;
> /* Silently ignore *any* errors, not only EACCES.
> * We saw "lock file is locked by process PID" error
> * when we raced with wizard.
> */
> int sv_logmode = logmode;
> logmode = 0;
> - struct dump_dir *dd = dd_opendir(dirname, DD_OPEN_READONLY |
> DD_FAIL_QUIETLY_EACCES);
> logmode = sv_logmode;
> + /*
> + struct dump_dir *dd = dd_opendir(dirname, DD_OPEN_READONLY |
> DD_FAIL_QUIETLY_EACCES);
> +
> if (!dd)
> return;
> + */
do not coment it out; remove it
> + problem_data_t *pd = get_problem_data_dbus(dir, NULL);
> char time_buf[sizeof("YYYY-MM-DD hh:mm:ss")];
> time_buf[0] = '\0';
> - char *time_str = dd_load_text(dd, FILENAME_TIME);
> + const char *time_str = get_problem_item_content_or_NULL(pd,
> FILENAME_TIME);
> time_t t = 0;
> if (time_str && time_str[0])
> {
> @@ -108,40 +151,18 @@ static void add_directory_to_dirlist(const char
> *dirname)
> size_t time_len = strftime(time_buf, sizeof(time_buf)-1, "%Y-%m-%d
> %H:%M", ptm);
> time_buf[time_len] = '\0';
> }
> - free(time_str);
> -
>
> - char *not_reportable_reason = dd_load_text_ext(dd,
> FILENAME_NOT_REPORTABLE, 0
> - |
> DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
> - | DD_FAIL_QUIETLY_ENOENT
> - | DD_FAIL_QUIETLY_EACCES);
> - char *reason = NULL;
> - if (!not_reportable_reason)
> - reason = dd_load_text(dd, FILENAME_REASON);
> + const char *not_reportable_reason = get_problem_item_content_or_NULL(pd,
> FILENAME_NOT_REPORTABLE);
> + const char *reason = get_problem_item_content_or_NULL(pd,
> FILENAME_REASON);
> + //if (!not_reportable_reason)
> + // reason = get_problem_item_content_or_NULL(pd, FILENAME_REASON);
remove comments
> /* the source of the problem:
> * - first we try to load component, as we use it on Fedora
> */
> - char *source = dd_load_text_ext(dd, FILENAME_COMPONENT, 0
> - | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
> - | DD_FAIL_QUIETLY_ENOENT
> - | DD_FAIL_QUIETLY_EACCES
> - );
> - /* if we don't have component, we fallback to executable */
> - if (!source)
> - {
> - source = dd_load_text_ext(dd, FILENAME_EXECUTABLE, 0
> - | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
> - | DD_FAIL_QUIETLY_ENOENT
> - | DD_FAIL_QUIETLY_EACCES
> - );
> - }
> + const char *source = get_problem_item_content_or_NULL(pd, "source");
>
> - char *msg = dd_load_text_ext(dd, FILENAME_REPORTED_TO, 0
> - | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
> - | DD_FAIL_QUIETLY_ENOENT
> - | DD_FAIL_QUIETLY_EACCES
> - );
> + const char *msg = get_problem_item_content_or_NULL(pd,
> FILENAME_REPORTED_TO);
>
>
> GtkListStore *list_store;
> @@ -166,16 +187,55 @@ static void add_directory_to_dirlist(const char
> *dirname)
> COLUMN_DUMP_DIR, dirname,
> COLUMN_REPORTED_TO, msg ? subm_status : NULL,
> -1);
> - /* this is safe, subm_status is either null or malloced string from
> get_last_line */
> - free(not_reportable_reason);
> - free(subm_status);
> - free(msg);
> - free(reason);
>
> - dd_close(dd);
> + free_problem_data(pd);
> +
> VERB1 log("added: %s", dirname);
> }
>
> +GList *get_problems_over_dbus(const char *dump_location, GError *error)
> +{
> + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
> + G_DBUS_PROXY_FLAGS_NONE,
> + NULL,
> + ABRT_DBUS_NAME,
> + ABRT_DBUS_OBJECT,
> + ABRT_DBUS_IFACE,
> + NULL,
> + &error);
> +
> +/*
> + GDBusProxy * proxy = g_dbus_proxy_new_sync(connection,
> + G_DBUS_PROXY_FLAGS_NONE,
> + NULL,
> + "org.freedesktop.problems",
> + "/org/freedesktop/problems",
> + "org.freedesktop.problems",
> + NULL,
> + &error);
> +*/
remove comment
> + GVariant *result = g_dbus_proxy_call_sync(proxy,
> + g_authorize ? "GetAllProblems" :
> "GetProblems",
> + g_variant_new("(s)", dump_location),
> + G_DBUS_CALL_FLAGS_NONE,
> + -1,
> + NULL,
> + &error);
> + GList *list = NULL;
> + GVariantIter *iter;
> + gchar *str;
> + g_variant_get(result, "(as)", &iter);
> + while (g_variant_iter_loop(iter, "s", &str))
> + {
> + VERB1 log("adding: %s\n", str);
> + list = g_list_prepend(list, xstrdup(str));
> + }
> + g_variant_iter_free(iter);
> +
> + return list;
> +}
> +
> static void rescan_dirs_and_add_to_dirlist(void)
> {
> gtk_list_store_clear(s_dumps_list_store);
> @@ -344,6 +404,35 @@ static gboolean on_focus_cb(
> return false; /* propagate the event further */
> }
>
> +static int chown_dir_over_dbus(const char *problem_dir_path)
> +{
> + GError *error;
> + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
> + G_DBUS_PROXY_FLAGS_NONE,
> + NULL,
> + ABRT_DBUS_NAME,
> + ABRT_DBUS_OBJECT,
> + ABRT_DBUS_IFACE,
> + NULL,
> + &error);
> +
> + g_dbus_proxy_call_sync(proxy,
> + "ChownProblemDir",
> + g_variant_new("(s)", problem_dir_path),
> + G_DBUS_CALL_FLAGS_NONE,
> + -1,
> + NULL,
> + &error);
> +
> + if (error)
> + {
> + //TODO show a warning dialog here or on the higher level?
> + error_msg(_("Can't chown '%s': %s"),problem_dir_path,
> error->message);
> + return 1;
> + }
> + return 0;
> +}
total off indentation and without freeing *error*
> static void on_row_activated_cb(GtkTreeView *treeview, GtkTreePath *path,
> GtkTreeViewColumn *column, gpointer user_data)
> {
> GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
> @@ -358,8 +447,13 @@ static void on_row_activated_cb(GtkTreeView *treeview,
> GtkTreePath *path, GtkTre
>
> const char *dirname = g_value_get_string(&d_dir);
>
> - report_problem_in_dir(dirname,
> + if (chown_dir_over_dbus(dirname) == 0)
> + {
> + report_problem_in_dir(dirname,
> LIBREPORT_ANALYZE | LIBREPORT_NOWAIT |
> LIBREPORT_GETPID);
> + }
> + //else
> + // TODO: show a warning dialog
> }
> }
> }
> @@ -392,6 +486,12 @@ static void on_column_change_cb(GtkTreeSortable
> *sortable, gpointer user_data)
> free(value);
> }
>
> +static void on_show_all_cb(GtkToggleButton *togglebutton, gpointer data)
> +{
> + g_authorize = gtk_toggle_button_get_active(togglebutton);
> + rescan_and_refresh();
> +}
> +
> static void load_sort_setting(GtkTreeSortable *sortable)
> {
> const char *name, *value;
> @@ -754,10 +854,14 @@ static GtkWidget *create_main_window(void)
> gtk_misc_set_alignment(GTK_MISC(not_subm_lbl), 0, 0);
> gtk_label_set_markup(GTK_LABEL(not_subm_lbl), _("<b>Not submitted
> reports</b>"));
>
> + GtkWidget *show_all_btn = gtk_check_button_new_with_label(_("Show all
> problems"));
> + g_signal_connect(show_all_btn, "toggled", G_CALLBACK(on_show_all_cb),
> NULL);
> +
> /* add label for not submitted tree view */
> gtk_box_pack_start(GTK_BOX(not_subm_vbox), not_subm_lbl, false, false,
> 0);
> gtk_box_pack_start(GTK_BOX(not_subm_vbox), new_problems_scroll_win,
> true, true, 0);
> gtk_box_pack_start(GTK_BOX(main_vbox), not_subm_vbox, true, true, 0);
> + gtk_box_pack_start(GTK_BOX(main_vbox), show_all_btn, false, false, 0);
>
> /* Two tree views */
> s_treeview = gtk_tree_view_new();
> @@ -988,27 +1092,11 @@ static gboolean handle_inotify_cb(GIOChannel *gio,
> GIOCondition condition, gpoin
>
> static void scan_directory_and_add_to_dirlist(const char *path)
> {
> - DIR *dp = opendir(path);
> - if (!dp)
> - {
> - /* We don't want to yell if, say, $HOME/.abrt/spool doesn't exist */
> - //perror_msg("Can't open directory '%s'", path);
> - return;
> - }
> -
> - struct dirent *dent;
> - while ((dent = readdir(dp)) != NULL)
> - {
> - if (dot_or_dotdot(dent->d_name))
> - continue; /* skip "." and ".." */
> -
> - char *full_name = concat_path_file(path, dent->d_name);
> - struct stat statbuf;
> - if (stat(full_name, &statbuf) == 0 && S_ISDIR(statbuf.st_mode))
> - add_directory_to_dirlist(full_name);
> - free(full_name);
> - }
> - closedir(dp);
> + GList *problem_dirs = get_problems_over_dbus(path, NULL);
> + if (problem_dirs)
> + g_list_foreach(problem_dirs, (GFunc)add_directory_to_dirlist, NULL);
> + else
> + error_msg_and_die(_("Can't get problem list from abrt-dbus"));
>
> if (inotify_fd >= 0 && inotify_add_watch(inotify_fd, path, 0
> // | IN_ATTRIB // Metadata changed
--
Nikola