/* Copyright (C) 2011 ABRT team Copyright (C) 2010 RedHat Inc This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "event_config.h" #include "workflow.h" #include "internal_libreport.h" struct workflow { config_item_info_t *info; int priority; // direct correlation: higher number -> higher priority GList *events; //list of event_option_t }; GHashTable *g_workflow_list; workflow_t *new_workflow(const char *name) { workflow_t *w = xzalloc(sizeof(*w)); w->info = new_config_info(name); return w; } void free_workflow(workflow_t *w) { if (!w) return; free_config_info(w->info); g_list_free_full(w->events, (GDestroyNotify)free_event_config); free(w); } void free_workflow_list(GHashTable **wl) { if (*wl != NULL) { g_hash_table_destroy(*wl); *wl = NULL; } } workflow_t *get_workflow(const char *name) { if (!g_workflow_list) return NULL; /* @@ FIXME: SYMLINKS@!!! if (g_event_config_symlinks) { char *link = g_hash_table_lookup(g_event_config_symlinks, name); if (link) name = link; } */ return g_hash_table_lookup(g_workflow_list, name); } static gint file_obj_cmp(file_obj_t *file, const char *filename) { gint cmp = strcmp(file->filename, filename); return cmp; } static void load_workflow_config(const char *name, GList *available_wfs, GHashTable *wf_list) { GList *wf_file = g_list_find_custom(available_wfs, name, (GCompareFunc)file_obj_cmp); if (wf_file) { file_obj_t *file = (file_obj_t *)wf_file->data; workflow_t *workflow = new_workflow(file->filename); load_workflow_description_from_file(workflow, file->fullpath); log_info("Adding '%s' to workflows\n", file->filename); g_hash_table_insert(wf_list, xstrdup(file->filename), workflow); } } GHashTable *load_workflow_config_data_from_list(GList *wf_names, const char *path) { GList *wfs = wf_names; GHashTable *wf_list = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, (GDestroyNotify) free_workflow ); if (path == NULL) path = WORKFLOWS_DIR; GList *workflow_files = get_file_list(path, "xml"); while(wfs) { load_workflow_config((const char *)wfs->data, workflow_files, wf_list); wfs = g_list_next(wfs); } free_file_list(workflow_files); return wf_list; } GHashTable *load_workflow_config_data(const char *path) { if (g_workflow_list) return g_workflow_list; if (g_workflow_list == NULL) { g_workflow_list = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, (GDestroyNotify) free_workflow ); } if (path == NULL) path = WORKFLOWS_DIR; GList *workflow_files = get_file_list(path, "xml"); while (workflow_files) { file_obj_t *file = (file_obj_t *)workflow_files->data; workflow_t *workflow = get_workflow(file->filename); bool nw_workflow = (!workflow); if (nw_workflow) workflow = new_workflow(file->filename); load_workflow_description_from_file(workflow, file->fullpath); if (nw_workflow) g_hash_table_replace(g_workflow_list, xstrdup(wf_get_name(workflow)), workflow); free_file_obj(file); workflow_files = g_list_delete_link(workflow_files, workflow_files); } return g_workflow_list; } config_item_info_t *workflow_get_config_info(workflow_t *w) { return w->info; } GList *wf_get_event_list(workflow_t *w) { return w->events; } GList *wf_get_event_names(workflow_t *w) { GList *wf_event_list = wf_get_event_list(w); GList *event_names = NULL; while(wf_event_list) { event_names = g_list_append(event_names, xstrdup(ec_get_name(wf_event_list->data))); wf_event_list = g_list_next(wf_event_list); } return event_names; } const char *wf_get_name(workflow_t *w) { return ci_get_name(workflow_get_config_info(w)); } const char *wf_get_screen_name(workflow_t *w) { return ci_get_screen_name(workflow_get_config_info(w)); } const char *wf_get_description(workflow_t *w) { return ci_get_description(workflow_get_config_info(w)); } const char *wf_get_long_desc(workflow_t *w) { return ci_get_long_desc(workflow_get_config_info(w)); } int wf_get_priority(workflow_t *w) { return w->priority; } void wf_set_screen_name(workflow_t *w, const char* screen_name) { ci_set_screen_name(workflow_get_config_info(w), screen_name); } void wf_set_description(workflow_t *w, const char* description) { ci_set_description(workflow_get_config_info(w), description); } void wf_set_long_desc(workflow_t *w, const char* long_desc) { ci_set_long_desc(workflow_get_config_info(w), long_desc); } void wf_add_event(workflow_t *w, event_config_t *ec) { w->events = g_list_append(w->events, ec); log_info("added to ev list: '%s'", ec_get_screen_name(ec)); } void wf_set_priority(workflow_t *w, int priority) { w->priority = priority; } /* * Returns a negative integer if the first value comes before the second, 0 if * they are equal, or a positive integer if the first value comes after the * second. */ int wf_priority_compare(const workflow_t *first, const workflow_t *second) { return second->priority - first->priority; }