diff options
Diffstat (limited to 'src')
61 files changed, 95 insertions, 8625 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 07230880..84499069 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1 +1 @@ -SUBDIRS = include lib report-python hooks btparser daemon gtk-helpers applet gui-gtk cli plugins gui-wizard-gtk retrace +SUBDIRS = include lib hooks btparser daemon applet gui-gtk cli plugins retrace diff --git a/src/applet/Makefile.am b/src/applet/Makefile.am index 8fcd38d1..bfcf22e3 100644 --- a/src/applet/Makefile.am +++ b/src/applet/Makefile.am @@ -5,9 +5,8 @@ abrt_applet_SOURCES = \ applet.c \ applet_gtk.h applet_gtk.c abrt_applet_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ - -I$(srcdir)/../gtk-helpers \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ -DCONF_DIR=\"$(CONF_DIR)\" \ @@ -17,6 +16,7 @@ abrt_applet_CPPFLAGS = \ -DICON_DIR=\"${datadir}/abrt/icons/hicolor/48x48/status\" \ $(GTK_CFLAGS) \ $(DBUS_CFLAGS) \ + $(LIBREPORT_GTK_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror # -I/usr/include/glib-2.0 @@ -24,9 +24,7 @@ abrt_applet_CPPFLAGS = \ # $(LIBNOTIFY_CFLAGS) # $(DBUS_GLIB_CFLAGS) abrt_applet_LDADD = \ - ../lib/libreport.la \ - ../lib/libabrt_dbus.la \ - ../gtk-helpers/libreportgtk.la \ + $(LIBREPORT_GTK_LIBS) -labrt_dbus \ -lglib-2.0 \ -lgthread-2.0 \ $(DBUS_LIBS) \ diff --git a/src/btparser/Makefile.am b/src/btparser/Makefile.am index c5b0f214..bdf4d900 100644 --- a/src/btparser/Makefile.am +++ b/src/btparser/Makefile.am @@ -13,9 +13,9 @@ libbtparser_la_SOURCES = \ normalize_xorg.c \ thread.h thread.c \ utils.h utils.c -libbtparser_la_CFLAGS = -Wall -Wwrite-strings -Werror -D_GNU_SOURCE -I../lib +libbtparser_la_CFLAGS = -Wall -Wwrite-strings -Werror -D_GNU_SOURCE -I../lib $(LIBREPORT_CFLAGS) libbtparser_la_LDFLAGS = -version-info 1:1:0 -libbtparser_la_LIBADD = ../lib/libreport.la +libbtparser_la_LIBADD = $(LIBREPORT_LIBS) libbtparser_includedir = $(includedir)/btparser libbtparser_include_HEADERS = \ diff --git a/src/cli/Makefile.am b/src/cli/Makefile.am index cd973281..5746e4b2 100644 --- a/src/cli/Makefile.am +++ b/src/cli/Makefile.am @@ -8,18 +8,18 @@ abrt_cli_SOURCES = \ run-command.h run-command.c \ report.h report.c abrt_cli_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DVAR_RUN=\"$(VAR_RUN)\" \ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(DBUS_CFLAGS) $(GLIB_CFLAGS) \ -D_GNU_SOURCE \ + $(LIBREPORT_CFLAGS) \ -Wall -Wwrite-strings -Werror # $(GTK_CFLAGS) abrt_cli_LDADD = \ - ../lib/libreport.la \ - ../lib/libabrt_dbus.la \ + $(LIBREPORT_LIBS) -labrt_dbus \ $(GLIB_LIBS) MAN_TXT = \ diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index 7d586796..58b9b2d9 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -19,7 +19,7 @@ abrtd_SOURCES = \ comm_layer_inner.h comm_layer_inner.c \ abrtd.c abrtd_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -31,17 +31,18 @@ abrtd_CPPFLAGS = \ -DLIBEXEC_DIR=\"$(LIBEXEC_DIR)\" \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings abrtd_LDADD = \ $(DBUS_LIBS) \ - ../lib/libreport.la \ - ../lib/libabrt_dbus.la + ../lib/libabrt.la \ + $(LIBREPORT_LIBS) -labrt_dbus abrt_server_SOURCES = \ abrt-server.c abrt_server_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -51,16 +52,18 @@ abrt_server_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_server_LDADD = \ - ../lib/libreport.la + ../lib/libabrt.la \ + $(LIBREPORT_LIBS) abrt_action_save_package_data_SOURCES = \ rpm.h rpm.c \ abrt-action-save-package-data.c abrt_action_save_package_data_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -71,11 +74,13 @@ abrt_action_save_package_data_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_save_package_data_LDADD = \ $(RPM_LIBS) \ - ../lib/libreport.la + $(LIBREPORT_LIBS) \ + ../lib/libabrt.la dbusabrtconfdir = ${sysconfdir}/dbus-1/system.d/ dist_dbusabrtconf_DATA = dbus-abrt.conf diff --git a/src/gui-gtk/Makefile.am b/src/gui-gtk/Makefile.am index b5c6cd54..a543eb98 100644 --- a/src/gui-gtk/Makefile.am +++ b/src/gui-gtk/Makefile.am @@ -4,7 +4,7 @@ abrt_gui_SOURCES = \ abrt-gtk.h abrt-gtk.c \ main.c abrt_gui_CFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -I$(srcdir)/../gtk-helpers \ -DBIN_DIR=\"$(bindir)\" \ @@ -16,6 +16,7 @@ abrt_gui_CFLAGS = \ -DICON_DIR=\"${datadir}/abrt/icons/hicolor/48x48/status\" \ $(GTK_CFLAGS) \ $(DBUS_CFLAGS) \ + $(LIBREPORT_GTK_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror # -I/usr/include/glib-2.0 @@ -23,13 +24,11 @@ abrt_gui_CFLAGS = \ # $(LIBNOTIFY_CFLAGS) # $(DBUS_GLIB_CFLAGS) abrt_gui_LDADD = \ - ../lib/libreport.la \ - ../lib/libabrt_dbus.la \ - ../gtk-helpers/libreportgtk.la \ -lglib-2.0 \ -lgthread-2.0 \ $(GTK_LIBS) \ - $(DBUS_LIBS) + $(DBUS_LIBS) \ + $(LIBREPORT_GTK_LIBS) -labrt_dbus # $(LIBNOTIFY_LIBS) #test_report_SOURCES = \ diff --git a/src/hooks/Makefile.am b/src/hooks/Makefile.am index cae22726..3fdc59ec 100644 --- a/src/hooks/Makefile.am +++ b/src/hooks/Makefile.am @@ -9,17 +9,19 @@ libexec_PROGRAMS = abrt-hook-ccpp abrt_hook_ccpp_SOURCES = \ abrt-hook-ccpp.c abrt_hook_ccpp_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ -DCONF_DIR=\"$(CONF_DIR)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -Wall -Wwrite-strings \ -D_GNU_SOURCE abrt_hook_ccpp_LDADD = \ - ../lib/libreport.la + ../lib/libabrt.la \ + $(LIBREPORT_LIBS) python_PYTHON = abrt.pth abrt_exception_handler.py EXTRA_DIST = abrt_exception_handler.py.in $(man_MANS) diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 4d31d1a9..357debd7 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -1,12 +1,6 @@ -libreport_includedir = $(includedir)/report -libreport_include_HEADERS = \ - report/problem_data.h \ - report/dump_dir.h \ - report/run_event.h \ - report/event_config.h \ - report/report.h +libabrt_includedir = \ + $(includedir)/abrt -libabrt_includedir = $(includedir)/abrt libabrt_include_HEADERS = \ abrtlib.h \ abrt_types.h \ diff --git a/src/include/abrtlib.h b/src/include/abrtlib.h index 1e68a661..52e05fa2 100644 --- a/src/include/abrtlib.h +++ b/src/include/abrtlib.h @@ -71,19 +71,8 @@ int vdprintf(int d, const char *format, va_list ap); #undef ARRAY_SIZE #define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0]))) -#include "xfuncs.h" -#include "logging.h" -#include "read_write.h" -#include "strbuf.h" -#include "hash_sha1.h" -#include "parse_options.h" - -#include "abrt_problem_data.h" -#include "abrt_types.h" -#include "dump_dir.h" +#include <libreport.h> #include "hooklib.h" -#include "run_event.h" -#include "event_config.h" #include "abrt_conf.h" @@ -91,201 +80,7 @@ int vdprintf(int d, const char *format, va_list ap); extern "C" { #endif -#define prefixcmp abrt_prefixcmp -int prefixcmp(const char *str, const char *prefix); -#define suffixcmp abrt_suffixcmp -int suffixcmp(const char *str, const char *suffix); -#define strtrim abrt_strtrim -char *strtrim(char *str); -#define concat_path_file abrt_concat_path_file -char *concat_path_file(const char *path, const char *filename); -#define append_to_malloced_string abrt_append_to_malloced_string -char *append_to_malloced_string(char *mstr, const char *append); -#define skip_whitespace abrt_skip_whitespace -char* skip_whitespace(const char *s); -#define skip_non_whitespace abrt_skip_non_whitespace -char* skip_non_whitespace(const char *s); -/* Like strcpy but can copy overlapping strings. */ -#define overlapping_strcpy abrt_overlapping_strcpy -void overlapping_strcpy(char *dst, const char *src); - -/* A-la fgets, but malloced and of unlimited size */ -#define xmalloc_fgets abrt_xmalloc_fgets -char *xmalloc_fgets(FILE *file); -/* Similar, but removes trailing \n */ -#define xmalloc_fgetline abrt_xmalloc_fgetline -char *xmalloc_fgetline(FILE *file); - -/* On error, copyfd_XX prints error messages and returns -1 */ -enum { - COPYFD_SPARSE = 1 << 0, -}; -#define copyfd_eof abrt_copyfd_eof -off_t copyfd_eof(int src_fd, int dst_fd, int flags); -#define copyfd_size abrt_copyfd_size -off_t copyfd_size(int src_fd, int dst_fd, off_t size, int flags); -#define copyfd_exact_size abrt_copyfd_exact_size -void copyfd_exact_size(int src_fd, int dst_fd, off_t size); -#define copy_file abrt_copy_file -off_t copy_file(const char *src_name, const char *dst_name, int mode); -#define copy_file_recursive abrt_copy_file_recursive -int copy_file_recursive(const char *source, const char *dest); - -/* Returns malloc'ed block */ -#define encode_base64 abrt_encode_base64 -char *encode_base64(const void *src, int length); - -#define xatou abrt_xatou -unsigned xatou(const char *numstr); -#define xatoi abrt_xatoi -int xatoi(const char *numstr); -/* Using xatoi() instead of naive atoi() is not always convenient - - * in many places people want *non-negative* values, but store them - * in signed int. Therefore we need this one: - * dies if input is not in [0, INT_MAX] range. Also will reject '-0' etc. - * It should really be named xatoi_nonnegative (since it allows 0), - * but that would be too long. - */ -#define xatoi_positive abrt_xatoi_positive -int xatoi_positive(const char *numstr); - -//unused for now -//unsigned long long monotonic_ns(void); -//unsigned long long monotonic_us(void); -//unsigned monotonic_sec(void); - -enum { - /* on return, pipefds[1] is fd to which parent may write - * and deliver data to child's stdin: */ - EXECFLG_INPUT = 1 << 0, - /* on return, pipefds[0] is fd from which parent may read - * child's stdout: */ - EXECFLG_OUTPUT = 1 << 1, - /* open child's stdin to /dev/null: */ - EXECFLG_INPUT_NUL = 1 << 2, - /* open child's stdout to /dev/null: */ - EXECFLG_OUTPUT_NUL = 1 << 3, - /* redirect child's stderr to stdout: */ - EXECFLG_ERR2OUT = 1 << 4, - /* open child's stderr to /dev/null: */ - EXECFLG_ERR_NUL = 1 << 5, - /* suppress perror_msg("Can't execute 'foo'") if exec fails */ - EXECFLG_QUIET = 1 << 6, - EXECFLG_SETGUID = 1 << 7, - EXECFLG_SETSID = 1 << 8, -}; -/* - * env_vec: list of variables to set in environment (if string has - * "VAR=VAL" form) or unset in environment (if string has no '=' char). - * - * Returns pid. - */ -#define fork_execv_on_steroids abrt_fork_execv_on_steroids -pid_t fork_execv_on_steroids(int flags, - char **argv, - int *pipefds, - char **env_vec, - const char *dir, - uid_t uid); -/* Returns malloc'ed string. NULs are retained, and extra one is appended - * after the last byte (this NUL is not accounted for in *size_p) */ -#define run_in_shell_and_save_output abrt_run_in_shell_and_save_output -char *run_in_shell_and_save_output(int flags, - const char *cmd, - const char *dir, - size_t *size_p); - -/* Random utility functions */ - -#define is_in_string_list abrt_is_in_string_list -bool is_in_string_list(const char *name, char **v); - -/* Frees every element'd data using free(), - * then frees list itself using g_list_free(list): - */ -#define list_free_with_free abrt_list_free_with_free -void list_free_with_free(GList *list); - -#define get_dirsize abrt_get_dirsize -double get_dirsize(const char *pPath); -#define get_dirsize_find_largest_dir abrt_get_dirsize_find_largest_dir -double get_dirsize_find_largest_dir( - const char *pPath, - char **worst_dir, /* can be NULL */ - const char *excluded /* can be NULL */ -); - -/* Emit a string of hex representation of bytes */ -#define bin2hex abrt_bin2hex -char* bin2hex(char *dst, const char *str, int count); -/* Convert "xxxxxxxx" hex string to binary, no more than COUNT bytes */ -#define hex2bin abrt_hex2bin -char* hex2bin(char *dst, const char *str, int count); - -/* Returns command line of running program. - * Caller is responsible to free() the returned value. - * If the pid is not valid or command line can not be obtained, - * empty string is returned. - */ -#define get_cmdline abrt_get_cmdline -char* get_cmdline(pid_t pid); -#define get_environ abrt_get_environ -char* get_environ(pid_t pid); - -/* Returns 1 if abrtd daemon is running, 0 otherwise. */ -#define daemon_is_ok abrt_daemon_is_ok -int daemon_is_ok(); - -/* Takes ptr to time_t, or NULL if you want to use current time. - * Returns "YYYY-MM-DD-hh:mm:ss" string. - */ -#define iso_date_string abrt_iso_date_string -char *iso_date_string(time_t *pt); - -enum { - MAKEDESC_SHOW_FILES = (1 << 0), - MAKEDESC_SHOW_MULTILINE = (1 << 1), - MAKEDESC_SHOW_ONLY_LIST = (1 << 2), -}; -#define make_description abrt_make_description -char *make_description(problem_data_t *problem_data, char **names_to_skip, unsigned max_text_size, unsigned desc_flags); -#define make_description_bz abrt_make_description_bz -char* make_description_bz(problem_data_t *problem_data); -#define make_description_logger abrt_make_description_logger -char* make_description_logger(problem_data_t *problem_data); -#define make_description_mailx abrt_make_description_mailx -char* make_description_mailx(problem_data_t *problem_data); - -#define parse_release_for_bz abrt_parse_release_for_bz -void parse_release_for_bz(const char *pRelease, char **product, char **version); -#define parse_release_for_rhts abrt_parse_release_for_rhts -void parse_release_for_rhts(const char *pRelease, char **product, char **version); - -/** - * Loads settings and stores it in second parameter. On success it - * returns true, otherwise returns false. - * - * @param path A path of config file. - * Config file consists of "key=value" lines. - * @param settings A read plugin's settings. - * @param skipKeysWithoutValue - * If true, lines in format "key=" (without value) are skipped. - * Otherwise empty value "" is inserted into pSettings. - * @return if it success it returns true, otherwise it returns false. - */ -#define load_conf_file abrt_load_conf_file -bool load_conf_file(const char *pPath, map_string_h *settings, bool skipKeysWithoutValue); - -/* Tries to create a copy of dump_dir_name in base_dir, with same or similar basename. - * Returns NULL if copying failed. In this case, logs a message before returning. */ -#define steal_directory abrt_steal_directory -struct dump_dir *steal_directory(const char *base_dir, const char *dump_dir_name); - -#define kernel_tainted_short abrt_kernel_tainted_short -char *kernel_tainted_short(unsigned tainted); -#define kernel_tainted_long abrt_kernel_tainted_long -GList *kernel_tainted_long(unsigned tainted); #ifdef __cplusplus } diff --git a/src/include/report/dump_dir.h b/src/include/report/dump_dir.h deleted file mode 100644 index c88ebe7f..00000000 --- a/src/include/report/dump_dir.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - On-disk storage of problem data - - Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) - Copyright (C) 2009 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. -*/ -#ifndef DUMP_DIR_H_ -#define DUMP_DIR_H_ - -/* For DIR */ -#include <sys/types.h> -#include <dirent.h> - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - DD_FAIL_QUIETLY_ENOENT = (1 << 0), - DD_FAIL_QUIETLY_EACCES = (1 << 1), - DD_OPEN_READONLY = (1 << 2), -}; - -struct dump_dir { - char *dd_dirname; - DIR *next_dir; - int locked; - uid_t dd_uid; - gid_t dd_gid; - /* mode fo saved files */ - mode_t mode; -}; - -void dd_close(struct dump_dir *dd); - -struct dump_dir *dd_opendir(const char *dir, int flags); -/* Pass uid = (uid_t)-1L to disable chown'ing of newly created files - * (IOW: if you aren't running under root): - */ -struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t mode); - -void dd_create_basic_files(struct dump_dir *dd, uid_t uid); -int dd_exist(struct dump_dir *dd, const char *path); -void dd_sanitize_mode_and_owner(struct dump_dir *dd); - -DIR *dd_init_next_file(struct dump_dir *dd); -int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name); - -enum { - /* DD_FAIL_QUIETLY_ENOENT bit is valid for dd_load_text_ext too, */ - DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE = (DD_OPEN_READONLY << 1), -}; -char* dd_load_text_ext(const struct dump_dir *dd, const char *name, unsigned flags); -char* dd_load_text(const struct dump_dir *dd, const char *name); -void dd_save_text(struct dump_dir *dd, const char *name, const char *data); -void dd_save_binary(struct dump_dir *dd, const char *name, const char *data, unsigned size); -/* Returns 0 if directory is deleted or not found */ -int dd_delete(struct dump_dir *dd); - -void delete_dump_dir(const char *dirname); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/include/report/event_config.h b/src/include/report/event_config.h deleted file mode 100644 index 8ab9477d..00000000 --- a/src/include/report/event_config.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (C) 2011 ABRT team - - 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 <glib.h> - -#ifndef EVENT_CONFIG_H -#define EVENT_CONFIG_H - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum -{ - OPTION_TYPE_TEXT, - OPTION_TYPE_BOOL, - OPTION_TYPE_PASSWORD, - OPTION_TYPE_NUMBER, - OPTION_TYPE_HINT_HTML, - OPTION_TYPE_INVALID, -} option_type_t; - -/* - * struct to hold information about config options - * it's supposed to hold information about: - * type -> which designates the widget used to display it and we can do some test based on the type - * label - * allowed value(s) -> regexp? - * name -> env variable name - * value -> value retrieved from the gui, so when we want to set the env - * evn variables, we can just traverse the list of the options - * and set the env variables according to name:value in this structure - */ -typedef struct -{ - char *eo_name; //name of the value which should be used for env variable - char *eo_value; - char *eo_label; - char *eo_note_html; - option_type_t eo_type; - int eo_allow_empty; - //char *description; //can be used as tooltip in gtk app - //char *allowed_value; - //int required; -} event_option_t; - -event_option_t *new_event_option(void); -void free_event_option(event_option_t *p); - -//structure to hold the option data -typedef struct -{ - char *screen_name; //ui friendly name of the event: "Bugzilla" "RedHat Support Upload" - char *description; // "Report to..."/"Save to file". Should be one sentence, not long - char *long_descr; // Long(er) explanation, if needed - - char *ec_creates_items; - char *ec_requires_items; - char *ec_exclude_items_by_default; - char *ec_include_items_by_default; - char *ec_exclude_items_always; - bool ec_exclude_binary_items; - - GList *options; -} event_config_t; - -event_config_t *new_event_config(void); -void free_event_config(event_config_t *p); - - -void load_event_description_from_file(event_config_t *event_config, const char* filename); - -// (Re)loads data from /etc/abrt/events/*.{conf,xml} -void load_event_config_data(void); -/* Frees all loaded data */ -void free_event_config_data(void); -event_config_t *get_event_config(const char *event_name); -event_option_t *get_event_option_from_list(const char *option_name, GList *event_options); - -extern GHashTable *g_event_config_list; // for iterating through entire list of all loaded configs - -GList *export_event_config(const char *event_name); -void unexport_event_config(GList *env_list); - -GHashTable *validate_event(const char *event_name); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/include/report/problem_data.h b/src/include/report/problem_data.h deleted file mode 100644 index 31ef7d25..00000000 --- a/src/include/report/problem_data.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - Copyright (C) 2009 Abrt team. - Copyright (C) 2009 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. -*/ -#ifndef PROBLEM_DATA_H_ -#define PROBLEM_DATA_H_ - -#include <glib.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct dump_dir; - -enum { - CD_FLAG_BIN = (1 << 0), - CD_FLAG_TXT = (1 << 1), - CD_FLAG_ISEDITABLE = (1 << 2), - CD_FLAG_ISNOTEDITABLE = (1 << 3), - /* Show this element in "short" info (abrt-cli -l) */ - CD_FLAG_LIST = (1 << 4), - CD_FLAG_UNIXTIME = (1 << 5), -}; - -struct problem_item { - char *content; - unsigned flags; - /* Used by UI for presenting "item allowed/not allowed" checkboxes: */ - int selected_by_user; /* 0 "don't know", -1 "no", 1 "yes" */ - int allowed_by_reporter; /* 0 "no", 1 "yes" */ - int default_by_reporter; /* 0 "no", 1 "yes" */ - int required_by_reporter; /* 0 "no", 1 "yes" */ -}; -typedef struct problem_item problem_item; - -char *format_problem_item(struct problem_item *item); - - -/* In-memory problem data structure and accessors */ - -typedef GHashTable problem_data_t; - -problem_data_t *new_problem_data(void); - -void add_basics_to_problem_data(problem_data_t *pd); - -static inline void free_problem_data(problem_data_t *problem_data) -{ - if (problem_data) - g_hash_table_destroy(problem_data); -} - -void add_to_problem_data_ext(problem_data_t *problem_data, - const char *name, - const char *content, - unsigned flags); -/* Uses CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE flags */ -void add_to_problem_data(problem_data_t *problem_data, - const char *name, - const char *content); - -static inline struct problem_item *get_problem_data_item_or_NULL(problem_data_t *problem_data, const char *key) -{ - return (struct problem_item *)g_hash_table_lookup(problem_data, key); -} -const char *get_problem_item_content_or_NULL(problem_data_t *problem_data, const char *key); -/* Aborts if key is not found: */ -const char *get_problem_item_content_or_die(problem_data_t *problem_data, const char *key); - - -/* Conversions between in-memory and on-disk formats */ - -void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_dir *dd, char **excluding); -problem_data_t *create_problem_data_from_dump_dir(struct dump_dir *dd); -/* Helper for typical operation in reporters: */ -problem_data_t *create_problem_data_for_reporting(const char *dump_dir_name); - -struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/include/report/report.h b/src/include/report/report.h deleted file mode 100644 index 269866b2..00000000 --- a/src/include/report/report.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2011 Abrt team. - Copyright (C) 2011 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. -*/ -#ifndef REPORT_H_ -#define REPORT_H_ - -#include "problem_data.h" - -enum { - LIBREPORT_NOWAIT = 0, - LIBREPORT_WAIT = (1 << 0), /* wait for report to finish and reload the problem data */ - LIBREPORT_ANALYZE = (1 << 1), /* run analyzers? */ - /* ("run reporters" is always on, has no flag (for now?)) */ - LIBREPORT_RELOAD_DATA = (1 << 3), /* reload problem data after run (needs WAIT) */ -}; - -int report_problem_in_dir(const char *dirname, int flags); - -/* Reports a problem stored in problem_data_t. - * It's first saved to /tmp and then processed as a dump dir. - */ -int report_problem_in_memory(problem_data_t *pd, int flags); - -/* Simple wrapper for trivial uses */ -int report_problem(problem_data_t *pd); - -#endif /* REPORT_H_ */ diff --git a/src/include/report/run_event.h b/src/include/report/run_event.h deleted file mode 100644 index 9726b643..00000000 --- a/src/include/report/run_event.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2009 Abrt team. - Copyright (C) 2009 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. -*/ -#ifndef RUN_EVENT_H_ -#define RUN_EVENT_H_ - -#include "problem_data.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct dump_dir; - -struct run_event_state { - int children_count; - - /* Used only for post-create dup detection. TODO: document its API */ - int (*post_run_callback)(const char *dump_dir_name, void *param); - void *post_run_param; - - /* Can take ownership of log_line, which is malloced. In this case, return NULL. - * Otherwise should return log_line (it will be freed by caller) - */ - char* (*logging_callback)(char *log_line, void *param); - void *logging_param; - - /* Internal data for async command execution */ - GList *rule_list; - pid_t command_pid; - int command_out_fd; -}; -struct run_event_state *new_run_event_state(void); -void free_run_event_state(struct run_event_state *state); - -/* Asynchronous command execution */ - -/* Returns 0 if no commands found for this dump_dir_name+event, else >0 */ -int prepare_commands(struct run_event_state *state, const char *dump_dir_name, const char *event); -/* Returns -1 is no more commands needs to be executed, - * else sets state->command_pid and state->command_out_fd and returns >=0 - */ -int spawn_next_command(struct run_event_state *state, const char *dump_dir_name, const char *event); -/* Cleans up internal state created in prepare_commands */ -void free_commands(struct run_event_state *state); - -/* Synchronous command execution */ - -/* Returns exit code of first failed action, or first nonzero return value - * of post_run_callback. If all actions are successful, returns 0. - */ -int run_event_on_dir_name(struct run_event_state *state, const char *dump_dir_name, const char *event); -int run_event_on_problem_data(struct run_event_state *state, problem_data_t *data, const char *event); - -/* Querying for possible events */ - -/* Scans event.conf for events starting with pfx which are applicable - * to dd, or (if dd is NULL), to dump_dir. - * Returns a malloced string with '\n'-terminated event names. - */ -char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 86210d4e..163e7c39 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -2,56 +2,22 @@ # libabrt_dbus - daemon, cli and applet use this # libabrt_web - for abrt-action-foo where foo deals with network/web/ftp/... lib_LTLIBRARIES = \ - libreport.la \ - libabrt_dbus.la \ + libabrt.la \ libabrt_web.la # Not used just yet: # time.cpp # xconnect.cpp -libreport_la_SOURCES = \ - kernel-tainted.c \ - xfuncs.c \ - is_in_string_list.c \ - encbase64.c \ - binhex.c \ - stdio_helpers.c \ - hash_sha1.c hash_sha1.h \ - read_write.c read_write.h \ - logging.c logging.h \ - copyfd.c \ - copy_file_recursive.c \ - concat_path_file.c \ - append_to_malloced_string.c \ - overlapping_strcpy.c \ - skip_whitespace.c \ - glib_support.c \ - iso_date_string.c \ - strbuf.c strbuf.h \ - xatonum.c \ - spawn.c \ - dirsize.c \ - dump_dir.c \ - get_cmdline.c \ - daemon_is_ok.c \ - load_plugin_settings.c \ - make_descr.c \ - run_event.c \ - problem_data.c \ - create_dump_dir.c \ - abrt_types.c \ - hooklib.c hooklib.h \ - parse_release.c \ - parse_options.c parse_options.h \ +libabrt_la_SOURCES = \ abrt_conf.c abrt_conf.h \ - steal_directory.c \ - event_xml_parser.c \ - event_config.c \ - report.c -libreport_la_CPPFLAGS = \ + hooklib.c hooklib.h \ + daemon_is_ok.c + +libabrt_la_CPPFLAGS = \ -Wall -Wwrite-strings -Werror \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ + -I$(srcdir)/../lib \ -DLOCALSTATEDIR='"$(localstatedir)"' \ -DVAR_RUN=\"$(VAR_RUN)\" \ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ @@ -61,39 +27,19 @@ libreport_la_CPPFLAGS = \ -DEVENTS_DIR=\"$(EVENTS_DIR)\" \ -DBIN_DIR=\"$(bindir)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE -libreport_la_LDFLAGS = \ +libabrt_la_LDFLAGS = \ -version-info 0:1:0 -libreport_la_LIBADD = \ +libabrt_la_LIBADD = \ $(GLIB_LIBS) -libabrt_dbus_la_SOURCES = \ - abrt_dbus.c abrt_dbus.h -libabrt_dbus_la_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ - -DLOCALSTATEDIR='"$(localstatedir)"' \ - -DVAR_RUN=\"$(VAR_RUN)\" \ - -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ - -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ - -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ - -DCONF_DIR=\"$(CONF_DIR)\" \ - -DEVENTS_DIR=\"$(EVENTS_DIR)\" \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - -Wall -Wwrite-strings -Werror \ - -D_GNU_SOURCE -libabrt_dbus_la_LDFLAGS = \ - -version-info 0:1:0 -libabrt_dbus_la_LIBADD = \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) - libabrt_web_la_SOURCES = \ abrt_curl.h abrt_curl.c \ abrt_xmlrpc.h abrt_xmlrpc.c libabrt_web_la_CPPFLAGS = \ -Wall -Wwrite-strings -Werror \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -DLOCALSTATEDIR='"$(localstatedir)"' \ -DVAR_RUN=\"$(VAR_RUN)\" \ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ @@ -105,6 +51,7 @@ libabrt_web_la_CPPFLAGS = \ $(CURL_CFLAGS) \ $(LIBXML_CFLAGS) \ $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE libabrt_web_la_LDFLAGS = \ -version-info 0:1:0 diff --git a/src/lib/abrt_dbus.c b/src/lib/abrt_dbus.c deleted file mode 100644 index c3cb9ba4..00000000 --- a/src/lib/abrt_dbus.c +++ /dev/null @@ -1,623 +0,0 @@ -/* - Copyright (C) 2010 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 <dbus/dbus.h> -#include "abrtlib.h" -#include "abrt_dbus.h" - -DBusConnection* g_dbus_conn; - - -/* - * Helpers for building DBus messages - */ - -//void store_bool(DBusMessageIter* iter, bool val) -//{ -// dbus_bool_t db = val; -// if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &db)) -// die_out_of_memory(); -//} -void store_int32(DBusMessageIter* iter, int32_t val) -{ - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &val)) - die_out_of_memory(); -} -void store_uint32(DBusMessageIter* iter, uint32_t val) -{ - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &val)) - die_out_of_memory(); -} -void store_int64(DBusMessageIter* iter, int64_t val) -{ - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_INT64, &val)) - die_out_of_memory(); -} -void store_uint64(DBusMessageIter* iter, uint64_t val) -{ - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &val)) - die_out_of_memory(); -} - -/* dbus daemon will simply close our connection if we send broken utf8. - * Therefore we must never do that. - */ -static char *sanitize_utf8(const char *src) -{ - const char *initial_src = src; - char *sanitized = NULL; - unsigned sanitized_pos = 0; - - while (*src) - { - int bytes = 0; - - unsigned c = (unsigned char) *src; - if (c <= 0x7f) - { - bytes = 1; - goto good_byte; - } - - /* Unicode -> utf8: */ - /* 80-7FF -> 110yyyxx 10xxxxxx */ - /* 800-FFFF -> 1110yyyy 10yyyyxx 10xxxxxx */ - /* 10000-1FFFFF -> 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx */ - /* 200000-3FFFFFF -> 111110tt 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx */ - /* 4000000-FFFFFFFF -> 111111tt 10tttttt 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx */ - do { - c <<= 1; - bytes++; - } while ((c & 0x80) && bytes < 6); - if (bytes == 1) - { - /* A bare "continuation" byte. Say, 80 */ - goto bad_byte; - } - - c = (uint8_t)(c) >> bytes; - { - const char *pp = src; - int cnt = bytes; - while (--cnt) - { - unsigned ch = (unsigned char) *++pp; - if ((ch & 0xc0) != 0x80) /* Missing "continuation" byte. Example: e0 80 */ - { - goto bad_byte; - } - c = (c << 6) + (ch & 0x3f); - } - } - /* TODO */ - /* Need to check that c isn't produced by overlong encoding */ - /* Example: 11000000 10000000 converts to NUL */ - /* 11110000 10000000 10000100 10000000 converts to 0x100 */ - /* correct encoding: 11000100 10000000 */ - if (c <= 0x7f) /* crude check: only catches bad encodings which map to chars <= 7f */ - { - goto bad_byte; - } - - good_byte: - while (--bytes >= 0) - { - c = (unsigned char) *src++; - if (sanitized) - { - sanitized = (char*) xrealloc(sanitized, sanitized_pos + 2); - sanitized[sanitized_pos++] = c; - sanitized[sanitized_pos] = '\0'; - } - } - continue; - - bad_byte: - if (!sanitized) - { - sanitized_pos = src - initial_src; - sanitized = xstrndup(initial_src, sanitized_pos); - } - sanitized = (char*) xrealloc(sanitized, sanitized_pos + 5); - sanitized[sanitized_pos++] = '['; - c = (unsigned char) *src++; - sanitized[sanitized_pos++] = "0123456789ABCDEF"[c >> 4]; - sanitized[sanitized_pos++] = "0123456789ABCDEF"[c & 0xf]; - sanitized[sanitized_pos++] = ']'; - sanitized[sanitized_pos] = '\0'; - } - - if (sanitized) - VERB2 log("note: bad utf8, converted '%s' -> '%s'", initial_src, sanitized); - - return sanitized; /* usually NULL: the whole string is ok */ -} -void store_string(DBusMessageIter* iter, const char* val) -{ - const char *sanitized = sanitize_utf8(val); - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, sanitized ? &sanitized : &val)) - die_out_of_memory(); - free((char*)sanitized); -} - - -/* - * Helpers for parsing DBus messages - */ - -//int load_bool(DBusMessageIter* iter, bool& val) -//{ -// int type = dbus_message_iter_get_arg_type(iter); -// if (type != DBUS_TYPE_BOOLEAN) -// error_msg_and_die("%s expected in dbus message, but not found ('%c')", "bool", type); -// dbus_bool_t db; -// dbus_message_iter_get_basic(iter, &db); -// val = db; -// return dbus_message_iter_next(iter); -//} -int load_int32(DBusMessageIter* iter, int32_t *val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_INT32) - { - error_msg("%s expected in dbus message, but not found ('%c')", "int32", type); - return -1; - } - dbus_message_iter_get_basic(iter, val); - return dbus_message_iter_next(iter); -} -int load_uint32(DBusMessageIter* iter, uint32_t *val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_UINT32) - { - error_msg("%s expected in dbus message, but not found ('%c')", "uint32", type); - return -1; - } - dbus_message_iter_get_basic(iter, val); - return dbus_message_iter_next(iter); -} -int load_int64(DBusMessageIter* iter, int64_t *val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_INT64) - { - error_msg("%s expected in dbus message, but not found ('%c')", "int64", type); - return -1; - } - dbus_message_iter_get_basic(iter, val); - return dbus_message_iter_next(iter); -} -int load_uint64(DBusMessageIter* iter, uint64_t *val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_UINT64) - { - error_msg("%s expected in dbus message, but not found ('%c')", "uint64", type); - return -1; - } - dbus_message_iter_get_basic(iter, val); - return dbus_message_iter_next(iter); -} -int load_charp(DBusMessageIter* iter, const char** val) -{ - *val = NULL; - - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_STRING) - { - error_msg("%s expected in dbus message, but not found ('%c')", "string", type); - return -1; - } - dbus_message_iter_get_basic(iter, val); -//log("load_charp:'%s'", *val); - return dbus_message_iter_next(iter); -} - - -/* - * Glib integration machinery - */ - -/* Callback: "glib says dbus fd is active" */ -static gboolean handle_dbus_fd(GIOChannel *gio, GIOCondition condition, gpointer data) -{ - DBusWatch *watch = (DBusWatch*)data; - - VERB3 log("%s(gio, condition:%x [bits:IN/PRI/OUT/ERR/HUP...], data)", __func__, (int)condition); - - /* Notify the D-Bus library when a previously-added watch - * is ready for reading or writing, or has an exception such as a hangup. - */ - int glib_flags = (int)condition; - int dbus_flags = 0; - if (glib_flags & G_IO_IN) dbus_flags |= DBUS_WATCH_READABLE; - if (glib_flags & G_IO_OUT) dbus_flags |= DBUS_WATCH_WRITABLE; - if (glib_flags & G_IO_ERR) dbus_flags |= DBUS_WATCH_ERROR; - if (glib_flags & G_IO_HUP) dbus_flags |= DBUS_WATCH_HANGUP; - /* - * TODO: - * If dbus_watch_handle returns FALSE, then the file descriptor - * may still be ready for reading or writing, but more memory - * is needed in order to do the reading or writing. If you ignore - * the FALSE return, your application may spin in a busy loop - * on the file descriptor until memory becomes available, - * but nothing more catastrophic should happen. - */ - dbus_watch_handle(watch, dbus_flags); - - while (dbus_connection_dispatch(g_dbus_conn) == DBUS_DISPATCH_DATA_REMAINS) - VERB3 log("%s: more data to process, looping", __func__); - return TRUE; /* "glib, do not remove this event source!" */ -} - -typedef struct watch_app_info_t -{ - GIOChannel *channel; - guint event_source_id; - bool watch_enabled; -} watch_app_info_t; -/* Callback: "dbus_watch_get_enabled() may return a different value than it did before" */ -static void toggled_watch(DBusWatch *watch, void* data) -{ - VERB3 log("%s(watch:%p, data)", __func__, watch); - - watch_app_info_t* app_info = (watch_app_info_t*)dbus_watch_get_data(watch); - if (dbus_watch_get_enabled(watch)) - { - if (!app_info->watch_enabled) - { - app_info->watch_enabled = true; - int dbus_flags = dbus_watch_get_flags(watch); - int glib_flags = 0; - if (dbus_flags & DBUS_WATCH_READABLE) glib_flags |= G_IO_IN; - if (dbus_flags & DBUS_WATCH_WRITABLE) glib_flags |= G_IO_OUT; - VERB3 log(" adding watch to glib main loop. dbus_flags:%x glib_flags:%x", dbus_flags, glib_flags); - app_info->event_source_id = g_io_add_watch(app_info->channel, (GIOCondition)glib_flags, handle_dbus_fd, watch); - } - /* else: it was already enabled */ - } - else - { - if (app_info->watch_enabled) - { - app_info->watch_enabled = false; - /* does it free the hidden GSource too? */ - VERB3 log(" removing watch from glib main loop"); - g_source_remove(app_info->event_source_id); - } - /* else: it was already disabled */ - } -} -/* Callback: "libdbus needs a new watch to be monitored by the main loop" */ -static dbus_bool_t add_watch(DBusWatch *watch, void* data) -{ - VERB3 log("%s(watch:%p, data)", __func__, watch); - - watch_app_info_t* app_info = (watch_app_info_t*)xzalloc(sizeof(*app_info)); - dbus_watch_set_data(watch, app_info, free); - - int fd = dbus_watch_get_unix_fd(watch); - VERB3 log(" dbus_watch_get_unix_fd():%d", fd); - app_info->channel = g_io_channel_unix_new(fd); - /* _unconditionally_ adding it to event loop would be an error */ - toggled_watch(watch, data); - return TRUE; -} -/* Callback: "libdbus no longer needs a watch to be monitored by the main loop" */ -static void remove_watch(DBusWatch *watch, void* data) -{ - VERB3 log("%s()", __func__); - watch_app_info_t* app_info = (watch_app_info_t*)dbus_watch_get_data(watch); - if (app_info->watch_enabled) - { - app_info->watch_enabled = false; - g_source_remove(app_info->event_source_id); - } - g_io_channel_unref(app_info->channel); -} - -/* Callback: "libdbus needs a new timeout to be monitored by the main loop" */ -static dbus_bool_t add_timeout(DBusTimeout *timeout, void* data) -{ - VERB3 log("%s()", __func__); - return TRUE; -} -/* Callback: "libdbus no longer needs a timeout to be monitored by the main loop" */ -static void remove_timeout(DBusTimeout *timeout, void* data) -{ - VERB3 log("%s()", __func__); -} -/* Callback: "dbus_timeout_get_enabled() may return a different value than it did before" */ -static void timeout_toggled(DBusTimeout *timeout, void* data) -{ -//seems to be never called, let's make it noisy - error_msg_and_die("%s(): FIXME: some dbus machinery is missing here", __func__); -} - -/* Callback: "DBusObjectPathVTable is unregistered (or its connection is freed)" */ -static void unregister_vtable(DBusConnection *conn, void* data) -{ - VERB3 log("%s()", __func__); -} - - -/* - * Simple logging handler for dbus errors. - */ -int log_dbus_error(const char *msg, DBusError *err) -{ - int ret = 0; - if (dbus_error_is_set(err)) - { - error_msg("dbus error: %s", err->message); - ret = 1; - } - if (msg) - { - error_msg(msg); - ret = 1; - } - return ret; -} - - -/* - * Initialization. Works as follows: - * - * we have a DBusConnection* (say, obtained with dbus_bus_get) - * we call dbus_connection_set_watch_functions - * libdbus calls back add_watch(watch:0x2341090, data), this watch is for writing - * we call toggled_watch, but it finds that watch is not to be enabled yet - * libdbus calls back add_watch(watch:0x23410e0, data), this watch is for reading - * we call toggled_watch, it adds watch's fd to glib main loop with POLLIN - * (note: these watches are different objects, but they have the same fd) - * we call dbus_connection_set_timeout_functions - * we call dbus_connection_register_object_path - * - * Note: if user will later call dbus_bus_request_name(conn, ...): - * libdbus calls back add_timeout() - * libdbus calls back remove_timeout() - * note - no callback to timeout_toggled()! - * (therefore there is no code yet in timeout_toggled (see above), it's not used) - */ -void attach_dbus_conn_to_glib_main_loop(DBusConnection* conn, - const char* object_path, - DBusHandlerResult (*message_received_func)(DBusConnection *conn, DBusMessage *msg, void* data) -) { - if (g_dbus_conn) - error_msg_and_die("Internal bug: can't connect to more than one dbus"); - g_dbus_conn = conn; - -//do we need this? why? -//log("dbus_connection_set_dispatch_status_function"); -// dbus_connection_set_dispatch_status_function(conn, -// dispatch, /* void dispatch(DBusConnection *conn, DBusDispatchStatus new_status, void* data) */ -// NULL, /* data */ -// NULL /* free_data_function */ -// ) - VERB3 log("dbus_connection_set_watch_functions"); - if (!dbus_connection_set_watch_functions(conn, - add_watch, - remove_watch, - toggled_watch, - NULL, /* data */ - NULL /* free_data_function */ - ) - ) { - die_out_of_memory(); - } - VERB3 log("dbus_connection_set_timeout_functions"); - if (!dbus_connection_set_timeout_functions(conn, - add_timeout, - remove_timeout, - timeout_toggled, - NULL, /* data */ - NULL /* free_data_function */ - ) - ) { - die_out_of_memory(); - } - - if (object_path && message_received_func) - { - /* Table */ - const DBusObjectPathVTable vtable = { - /* .unregister_function = */ unregister_vtable, - /* .message_function = */ message_received_func, - }; - VERB3 log("dbus_connection_register_object_path"); - if (!dbus_connection_register_object_path(conn, - object_path, - &vtable, - NULL /* data */ - ) - ) { - die_out_of_memory(); - } - } -} - - -/* - * Support functions for clients - */ - -/* helpers */ -static DBusMessage* new_call_msg(const char* method) -{ - DBusMessage* msg = dbus_message_new_method_call(ABRTD_DBUS_NAME, ABRTD_DBUS_PATH, ABRTD_DBUS_IFACE, method); - if (!msg) - die_out_of_memory(); - return msg; -} - -static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) -{ - dbus_uint32_t serial; - if (TRUE != dbus_connection_send(g_dbus_conn, msg, &serial)) - error_msg_and_die("Error sending DBus message"); - dbus_message_unref(msg); - - while (true) - { - DBusMessage *received = dbus_connection_pop_message(g_dbus_conn); - if (!received) - { - if (FALSE == dbus_connection_read_write(g_dbus_conn, -1)) - error_msg_and_die("dbus connection closed"); - continue; - } - - int tp = dbus_message_get_type(received); - const char *error_str = dbus_message_get_error_name(received); -#if 0 - /* Debugging */ - printf("type:%u (CALL:%u, RETURN:%u, ERROR:%u, SIGNAL:%u)\n", tp, - DBUS_MESSAGE_TYPE_METHOD_CALL, - DBUS_MESSAGE_TYPE_METHOD_RETURN, - DBUS_MESSAGE_TYPE_ERROR, - DBUS_MESSAGE_TYPE_SIGNAL - ); - const char *sender = dbus_message_get_sender(received); - if (sender) - printf("sender: %s\n", sender); - const char *path = dbus_message_get_path(received); - if (path) - printf("path: %s\n", path); - const char *member = dbus_message_get_member(received); - if (member) - printf("member: %s\n", member); - const char *interface = dbus_message_get_interface(received); - if (interface) - printf("interface: %s\n", interface); - const char *destination = dbus_message_get_destination(received); - if (destination) - printf("destination: %s\n", destination); - if (error_str) - printf("error: '%s'\n", error_str); -#endif - - DBusError err; - dbus_error_init(&err); - - if (dbus_message_is_signal(received, ABRTD_DBUS_IFACE, "Update")) - { - const char *update_msg; - if (!dbus_message_get_args(received, &err, - DBUS_TYPE_STRING, &update_msg, - DBUS_TYPE_INVALID)) - { - error_msg_and_die("dbus Update message: arguments mismatch"); - } - printf(">> %s\n", update_msg); - } - else if (dbus_message_is_signal(received, ABRTD_DBUS_IFACE, "Warning")) - { - const char *warning_msg; - if (!dbus_message_get_args(received, &err, - DBUS_TYPE_STRING, &warning_msg, - DBUS_TYPE_INVALID)) - { - error_msg_and_die("dbus Warning message: arguments mismatch"); - } - log(">! %s", warning_msg); - } - else - if (tp == DBUS_MESSAGE_TYPE_METHOD_RETURN - && dbus_message_get_reply_serial(received) == serial - ) { - return received; - } - else - if (tp == DBUS_MESSAGE_TYPE_ERROR - && dbus_message_get_reply_serial(received) == serial - ) { - error_msg_and_die("dbus call returned error: '%s'", error_str); - } - - dbus_message_unref(received); - } -} - -int32_t call_DeleteDebugDump(const char *dump_dir_name) -{ - DBusMessage* msg = new_call_msg(__func__ + 5); - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &dump_dir_name, - DBUS_TYPE_INVALID); - - DBusMessage *reply = send_get_reply_and_unref(msg); - - DBusMessageIter in_iter; - dbus_message_iter_init(reply, &in_iter); - - int32_t result; - int r = load_int32(&in_iter, &result); - if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */ - error_msg_and_die("dbus call %s: return type mismatch", __func__ + 5); - - dbus_message_unref(reply); - return result; -} - -static int connect_to_abrtd_and_call_DeleteDebugDump(const char *dump_dir_name) -{ - DBusError err; - dbus_error_init(&err); - g_dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); - if (log_dbus_error( - g_dbus_conn ? NULL : - "error requesting system DBus, possible reasons: " - "dbus config is incorrect; dbus-daemon is not running, " - "or dbus daemon needs to be restarted to reload dbus config", - &err - ) - ) { - if (g_dbus_conn) - dbus_connection_unref(g_dbus_conn); - g_dbus_conn = NULL; - return 1; - } - - int ret = call_DeleteDebugDump(dump_dir_name); - if (ret == ENOENT) - error_msg("Dump directory '%s' is not found", dump_dir_name); - else if (ret != 0) - error_msg("Can't delete dump directory '%s'", dump_dir_name); - - dbus_connection_unref(g_dbus_conn); - g_dbus_conn = NULL; - - return ret; -} - -int delete_dump_dir_possibly_using_abrtd(const char *dump_dir_name) -{ - /* Try to delete it ourselves */ - struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY); - if (dd) - { - if (dd->locked) /* it is not readonly */ - return dd_delete(dd); - dd_close(dd); - } - - VERB1 log("Deleting '%s' via abrtd dbus call", dump_dir_name); - return connect_to_abrtd_and_call_DeleteDebugDump(dump_dir_name); -} diff --git a/src/lib/abrt_dbus.h b/src/lib/abrt_dbus.h deleted file mode 100644 index b7e7b566..00000000 --- a/src/lib/abrt_dbus.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - Copyright (C) 2010 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. -*/ -#ifndef ABRT_DBUS_H -#define ABRT_DBUS_H - -#include <dbus/dbus.h> -#include "abrtlib.h" - - -#define ABRTD_DBUS_NAME "com.redhat.abrt" -#define ABRTD_DBUS_PATH "/com/redhat/abrt" -#define ABRTD_DBUS_IFACE "com.redhat.abrt" - - -#ifdef __cplusplus -extern "C" { -#endif - -extern DBusConnection* g_dbus_conn; - -/* - * Glib integration machinery - */ - -/* Hook up to DBus and to glib main loop. - * Usage cases: - * - * - server: - * conn = dbus_bus_get(DBUS_BUS_SYSTEM/SESSION, &err); - * attach_dbus_conn_to_glib_main_loop(conn, "/some/path", handler_of_calls_to_some_path); - * rc = dbus_bus_request_name(conn, "server.name", DBUS_NAME_FLAG_REPLACE_EXISTING, &err); - * - * - client which does not receive signals (only makes calls and emits signals): - * conn = dbus_bus_get(DBUS_BUS_SYSTEM/SESSION, &err); - * // needed only if you need to use async dbus calls (not shown below): - * attach_dbus_conn_to_glib_main_loop(conn, NULL, NULL); - * // synchronous method call: - * msg = dbus_message_new_method_call("some.serv", "/path/on/serv", "optional.iface.on.serv", "method_name"); - * reply = dbus_connection_send_with_reply_and_block(conn, msg, timeout, &err); - * // emitting signal: - * msg = dbus_message_new_signal("/path/sig/emitted/from", "iface.sig.emitted.from", "sig_name"); - * // (note: "iface.sig.emitted.from" is not optional for signals!) - * dbus_message_set_destination(msg, "peer"); // optional - * dbus_connection_send(conn, msg, &serial); // &serial can be NULL - * dbus_connection_unref(conn); // if you don't want to *stay* connected - * - * - client which receives and processes signals: - * conn = dbus_bus_get(DBUS_BUS_SYSTEM/SESSION, &err); - * attach_dbus_conn_to_glib_main_loop(conn, NULL, NULL); - * dbus_connection_add_filter(conn, handle_message, NULL, NULL) - * dbus_bus_add_match(system_conn, "type='signal',...", &err); - * // signal is a dbus message which looks like this: - * // sender=XXX dest=YYY(or null) path=/path/sig/emitted/from interface=iface.sig.emitted.from member=sig_name - * // and handler_for_signals(conn,msg,opaque) will be called by glib - * // main loop to process received signals (and other messages - * // if you ask for them in dbus_bus_add_match[es], but this - * // would turn you into a server if you handle them too) ;] - */ -void attach_dbus_conn_to_glib_main_loop(DBusConnection* conn, - /* NULL if you are just a client */ - const char* object_path_to_register, - /* makes sense only if you use object_path_to_register: */ - DBusHandlerResult (*message_received_func)(DBusConnection *conn, DBusMessage *msg, void* data) -); - -/* Log dbus error if err has it set. Then log msg if it's !NULL. - * In both cases return 1. Otherwise return 0. - */ -int log_dbus_error(const char *msg, DBusError *err); - -/* Perform "DeleteDebugDump" call over g_dbus_conn */ -int32_t call_DeleteDebugDump(const char *dump_dir_name); - -/* Connect to system bus, find abrtd, perform "DeleteDebugDump" call, close g_dbus_conn */ -/* now static: int connect_to_abrtd_and_call_DeleteDebugDump(const char *dump_dir_name); */ -int delete_dump_dir_possibly_using_abrtd(const char *dump_dir_name); - - -/* - * Helpers for building DBus messages - */ -//void store_bool(DBusMessageIter* iter, bool val); -void store_int32(DBusMessageIter* iter, int32_t val); -void store_uint32(DBusMessageIter* iter, uint32_t val); -void store_int64(DBusMessageIter* iter, int64_t val); -void store_uint64(DBusMessageIter* iter, uint64_t val); -void store_string(DBusMessageIter* iter, const char* val); - -/* - * Helpers for parsing DBus messages - */ -enum { - ABRT_DBUS_ERROR = -1, - ABRT_DBUS_LAST_FIELD = 0, - ABRT_DBUS_MORE_FIELDS = 1, - /* note that dbus_message_iter_next() returns FALSE on last field - * and TRUE if there are more fields. - * It maps exactly on the above constants. */ -}; -/* Checks type, loads data, advances to the next arg. - * Returns TRUE if next arg exists. - */ -//int load_bool(DBusMessageIter* iter, bool& val); -int load_int32(DBusMessageIter* iter, int32_t *val); -int load_uint32(DBusMessageIter* iter, uint32_t *val); -int load_int64(DBusMessageIter* iter, int64_t *val); -int load_uint64(DBusMessageIter* iter, uint64_t *val); -int load_charp(DBusMessageIter* iter, const char **val); - -#ifdef __cplusplus -} -#endif - - -/* - * C++ style stuff - */ - -#ifdef __cplusplus - -#include <map> -#include <vector> - -/* - * Helpers for building DBus messages - */ - -static inline std::string ssprintf(const char *format, ...) -{ - va_list p; - char *string_ptr; - - va_start(p, format); - string_ptr = xvasprintf(format, p); - va_end(p); - - std::string res = string_ptr; - free(string_ptr); - return res; -} - -//static inline void store_val(DBusMessageIter* iter, bool val) { store_bool(iter, val); } -static inline void store_val(DBusMessageIter* iter, int32_t val) { store_int32(iter, val); } -static inline void store_val(DBusMessageIter* iter, uint32_t val) { store_uint32(iter, val); } -static inline void store_val(DBusMessageIter* iter, int64_t val) { store_int64(iter, val); } -static inline void store_val(DBusMessageIter* iter, uint64_t val) { store_uint64(iter, val); } -static inline void store_val(DBusMessageIter* iter, const char* val) { store_string(iter, val); } -static inline void store_val(DBusMessageIter* iter, const std::string& val) { store_string(iter, val.c_str()); } - -/* Templates for vector and map */ -template <typename T> struct abrt_dbus_type {}; -//template <> struct abrt_dbus_type<bool> { static const char* csig() { return "b"; } }; -template <> struct abrt_dbus_type<int32_t> { static const char* csig() { return "i"; } static std::string sig(); }; -template <> struct abrt_dbus_type<uint32_t> { static const char* csig() { return "u"; } static std::string sig(); }; -template <> struct abrt_dbus_type<int64_t> { static const char* csig() { return "x"; } static std::string sig(); }; -template <> struct abrt_dbus_type<uint64_t> { static const char* csig() { return "t"; } static std::string sig(); }; -template <> struct abrt_dbus_type<std::string> { static const char* csig() { return "s"; } static std::string sig(); }; -#define ABRT_DBUS_SIG(T) (abrt_dbus_type<T>::csig() ? abrt_dbus_type<T>::csig() : abrt_dbus_type<T>::sig().c_str()) -template <typename E> -struct abrt_dbus_type< std::vector<E> > { - static const char* csig() { return NULL; } - static std::string sig() { return ssprintf("a%s", ABRT_DBUS_SIG(E)); } -}; -template <typename K, typename V> -struct abrt_dbus_type< std::map<K,V> > { - static const char* csig() { return NULL; } - static std::string sig() { return ssprintf("a{%s%s}", ABRT_DBUS_SIG(K), ABRT_DBUS_SIG(V)); } -}; - -template <typename E> -static void store_vector(DBusMessageIter* iter, const std::vector<E>& val) -{ - DBusMessageIter sub_iter; - if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, ABRT_DBUS_SIG(E), &sub_iter)) - die_out_of_memory(); - - typename std::vector<E>::const_iterator vit = val.begin(); - for (; vit != val.end(); ++vit) - { - store_val(&sub_iter, *vit); - } - - if (!dbus_message_iter_close_container(iter, &sub_iter)) - die_out_of_memory(); -} -/* -template<> -static void store_vector(DBus::MessageIter &iter, const std::vector<uint8_t>& val) -{ - if we use such vector, MUST add specialized code here (see in dbus-c++ source) -} -*/ -template <typename K, typename V> -static void store_map(DBusMessageIter* iter, const std::map<K,V>& val) -{ - DBusMessageIter sub_iter; - if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, - ssprintf("{%s%s}", ABRT_DBUS_SIG(K), ABRT_DBUS_SIG(V)).c_str(), - &sub_iter)) - die_out_of_memory(); - - typename std::map<K,V>::const_iterator mit = val.begin(); - for (; mit != val.end(); ++mit) - { - DBusMessageIter sub_sub_iter; - if (!dbus_message_iter_open_container(&sub_iter, DBUS_TYPE_DICT_ENTRY, NULL, &sub_sub_iter)) - die_out_of_memory(); - store_val(&sub_sub_iter, mit->first); - store_val(&sub_sub_iter, mit->second); - if (!dbus_message_iter_close_container(&sub_iter, &sub_sub_iter)) - die_out_of_memory(); - } - - if (!dbus_message_iter_close_container(iter, &sub_iter)) - die_out_of_memory(); -} - -template <typename E> -static inline void store_val(DBusMessageIter* iter, const std::vector<E>& val) { store_vector(iter, val); } -template <typename K, typename V> -static inline void store_val(DBusMessageIter* iter, const std::map<K,V>& val) { store_map(iter, val); } - - -/* - * Helpers for parsing DBus messages - */ - -//static inline int load_val(DBusMessageIter* iter, bool &val) { return load_bool(iter, &val); } -static inline int load_val(DBusMessageIter* iter, int32_t &val) { return load_int32(iter, &val); } -static inline int load_val(DBusMessageIter* iter, uint32_t &val) { return load_uint32(iter, &val); } -static inline int load_val(DBusMessageIter* iter, int64_t &val) { return load_int64(iter, &val); } -static inline int load_val(DBusMessageIter* iter, uint64_t &val) { return load_uint64(iter, &val); } -static inline int load_val(DBusMessageIter* iter, const char*& val) { return load_charp(iter, &val); } -static inline int load_val(DBusMessageIter* iter, std::string& val) -{ - const char* str; - int r = load_charp(iter, &str); - val = str; - return r; -} - -/* Templates for vector and map */ -template <typename E> -static int load_vector(DBusMessageIter* iter, std::vector<E>& val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_ARRAY) - { - error_msg("array expected in dbus message, but not found ('%c')", type); - return -1; - } - - DBusMessageIter sub_iter; - dbus_message_iter_recurse(iter, &sub_iter); - - int r; -//int cnt = 0; - /* When the vector has 0 elements, we see DBUS_TYPE_INVALID here */ - type = dbus_message_iter_get_arg_type(&sub_iter); - if (type != DBUS_TYPE_INVALID) - { - do { - E elem; -//cnt++; - r = load_val(&sub_iter, elem); - if (r < 0) - return r; - val.push_back(elem); - } while (r == ABRT_DBUS_MORE_FIELDS); - } -//log("%s: %d elems", __func__, cnt); - - return dbus_message_iter_next(iter); -} -/* -template<> -static int load_vector(DBusMessageIter* iter, std::vector<uint8_t>& val) -{ - if we use such vector, MUST add specialized code here (see in dbus-c++ source) -} -*/ -template <typename K, typename V> -static int load_map(DBusMessageIter* iter, std::map<K,V>& val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_ARRAY) - { - error_msg("array expected in dbus message, but not found ('%c')", type); - return -1; - } - - DBusMessageIter sub_iter; - dbus_message_iter_recurse(iter, &sub_iter); - - bool next_exists; - int r; -//int cnt = 0; - do { - type = dbus_message_iter_get_arg_type(&sub_iter); - if (type != DBUS_TYPE_DICT_ENTRY) - { - /* When the map has 0 elements, we see DBUS_TYPE_INVALID (on the first iteration) */ - if (type == DBUS_TYPE_INVALID) - break; - error_msg("sub_iter type is not DBUS_TYPE_DICT_ENTRY (%c)!", type); - return -1; - } - - DBusMessageIter sub_sub_iter; - dbus_message_iter_recurse(&sub_iter, &sub_sub_iter); - - K key; - r = load_val(&sub_sub_iter, key); - if (r != ABRT_DBUS_MORE_FIELDS) - { - if (r == ABRT_DBUS_LAST_FIELD) - error_msg("malformed map element in dbus message"); - return -1; - } - V value; - r = load_val(&sub_sub_iter, value); - if (r != ABRT_DBUS_LAST_FIELD) - { - if (r == ABRT_DBUS_MORE_FIELDS) - error_msg("malformed map element in dbus message"); - return -1; - } - val[key] = value; -//cnt++; - next_exists = dbus_message_iter_next(&sub_iter); - } while (next_exists); -//log("%s: %d elems", __func__, cnt); - - return dbus_message_iter_next(iter); -} - -template <typename E> -static inline int load_val(DBusMessageIter* iter, std::vector<E>& val) { return load_vector(iter, val); } -template <typename K, typename V> -static inline int load_val(DBusMessageIter* iter, std::map<K,V>& val) { return load_map(iter, val); } - -#endif /* __cplusplus */ - -#endif diff --git a/src/lib/abrt_types.c b/src/lib/abrt_types.c deleted file mode 100644 index 42100075..00000000 --- a/src/lib/abrt_types.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2010 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 "abrtlib.h" - -map_string_h *new_map_string(void) -{ - return g_hash_table_new_full(g_str_hash, g_str_equal, free, free); -} - -void free_map_string(map_string_h *ms) -{ - if (ms) - g_hash_table_destroy(ms); -} - -const char *get_map_string_item_or_empty(map_string_h *ms, const char *key) -{ - const char *v = (const char*)g_hash_table_lookup(ms, key); - if (!v) v = ""; - return v; -} diff --git a/src/lib/append_to_malloced_string.c b/src/lib/append_to_malloced_string.c deleted file mode 100644 index 430cef0b..00000000 --- a/src/lib/append_to_malloced_string.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2010 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 "abrtlib.h" - -char *append_to_malloced_string(char *mstr, const char *append) -{ - unsigned mlen = strlen(mstr); - mstr = (char*) xrealloc(mstr, mlen + strlen(append) + 1); - strcpy(mstr + mlen, append); - return mstr; -} diff --git a/src/lib/binhex.c b/src/lib/binhex.c deleted file mode 100644 index 1fcb7445..00000000 --- a/src/lib/binhex.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2010 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 version 2 - as published by the Free Software Foundation. - - 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 "abrtlib.h" - -static const char hexdigits_locase[] = "0123456789abcdef"; - -/* Emit a string of hex representation of bytes */ -char *bin2hex(char *dst, const char *str, int count) -{ - while (count) { - unsigned char c = *str++; - /* put lowercase hex digits */ - *dst++ = hexdigits_locase[c >> 4]; - *dst++ = hexdigits_locase[c & 0xf]; - count--; - } - return dst; -} - -/* Convert "xxxxxxxx" hex string to binary, no more than COUNT bytes */ -char *hex2bin(char *dst, const char *str, int count) -{ - /* Parts commented out with // allow parsing - * of strings like "xx:x:x:xx:xx:xx:xxxxxx" - * (IPv6, ethernet addresses and the like). - */ - errno = EINVAL; - while (*str && count) { - uint8_t val; - uint8_t c; - - c = *str++; - if (isdigit(c)) - val = c - '0'; - else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') - val = (c|0x20) - ('a' - 10); - else - return NULL; - val <<= 4; - c = *str; - if (isdigit(c)) - val |= c - '0'; - else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') - val |= (c|0x20) - ('a' - 10); - //else if (c == ':' || c == '\0') - // val >>= 4; - else - return NULL; - - *dst++ = val; - //if (c != '\0') - str++; - //if (*str == ':') - // str++; - count--; - } - errno = (*str ? ERANGE : 0); - return dst; -} diff --git a/src/lib/concat_path_file.c b/src/lib/concat_path_file.c deleted file mode 100644 index 4c946628..00000000 --- a/src/lib/concat_path_file.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Utility routines. - * - * Copyright (C) 2001 Erik Andersen - * - * Licensed under GPLv2 or later. - */ - -/* Concatenate path and filename to new allocated buffer. - * Add '/' only as needed (no duplicate // are produced). - * If path is NULL, it is assumed to be "/". - * filename should not be NULL. - */ - -#include "abrtlib.h" - -char *concat_path_file(const char *path, const char *filename) -{ - if (!path) - path = ""; - const char *end = path + strlen(path); - while (*filename == '/') - filename++; - return xasprintf("%s%s%s", path, (end != path && end[-1] != '/' ? "/" : ""), filename); -} diff --git a/src/lib/copy_file_recursive.c b/src/lib/copy_file_recursive.c deleted file mode 100644 index 48108a1d..00000000 --- a/src/lib/copy_file_recursive.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - Copyright (C) 2011 ABRT team - Copyright (C) 2011 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 "abrtlib.h" - -int copy_file_recursive(const char *source, const char *dest) -{ - /* This is a recursive function, try to minimize stack usage */ - /* NB: each struct stat is ~100 bytes */ - struct stat source_stat; - struct stat dest_stat; - int retval = 0; - int dest_exists = 0; - - if (strcmp(source, ".lock") == 0) - goto skip; - - if (stat(source, &source_stat) < 0) { - perror_msg("Can't stat '%s'", source); - return -1; - } - - if (lstat(dest, &dest_stat) < 0) { - if (errno != ENOENT) { - perror_msg("Can't stat '%s'", dest); - return -1; - } - } else { - if (source_stat.st_dev == dest_stat.st_dev - && source_stat.st_ino == dest_stat.st_ino - ) { - error_msg("'%s' and '%s' are the same file", source, dest); - return -1; - } - dest_exists = 1; - } - - if (S_ISDIR(source_stat.st_mode)) { - DIR *dp; - struct dirent *d; - - if (dest_exists) { - if (!S_ISDIR(dest_stat.st_mode)) { - error_msg("Target '%s' is not a directory", dest); - return -1; - } - /* race here: user can substitute a symlink between - * this check and actual creation of files inside dest */ - } else { - /* Create DEST */ - mode_t mode = source_stat.st_mode; - /* Allow owner to access new dir (at least for now) */ - mode |= S_IRWXU; - if (mkdir(dest, mode) < 0) { - perror_msg("Can't create directory '%s'", dest); - return -1; - } - } - /* Recursively copy files in SOURCE */ - dp = opendir(source); - if (dp == NULL) { - retval = -1; - goto ret; - } - - while (retval == 0 && (d = readdir(dp)) != NULL) { - char *new_source, *new_dest; - - if (dot_or_dotdot(d->d_name)) - continue; - new_source = concat_path_file(source, d->d_name); - new_dest = concat_path_file(dest, d->d_name); - if (copy_file_recursive(new_source, new_dest) < 0) - retval = -1; - free(new_source); - free(new_dest); - } - closedir(dp); - - goto ret; - } - - if (S_ISREG(source_stat.st_mode)) { - int src_fd; - int dst_fd; - mode_t new_mode; - - src_fd = open(source, O_RDONLY); - if (src_fd < 0) { - perror_msg("Can't open '%s'", source); - return -1; - } - - /* Do not try to open with weird mode fields */ - new_mode = source_stat.st_mode; - - // security problem versus (sym)link attacks - // dst_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, new_mode); - /* safe way: */ - dst_fd = open(dest, O_WRONLY|O_CREAT|O_EXCL, new_mode); - if (dst_fd < 0) { - close(src_fd); - return -1; - } - - if (copyfd_eof(src_fd, dst_fd, COPYFD_SPARSE) == -1) - retval = -1; - close(src_fd); - /* Careful: do check that buffered writes succeeded... */ - if (close(dst_fd) < 0) { - perror_msg("Error writing to '%s'", dest); - retval = -1; - } else { - /* (Try to) copy atime and mtime */ - struct timeval atime_mtime[2]; - atime_mtime[0].tv_sec = source_stat.st_atime; - // note: if "st_atim.tv_nsec" doesn't compile, try "st_atimensec": - atime_mtime[0].tv_usec = source_stat.st_atim.tv_nsec / 1000; - atime_mtime[1].tv_sec = source_stat.st_mtime; - atime_mtime[1].tv_usec = source_stat.st_mtim.tv_nsec / 1000; - // note: can use utimensat when it is more widely supported: - utimes(dest, atime_mtime); - } - goto ret; - } - - /* Neither dir not regular file: skip */ - - skip: - log("Skipping '%s'", source); - ret: - return retval; -} diff --git a/src/lib/copyfd.c b/src/lib/copyfd.c deleted file mode 100644 index bfe0fa49..00000000 --- a/src/lib/copyfd.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright (C) 2010 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. -*/ - -/* - * Utility routines. - * - */ -#include "abrtlib.h" - -#define CONFIG_FEATURE_COPYBUF_KB 4 - -static const char msg_write_error[] = "write error"; -static const char msg_read_error[] = "read error"; - -static off_t full_fd_action(int src_fd, int dst_fd, off_t size, int flags) -{ - int status = -1; - off_t total = 0; - int last_was_seek = 0; -#if CONFIG_FEATURE_COPYBUF_KB <= 4 - char buffer[CONFIG_FEATURE_COPYBUF_KB * 1024]; - enum { buffer_size = sizeof(buffer) }; -#else - char *buffer; - int buffer_size; - - /* We want page-aligned buffer, just in case kernel is clever - * and can do page-aligned io more efficiently */ - buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, - /* ignored: */ -1, 0); - buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024; - if (buffer == MAP_FAILED) { - buffer = alloca(4 * 1024); - buffer_size = 4 * 1024; - } -#endif - - if (src_fd < 0) - goto out; - - if (!size) { - size = buffer_size; - status = 1; /* copy until eof */ - } - - while (1) { - ssize_t rd; - - rd = safe_read(src_fd, buffer, size > buffer_size ? buffer_size : size); - - if (!rd) { /* eof - all done */ - if (last_was_seek) { - if (lseek(dst_fd, -1, SEEK_CUR) < 0 - || safe_write(dst_fd, "", 1) != 1 - ) { - perror_msg("%s", msg_write_error); - break; - } - } - status = 0; - break; - } - if (rd < 0) { - perror_msg("%s", msg_read_error); - break; - } - /* dst_fd == -1 is a fake, else... */ - if (dst_fd >= 0) { - if (flags & COPYFD_SPARSE) { - ssize_t cnt = rd; - while (--cnt >= 0) - if (buffer[cnt] != 0) - goto need2write; - if (lseek(dst_fd, rd, SEEK_CUR) < 0) { - flags &= ~COPYFD_SPARSE; - goto need2write; - } - last_was_seek = 1; - } else { - need2write: - { - ssize_t wr = full_write(dst_fd, buffer, rd); - if (wr < rd) { - perror_msg("%s", msg_write_error); - break; - } - last_was_seek = 0; - } - } - } - total += rd; - if (status < 0) { /* if we aren't copying till EOF... */ - size -= rd; - if (!size) { - /* 'size' bytes copied - all done */ - status = 0; - break; - } - } - } - out: - -#if CONFIG_FEATURE_COPYBUF_KB > 4 - if (buffer_size != 4 * 1024) - munmap(buffer, buffer_size); -#endif - return status ? -1 : total; -} - -off_t copyfd_size(int fd1, int fd2, off_t size, int flags) -{ - if (size) { - return full_fd_action(fd1, fd2, size, flags); - } - return 0; -} - -void copyfd_exact_size(int fd1, int fd2, off_t size) -{ - off_t sz = copyfd_size(fd1, fd2, size, /*flags:*/ 0); - if (sz == size) - return; - if (sz != -1) - error_msg_and_die("short read"); - /* if sz == -1, copyfd_XX already complained */ - xfunc_die(); -} - -off_t copyfd_eof(int fd1, int fd2, int flags) -{ - return full_fd_action(fd1, fd2, 0, flags); -} - -off_t copy_file(const char *src_name, const char *dst_name, int mode) -{ - off_t r; - int src = open(src_name, O_RDONLY); - if (src < 0) - { - perror_msg("Can't open '%s'", src_name); - return -1; - } - int dst = open(dst_name, O_WRONLY | O_TRUNC | O_CREAT, mode); - if (dst < 0) - { - close(src); - perror_msg("Can't open '%s'", dst_name); - return -1; - } - r = copyfd_eof(src, dst, /*flags:*/ 0); - close(src); - close(dst); - return r; -} diff --git a/src/lib/create_dump_dir.c b/src/lib/create_dump_dir.c deleted file mode 100644 index 9839a96c..00000000 --- a/src/lib/create_dump_dir.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright (C) 2010 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 "abrtlib.h" - -static struct dump_dir *try_dd_create(const char *base_dir_name, const char *dir_name) -{ - char *path = concat_path_file(base_dir_name, dir_name); - struct dump_dir *dd = dd_create(path, (uid_t)-1L, 0640); - if (dd) - dd_create_basic_files(dd, (uid_t)-1L); - free(path); - return dd; -} - -struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name) -{ - char dir_name[sizeof("abrt-tmp-YYYY-MM-DD-HH:MM:SS-%lu") + sizeof(long)*3]; - sprintf(dir_name, "abrt-tmp-%s-%lu", iso_date_string(NULL), (long)getpid()); - - struct dump_dir *dd; - if (base_dir_name) - dd = try_dd_create(base_dir_name, dir_name); - else - { - /* Try /var/run/abrt */ - dd = try_dd_create(LOCALSTATEDIR"/run/abrt", dir_name); - /* Try $HOME/tmp */ - if (!dd) - { - char *home = getenv("HOME"); - if (home && home[0]) - { - home = concat_path_file(home, "tmp"); - /*mkdir(home, 0777); - do we want this? */ - dd = try_dd_create(home, dir_name); - free(home); - } - } -//TODO: try user's home dir obtained by getpwuid(getuid())? - /* Try /tmp */ - if (!dd) - dd = try_dd_create("/tmp", dir_name); - } - if (!dd) - return NULL; - - GHashTableIter iter; - char *name; - struct problem_item *value; - g_hash_table_iter_init(&iter, problem_data); - while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) - { - if (name[0] == '.' || strchr(name, '/')) - { - error_msg("Problem data field name contains disallowed chars: '%s'", name); - goto next; - } - -//FIXME: what to do with CD_FLAG_BINs?? - if (value->flags & CD_FLAG_BIN) - goto next; - - dd_save_text(dd, name, value->content); - next: ; - } - - return dd; -} diff --git a/src/lib/dirsize.c b/src/lib/dirsize.c deleted file mode 100644 index be927ad5..00000000 --- a/src/lib/dirsize.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) - Copyright (C) 2009 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 "abrtlib.h" - -double get_dirsize(const char *pPath) -{ - DIR *dp = opendir(pPath); - if (dp == NULL) - return 0; - - struct dirent *ep; - struct stat statbuf; - double size = 0; - while ((ep = readdir(dp)) != NULL) - { - if (dot_or_dotdot(ep->d_name)) - continue; - char *dname = concat_path_file(pPath, ep->d_name); - if (lstat(dname, &statbuf) != 0) - { - free(dname); - continue; - } - if (S_ISDIR(statbuf.st_mode)) - { - size += get_dirsize(dname); - } - else if (S_ISREG(statbuf.st_mode)) - { - size += statbuf.st_size; - } - free(dname); - } - closedir(dp); - return size; -} - -double get_dirsize_find_largest_dir( - const char *pPath, - char **worst_dir, - const char *excluded) -{ - if (worst_dir) - *worst_dir = NULL; - - DIR *dp = opendir(pPath); - if (dp == NULL) - return 0; - - struct dirent *ep; - struct stat statbuf; - double size = 0; - double maxsz = 0; - while ((ep = readdir(dp)) != NULL) - { - if (dot_or_dotdot(ep->d_name)) - continue; - char *dname = concat_path_file(pPath, ep->d_name); - if (lstat(dname, &statbuf) != 0) - { - free(dname); - continue; - } - if (S_ISDIR(statbuf.st_mode)) - { - double sz = get_dirsize(dname); - size += sz; - - if (worst_dir && (!excluded || strcmp(excluded, ep->d_name) != 0)) - { - /* Calculate "weighted" size and age - * w = sz_kbytes * age_mins */ - sz /= 1024; - long age = (time(NULL) - statbuf.st_mtime) / 60; - if (age > 0) - sz *= age; - - if (sz > maxsz) - { - maxsz = sz; - free(*worst_dir); - *worst_dir = xstrdup(ep->d_name); - } - } - } - else if (S_ISREG(statbuf.st_mode)) - { - size += statbuf.st_size; - } - free(dname); - } - closedir(dp); - return size; -} diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c deleted file mode 100644 index 03097ce1..00000000 --- a/src/lib/dump_dir.c +++ /dev/null @@ -1,839 +0,0 @@ -/* - Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) - Copyright (C) 2009 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 <sys/utsname.h> -#include "abrtlib.h" -#include "strbuf.h" - -// Locking logic: -// -// The directory is locked by creating a symlink named .lock inside it, -// whose value (where it "points to") is the pid of locking process. -// We use symlink, not an ordinary file, because symlink creation -// is an atomic operation. -// -// There are two cases where after .lock creation, we might discover -// that directory is not really free: -// * another process just created new directory, but didn't manage -// to lock it before us. -// * another process is deleting the directory, and we managed to sneak in -// and create .lock after it deleted all files (including .lock) -// but before it rmdir'ed the empty directory. -// -// Both these cases are detected by the fact that file named "time" -// is not present (it must be present in any valid dump dir). -// If after locking the dir we don't see time file, we remove the lock -// at once and back off. What happens in concurrent processes -// we interfered with? -// * "create new dump dir" process just re-tries locking. -// * "delete dump dir" process just retries rmdir. -// -// There is another case when we don't find time file: -// when the directory is not really a *dump* dir - user gave us -// an ordinary directory name by mistake. -// We detect it by bailing out of "lock, check time file; sleep -// and retry if it doesn't exist" loop using a counter. -// -// To make locking work reliably, it's important to set timeouts -// correctly. For example, dd_create should retry locking -// its newly-created directory much faster than dd_opendir -// tries to lock the directory it tries to open. - - -// How long to sleep between "symlink fails with EEXIST, -// readlink fails with ENOENT" tries. Someone just unlocked the dir. -// We never bail out in this case, we retry forever. -// The value can be really small: -#define SYMLINK_RETRY_USLEEP (10*1000) - -// How long to sleep when lock file with valid pid is seen by dd_opendir -// (we are waiting for other process to unlock or die): -#define WAIT_FOR_OTHER_PROCESS_USLEEP (500*1000) - -// How long to sleep when lock file with valid pid is seen by dd_create -// (some idiot jumped the gun and locked the dir we just created). -// Must not be the same as WAIT_FOR_OTHER_PROCESS_USLEEP (we depend on this) -// and should be small (we have the priority in locking, this is OUR dir): -#define CREATE_LOCK_USLEEP (10*1000) - -// How long to sleep after we locked a dir, found no time file -// (either we are racing with someone, or it's not a dump dir) -// and unlocked it; -// and after how many tries to give up and declare it's not a dump dir: -#define NO_TIME_FILE_USLEEP (50*1000) -#define NO_TIME_FILE_COUNT 10 - -// How long to sleep after we unlocked an empty dir, but then rmdir failed -// (some idiot jumped the gun and locked the dir we are deleting); -// and after how many tries to give up: -#define RMDIR_FAIL_USLEEP (10*1000) -#define RMDIR_FAIL_COUNT 50 - - -static char *load_text_file(const char *path, unsigned flags); - -static bool isdigit_str(const char *str) -{ - do - { - if (*str < '0' || *str > '9') return false; - str++; - } while (*str); - return true; -} - -static bool exist_file_dir(const char *path) -{ - struct stat buf; - if (stat(path, &buf) == 0) - { - if (S_ISDIR(buf.st_mode) || S_ISREG(buf.st_mode)) - { - return true; - } - } - return false; -} - -/* Return values: - * -1: error (in this case, errno is 0 if error message is already logged) - * 0: failed to lock (someone else has it locked) - * 1: success - */ -static int get_and_set_lock(const char* lock_file, const char* pid) -{ - while (symlink(pid, lock_file) != 0) - { - if (errno != EEXIST) - { - if (errno != ENOENT && errno != ENOTDIR && errno != EACCES) - { - perror_msg("Can't create lock file '%s'", lock_file); - errno = 0; - } - return -1; - } - - char pid_buf[sizeof(pid_t)*3 + 4]; - ssize_t r = readlink(lock_file, pid_buf, sizeof(pid_buf) - 1); - if (r < 0) - { - if (errno == ENOENT) - { - /* Looks like lock_file was deleted */ - usleep(SYMLINK_RETRY_USLEEP); /* avoid CPU eating loop */ - continue; - } - perror_msg("Can't read lock file '%s'", lock_file); - errno = 0; - return -1; - } - pid_buf[r] = '\0'; - - if (strcmp(pid_buf, pid) == 0) - { - log("Lock file '%s' is already locked by us", lock_file); - return 0; - } - if (isdigit_str(pid_buf)) - { - char pid_str[sizeof("/proc/") + sizeof(pid_buf)]; - sprintf(pid_str, "/proc/%s", pid_buf); - if (access(pid_str, F_OK) == 0) - { - log("Lock file '%s' is locked by process %s", lock_file, pid_buf); - return 0; - } - log("Lock file '%s' was locked by process %s, but it crashed?", lock_file, pid_buf); - } - /* The file may be deleted by now by other process. Ignore ENOENT */ - if (unlink(lock_file) != 0 && errno != ENOENT) - { - perror_msg("Can't remove stale lock file '%s'", lock_file); - errno = 0; - return -1; - } - } - - VERB1 log("Locked '%s'", lock_file); - return 1; -} - -static int dd_lock(struct dump_dir *dd, unsigned sleep_usec, int flags) -{ - if (dd->locked) - error_msg_and_die("Locking bug on '%s'", dd->dd_dirname); - - char pid_buf[sizeof(long)*3 + 2]; - sprintf(pid_buf, "%lu", (long)getpid()); - - unsigned dirname_len = strlen(dd->dd_dirname); - char lock_buf[dirname_len + sizeof("/.lock")]; - strcpy(lock_buf, dd->dd_dirname); - strcpy(lock_buf + dirname_len, "/.lock"); - - unsigned count = NO_TIME_FILE_COUNT; - retry: - while (1) - { - int r = get_and_set_lock(lock_buf, pid_buf); - if (r < 0) - return r; /* error */ - if (r > 0) - break; /* locked successfully */ - /* Other process has the lock, wait for it to go away */ - usleep(sleep_usec); - } - - /* Are we called by dd_opendir (as opposed to dd_create)? */ - if (sleep_usec == WAIT_FOR_OTHER_PROCESS_USLEEP) /* yes */ - { - strcpy(lock_buf + dirname_len, "/time"); - if (access(lock_buf, F_OK) != 0) - { - /* time file doesn't exist. We managed to lock the directory - * which was just created by somebody else, or is almost deleted - * by delete_file_dir. - * Unlock and back off. - */ - strcpy(lock_buf + dirname_len, "/.lock"); - xunlink(lock_buf); - VERB1 log("Unlocked '%s' (no time file)", lock_buf); - if (--count == 0) - { - errno = EISDIR; /* "this is an ordinary dir, not dump dir" */ - return -1; - } - usleep(NO_TIME_FILE_USLEEP); - goto retry; - } - } - - dd->locked = true; - return 0; -} - -static void dd_unlock(struct dump_dir *dd) -{ - if (dd->locked) - { - dd->locked = 0; - - unsigned dirname_len = strlen(dd->dd_dirname); - char lock_buf[dirname_len + sizeof("/.lock")]; - strcpy(lock_buf, dd->dd_dirname); - strcpy(lock_buf + dirname_len, "/.lock"); - xunlink(lock_buf); - - VERB1 log("Unlocked '%s'", lock_buf); - } -} - -static inline struct dump_dir *dd_init(void) -{ - return (struct dump_dir*)xzalloc(sizeof(struct dump_dir)); -} - -int dd_exist(struct dump_dir *dd, const char *path) -{ - char *full_path = concat_path_file(dd->dd_dirname, path); - int ret = exist_file_dir(full_path); - free(full_path); - return ret; -} - -void dd_close(struct dump_dir *dd) -{ - if (!dd) - return; - - dd_unlock(dd); - if (dd->next_dir) - { - closedir(dd->next_dir); - /* free(dd->next_dir); - WRONG! */ - } - - free(dd->dd_dirname); - free(dd); -} - -static char* rm_trailing_slashes(const char *dir) -{ - unsigned len = strlen(dir); - while (len != 0 && dir[len-1] == '/') - len--; - return xstrndup(dir, len); -} - -struct dump_dir *dd_opendir(const char *dir, int flags) -{ - struct dump_dir *dd = dd_init(); - - dir = dd->dd_dirname = rm_trailing_slashes(dir); - - struct stat stat_buf; - stat(dir, &stat_buf); - /* & 0666 should remove the executable bit */ - dd->mode = (stat_buf.st_mode & 0666); - - errno = 0; - if (dd_lock(dd, WAIT_FOR_OTHER_PROCESS_USLEEP, flags) < 0) - { - if ((flags & DD_OPEN_READONLY) && errno == EACCES) - { - /* Directory is not writable. If it seems to be readable, - * return "read only" dd, not NULL */ - if (stat(dir, &stat_buf) == 0 - && S_ISDIR(stat_buf.st_mode) - && access(dir, R_OK) == 0 - ) { - return dd; - } - } - if (errno == EISDIR) - { - /* EISDIR: dd_lock can lock the dir, but it sees no time file there, - * even after it retried many times. It must be an ordinary directory! - * - * Without this check, e.g. abrt-action-print happily prints any current - * directory when run without arguments, because its option -d DIR - * defaults to "."! - */ - error_msg("'%s' is not a dump directory", dir); - } - else if (errno == ENOENT || errno == ENOTDIR) - { - if (!(flags & DD_FAIL_QUIETLY_ENOENT)) - error_msg("'%s' does not exist", dir); - } - else - { - if (!(flags & DD_FAIL_QUIETLY_EACCES)) - perror_msg("Can't access '%s'", dir); - } - dd_close(dd); - return NULL; - } - - dd->dd_uid = (uid_t)-1L; - dd->dd_gid = (gid_t)-1L; - if (geteuid() == 0) - { - /* In case caller would want to create more files, he'll need uid:gid */ - struct stat stat_buf; - if (stat(dir, &stat_buf) != 0 || !S_ISDIR(stat_buf.st_mode)) - { - error_msg("Can't stat '%s', or it is not a directory", dir); - dd_close(dd); - return NULL; - } - dd->dd_uid = stat_buf.st_uid; - dd->dd_gid = stat_buf.st_gid; - } - - return dd; -} - -/* Create a fresh empty debug dump dir. - * - * Security: we should not allow users to write new files or write - * into existing ones, but they should be able to read them. - * - * @param uid - * Crashed application's User Id - * - * We currently have only three callers: - * kernel oops hook: uid -> not saved, so everyone can steal and work with it - * this hook runs under 0:0 - * ccpp hook: uid=uid of crashed user's binary - * this hook runs under 0:0 - * python hook: uid=uid of crashed user's script - * this hook runs under abrt:gid - * - * Currently, we set dir's gid to passwd(uid)->pw_gid parameter, and we set uid to - * abrt's user id. We do not allow write access to group. - */ -struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t mode) -{ - /* a little trick to copy read bits from file mode to exec bit of dir mode*/ - mode_t dir_mode = mode | ((mode & 0444) >> 2); - struct dump_dir *dd = dd_init(); - - dd->mode = mode; - - /* Unlike dd_opendir, can't use realpath: the directory doesn't exist yet, - * realpath will always return NULL. We don't really have to: - * dd_opendir(".") makes sense, dd_create(".") does not. - */ - dir = dd->dd_dirname = rm_trailing_slashes(dir); - - const char *last_component = strrchr(dir, '/'); - if (last_component) - last_component++; - else - last_component = dir; - if (dot_or_dotdot(last_component)) - { - /* dd_create("."), dd_create(".."), dd_create("dir/."), - * dd_create("dir/..") and similar are madness, refuse them. - */ - error_msg("Bad dir name '%s'", dir); - dd_close(dd); - return NULL; - } - - bool created_parents = false; - try_again: - /* Was creating it with mode 0700 and user as the owner, but this allows - * the user to replace any file in the directory, changing security-sensitive data - * (e.g. "uid", "analyzer", "executable") - */ - if (mkdir(dir, dir_mode) == -1) - { - int err = errno; - if (!created_parents && errno == ENOENT) - { - char *p = dd->dd_dirname + 1; - while ((p = strchr(p, '/')) != NULL) - { - *p = '\0'; - int r = (mkdir(dd->dd_dirname, 0755) == 0 || errno == EEXIST); - *p++ = '/'; - if (!r) - goto report_err; - } - created_parents = true; - goto try_again; - } - report_err: - errno = err; - perror_msg("Can't create directory '%s'", dir); - dd_close(dd); - return NULL; - } - - if (dd_lock(dd, CREATE_LOCK_USLEEP, /*flags:*/ 0) < 0) - { - dd_close(dd); - return NULL; - } - - /* mkdir's mode (above) can be affected by umask, fix it */ - if (chmod(dir, dir_mode) == -1) - { - perror_msg("can't change mode of '%s'", dir); - dd_close(dd); - return NULL; - } - - dd->dd_uid = (uid_t)-1L; - dd->dd_gid = (gid_t)-1L; - if (uid != (uid_t)-1L) - { - /* Get ABRT's user id */ - dd->dd_uid = 0; - struct passwd *pw = getpwnam("abrt"); - if (pw) - dd->dd_uid = pw->pw_uid; - else - error_msg("user 'abrt' does not exist, using uid 0"); - - /* Get crashed application's group id */ - /*dd->dd_gid = 0; - dd_init did this already */ - pw = getpwuid(uid); - if (pw) - dd->dd_gid = pw->pw_gid; - else - error_msg("User %lu does not exist, using gid 0", (long)uid); - - if (chown(dir, dd->dd_uid, dd->dd_gid) == -1) - { - perror_msg("can't change '%s' ownership to %lu:%lu", dir, - (long)dd->dd_uid, (long)dd->dd_gid); - } - } - - return dd; -} - -void dd_create_basic_files(struct dump_dir *dd, uid_t uid) -{ - char long_str[sizeof(long) * 3 + 2]; - - time_t t = time(NULL); - sprintf(long_str, "%lu", (long)t); - dd_save_text(dd, FILENAME_TIME, long_str); - - /* it doesn't make sense to create the uid file if uid == -1 */ - if (uid != (uid_t)-1L) - { - sprintf(long_str, "%li", (long)uid); - dd_save_text(dd, FILENAME_UID, long_str); - } - - struct utsname buf; - uname(&buf); /* never fails */ - dd_save_text(dd, FILENAME_KERNEL, buf.release); - dd_save_text(dd, FILENAME_ARCHITECTURE, buf.machine); - dd_save_text(dd, FILENAME_HOSTNAME, buf.nodename); - - char *release = load_text_file("/etc/system-release", - DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE); - if (!release) - release = load_text_file("/etc/redhat-release", /*flags:*/ 0); - dd_save_text(dd, FILENAME_OS_RELEASE, release); - free(release); -} - -void dd_sanitize_mode_and_owner(struct dump_dir *dd) -{ - /* Don't sanitize if we aren't run under root: - * we assume that during file creation (by whatever means, - * even by "hostname >file" in abrt_event.conf) - * normal umask-based mode setting takes care of correct mode, - * and uid:gid is, of course, set to user's uid and gid. - * - * For root operating on /var/spool/abrt/USERS_PROBLEM, this isn't true: - * "hostname >file", for example, would create file OWNED BY ROOT! - * This routine resets mode and uid:gid for all such files. - */ - if (dd->dd_uid == (uid_t)-1) - return; - - if (!dd->locked) - error_msg_and_die("dump_dir is not opened"); /* bug */ - - DIR *d = opendir(dd->dd_dirname); - if (!d) - return; - - struct dirent *dent; - while ((dent = readdir(d)) != NULL) - { - if (dent->d_name[0] == '.') /* ".lock", ".", ".."? skip */ - continue; - char *full_path = concat_path_file(dd->dd_dirname, dent->d_name); - struct stat statbuf; - if (lstat(full_path, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) - { - if ((statbuf.st_mode & 0777) != dd->mode) - chmod(full_path, dd->mode); - if (statbuf.st_uid != dd->dd_uid || statbuf.st_gid != dd->dd_gid) - { - if (chown(full_path, dd->dd_uid, dd->dd_gid) != 0) - { - perror_msg("can't change '%s' ownership to %lu:%lu", full_path, - (long)dd->dd_uid, (long)dd->dd_gid); - } - } - } - free(full_path); - } - closedir(d); -} - -static int delete_file_dir(const char *dir, bool skip_lock_file) -{ - DIR *d = opendir(dir); - if (!d) - { - /* The caller expects us to error out only if the directory - * still exists (not deleted). If directory - * *doesn't exist*, return 0 and clear errno. - */ - if (errno == ENOENT || errno == ENOTDIR) - { - errno = 0; - return 0; - } - return -1; - } - - bool unlink_lock_file = false; - struct dirent *dent; - while ((dent = readdir(d)) != NULL) - { - if (dot_or_dotdot(dent->d_name)) - continue; - if (skip_lock_file && strcmp(dent->d_name, ".lock") == 0) - { - unlink_lock_file = true; - continue; - } - char *full_path = concat_path_file(dir, dent->d_name); - if (unlink(full_path) == -1 && errno != ENOENT) - { - int err = 0; - if (errno == EISDIR) - { - errno = 0; - err = delete_file_dir(full_path, /*skip_lock_file:*/ false); - } - if (errno || err) - { - perror_msg("Can't remove '%s'", full_path); - free(full_path); - closedir(d); - return -1; - } - } - free(full_path); - } - closedir(d); - - /* Here we know for sure that all files/subdirs we found via readdir - * were deleted successfully. If rmdir below fails, we assume someone - * is racing with us and created a new file. - */ - - if (unlink_lock_file) - { - char *full_path = concat_path_file(dir, ".lock"); - xunlink(full_path); - free(full_path); - - unsigned cnt = RMDIR_FAIL_COUNT; - do { - if (rmdir(dir) == 0) - return 0; - /* Someone locked the dir after unlink, but before rmdir. - * This "someone" must be dd_lock(). - * It detects this (by seeing that there is no time file) - * and backs off at once. So we need to just retry rmdir, - * with minimal sleep. - */ - usleep(RMDIR_FAIL_USLEEP); - } while (--cnt != 0); - } - - int r = rmdir(dir); - if (r) - perror_msg("Can't remove directory '%s'", dir); - return r; -} - -int dd_delete(struct dump_dir *dd) -{ - int r = delete_file_dir(dd->dd_dirname, /*skip_lock_file:*/ true); - dd->locked = 0; /* delete_file_dir already removed .lock */ - dd_close(dd); - return r; -} - -static char *load_text_file(const char *path, unsigned flags) -{ - FILE *fp = fopen(path, "r"); - if (!fp) - { - if (!(flags & DD_FAIL_QUIETLY_ENOENT)) - perror_msg("Can't open file '%s'", path); - return (flags & DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE ? NULL : xstrdup("")); - } - - struct strbuf *buf_content = strbuf_new(); - int oneline = 0; - int ch; - while ((ch = fgetc(fp)) != EOF) - { -//TODO? \r -> \n? -//TODO? strip trailing spaces/tabs? - if (ch == '\n') - oneline = (oneline << 1) | 1; - if (ch == '\0') - ch = ' '; - if (isspace(ch) || ch >= ' ') /* used !iscntrl, but it failed on unicode */ - strbuf_append_char(buf_content, ch); - } - fclose(fp); - - char last = oneline != 0 ? buf_content->buf[buf_content->len - 1] : 0; - if (last == '\n') - { - /* If file contains exactly one '\n' and it is at the end, remove it. - * This enables users to use simple "echo blah >file" in order to create - * short string items in dump dirs. - */ - if (oneline == 1) - buf_content->buf[--buf_content->len] = '\0'; - } - else /* last != '\n' */ - { - /* Last line is unterminated, fix it */ - /* Cases: */ - /* oneline=0: "qwe" - DONT fix this! */ - /* oneline=1: "qwe\nrty" - two lines in fact */ - /* oneline>1: "qwe\nrty\uio" */ - if (oneline >= 1) - strbuf_append_char(buf_content, '\n'); - } - - return strbuf_free_nobuf(buf_content); -} - -static bool save_binary_file(const char *path, const char* data, unsigned size, uid_t uid, gid_t gid, mode_t mode) -{ - /* the mode is set by the caller, see dd_create() for security analysis */ - unlink(path); - int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode); - if (fd < 0) - { - perror_msg("Can't open file '%s'", path); - return false; - } - - if (uid != (uid_t)-1L) - { - if (fchown(fd, uid, gid) == -1) - { - perror_msg("can't change '%s' ownership to %lu:%lu", path, (long)uid, (long)gid); - } - } - - unsigned r = full_write(fd, data, size); - close(fd); - if (r != size) - { - error_msg("Can't save file '%s'", path); - return false; - } - - return true; -} - -char* dd_load_text_ext(const struct dump_dir *dd, const char *name, unsigned flags) -{ -// if (!dd->locked) -// error_msg_and_die("dump_dir is not opened"); /* bug */ - - /* Compat with old abrt dumps. Remove in abrt-2.1 */ - if (strcmp(name, "release") == 0) - name = FILENAME_OS_RELEASE; - - char *full_path = concat_path_file(dd->dd_dirname, name); - char *ret = load_text_file(full_path, flags); - free(full_path); - - return ret; -} - -char* dd_load_text(const struct dump_dir *dd, const char *name) -{ - return dd_load_text_ext(dd, name, /*flags:*/ 0); -} - -void dd_save_text(struct dump_dir *dd, const char *name, const char *data) -{ - if (!dd->locked) - error_msg_and_die("dump_dir is not opened"); /* bug */ - - char *full_path = concat_path_file(dd->dd_dirname, name); - save_binary_file(full_path, data, strlen(data), dd->dd_uid, dd->dd_gid, dd->mode); - free(full_path); -} - -void dd_save_binary(struct dump_dir* dd, const char* name, const char* data, unsigned size) -{ - if (!dd->locked) - error_msg_and_die("dump_dir is not opened"); /* bug */ - - char *full_path = concat_path_file(dd->dd_dirname, name); - save_binary_file(full_path, data, size, dd->dd_uid, dd->dd_gid, dd->mode); - free(full_path); -} - -void add_reported_to(struct dump_dir *dd, const char *line) -{ - if (!dd->locked) - error_msg_and_die("dump_dir is not opened"); /* bug */ - - char *reported_to = dd_load_text_ext(dd, FILENAME_REPORTED_TO, DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE); - if (reported_to) - { - unsigned len_line = strlen(line); - char *p = reported_to; - while (*p) - { - if (strncmp(p, line, len_line) == 0 && (p[len_line] == '\n' || p[len_line] == '\0')) - goto ret; - p = strchrnul(p, '\n'); - if (!*p) - break; - p++; - } - if (p != reported_to && p[-1] != '\n') - reported_to = append_to_malloced_string(reported_to, "\n"); - reported_to = append_to_malloced_string(reported_to, line); - reported_to = append_to_malloced_string(reported_to, "\n"); - } - else - reported_to = xasprintf("%s\n", line); - dd_save_text(dd, FILENAME_REPORTED_TO, reported_to); - ret: - free(reported_to); -} - -DIR *dd_init_next_file(struct dump_dir *dd) -{ -// if (!dd->locked) -// error_msg_and_die("dump_dir is not opened"); /* bug */ - - if (dd->next_dir) - closedir(dd->next_dir); - - dd->next_dir = opendir(dd->dd_dirname); - if (!dd->next_dir) - { - error_msg("Can't open directory '%s'", dd->dd_dirname); - } - - return dd->next_dir; -} - -int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name) -{ - if (dd->next_dir == NULL) - return 0; - - struct dirent *dent; - while ((dent = readdir(dd->next_dir)) != NULL) - { - if (is_regular_file(dent, dd->dd_dirname)) - { - if (short_name) - *short_name = xstrdup(dent->d_name); - if (full_name) - *full_name = concat_path_file(dd->dd_dirname, dent->d_name); - return 1; - } - } - - closedir(dd->next_dir); - dd->next_dir = NULL; - return 0; -} - -/* Utility function */ -void delete_dump_dir(const char *dirname) -{ - struct dump_dir *dd = dd_opendir(dirname, /*flags:*/ 0); - if (dd) - { - dd_delete(dd); - } -} diff --git a/src/lib/encbase64.c b/src/lib/encbase64.c deleted file mode 100644 index 6a6f1f75..00000000 --- a/src/lib/encbase64.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2006 Rob Landley <rob@landley.net> - * - * Licensed under GPLv2 or later. - */ -#include "abrtlib.h" /* xmalloc */ - -/* Conversion table for base 64 */ -static const char tbl_base64[65 /*+ 2*/] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/', - '=' /* termination character */, - // '\n', '\0' /* needed for uudecode.c */ -}; - -/* Conversion table for uuencode -const char tbl_uuencode[65] ALIGN1 = { - '`', '!', '"', '#', '$', '%', '&', '\'', - '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', ':', ';', '<', '=', '>', '?', - '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', - '`' -}; -*/ - -/* - * Encode bytes at S of length LENGTH. - * Result will be 0-terminated, and must point to a writable - * buffer of at least 1+BASE64_LENGTH(length) bytes, - * where BASE64_LENGTH(len) = 4 * ((LENGTH + 2) / 3) - */ -static void encode_64bit(char *p, const void *src, int length, const char *tbl) -{ - const unsigned char *s = (const unsigned char *)src; - - /* Transform the 3x8 bits to 4x6 bits */ - while (length > 0) { - unsigned s1, s2; - - /* Are s[1], s[2] valid or should be assumed 0? */ - s1 = s2 = 0; - length -= 3; /* can be >=0, -1, -2 */ - if (length >= -1) { - s1 = s[1]; - if (length >= 0) - s2 = s[2]; - } - *p++ = tbl[s[0] >> 2]; - *p++ = tbl[((s[0] & 3) << 4) + (s1 >> 4)]; - *p++ = tbl[((s1 & 0xf) << 2) + (s2 >> 6)]; - *p++ = tbl[s2 & 0x3f]; - s += 3; - } - /* Zero-terminate */ - *p = '\0'; - /* If length is -2 or -1, pad last char or two */ - while (length) { - *--p = tbl[64]; - length++; - } -} - -char *encode_base64(const void *src, int length) -{ - char *dst = (char *)xmalloc(4 * ((length + 2) / 3) + 1); - encode_64bit(dst, src, length, tbl_base64); - return dst; -} diff --git a/src/lib/event_config.c b/src/lib/event_config.c deleted file mode 100644 index 38da44ef..00000000 --- a/src/lib/event_config.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - Copyright (C) 2011 ABRT Team - Copyright (C) 2011 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 "abrtlib.h" - -GHashTable *g_event_config_list; -static GHashTable *g_event_config_symlinks; - -event_option_t *new_event_option(void) -{ - return xzalloc(sizeof(event_option_t)); -} - -event_config_t *new_event_config(void) -{ - return xzalloc(sizeof(event_config_t)); -} - -void free_event_option(event_option_t *p) -{ - if (!p) - return; - free(p->eo_name); - free(p->eo_value); - free(p->eo_label); - free(p->eo_note_html); - //free(p->eo_description); - //free(p->eo_allowed_value); - free(p); -} - -void free_event_config(event_config_t *p) -{ - if (!p) - return; - - free(p->screen_name); - free(p->description); - free(p->long_descr); - free(p->ec_creates_items); - free(p->ec_requires_items); - free(p->ec_exclude_items_by_default); - free(p->ec_include_items_by_default); - free(p->ec_exclude_items_always); - GList *opt; - for (opt = p->options; opt; opt = opt->next) - free_event_option(opt->data); - g_list_free(p->options); - - free(p); -} - - -static int cmp_event_option_name_with_string(gconstpointer a, gconstpointer b) -{ - const event_option_t *evopt = a; - return !evopt->eo_name || strcmp(evopt->eo_name, (char *)b) != 0; -} - -event_option_t *get_event_option_from_list(const char *name, GList *options) -{ - GList *elem = g_list_find_custom(options, name, &cmp_event_option_name_with_string); - if (elem) - return (event_option_t *)elem->data; - return NULL; -} - -static void load_config_files(const char *dir_path) -{ - DIR *dir; - struct dirent *dent; - - /* Load .conf files */ - dir = opendir(dir_path); - if (!dir) - return; - while ((dent = readdir(dir)) != NULL) - { - char *ext = strrchr(dent->d_name, '.'); - if (!ext) - continue; - if (strcmp(ext + 1, "conf") != 0) - continue; - - char *fullname = concat_path_file(dir_path, dent->d_name); - - *ext = '\0'; - event_config_t *event_config = get_event_config(dent->d_name); - bool new_config = (!event_config); - if (new_config) - event_config = new_event_config(); - - map_string_h *keys_and_values = new_map_string(); - - load_conf_file(fullname, keys_and_values, /*skipKeysWithoutValue:*/ false); - free(fullname); - - /* Insert or replace every key/value from keys_and_values to event_config->option */ - GHashTableIter iter; - char *name; - char *value; - g_hash_table_iter_init(&iter, keys_and_values); - while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) - { - event_option_t *opt; - GList *elem = g_list_find_custom(event_config->options, name, - cmp_event_option_name_with_string); - if (elem) - { - opt = elem->data; - // log("conf: replacing '%s' value:'%s'->'%s'", name, opt->value, value); - free(opt->eo_value); - } - else - { - // log("conf: new value %s='%s'", name, value); - opt = new_event_option(); - opt->eo_name = xstrdup(name); - } - opt->eo_value = xstrdup(value); - if (!elem) - event_config->options = g_list_append(event_config->options, opt); - } - - free_map_string(keys_and_values); - - if (new_config) - g_hash_table_replace(g_event_config_list, xstrdup(dent->d_name), event_config); - } - closedir(dir); -} - -/* (Re)loads data from /etc/abrt/events/foo.{xml,conf} and ~/.abrt/events/foo.conf */ -void load_event_config_data(void) -{ - free_event_config_data(); - - if (!g_event_config_list) - g_event_config_list = g_hash_table_new_full( - /*hash_func*/ g_str_hash, - /*key_equal_func:*/ g_str_equal, - /*key_destroy_func:*/ free, - /*value_destroy_func:*/ (GDestroyNotify) free_event_config - ); - if (!g_event_config_symlinks) - g_event_config_symlinks = g_hash_table_new_full( - /*hash_func*/ g_str_hash, - /*key_equal_func:*/ g_str_equal, - /*key_destroy_func:*/ free, - /*value_destroy_func:*/ free - ); - - DIR *dir; - struct dirent *dent; - - /* Load .xml files */ - dir = opendir(EVENTS_DIR); - if (!dir) - return; - while ((dent = readdir(dir)) != NULL) - { - char *ext = strrchr(dent->d_name, '.'); - if (!ext) - continue; - if (strcmp(ext + 1, "xml") != 0) - continue; - - char *fullname = concat_path_file(EVENTS_DIR, dent->d_name); - *ext = '\0'; - - struct stat buf; - if (0 != lstat(fullname, &buf)) - continue; - if (S_ISLNK(buf.st_mode)) - { - GError *error = NULL; - gchar *link = g_file_read_link(fullname, &error); - if (error != NULL) - error_msg_and_die("Error reading symlink '%s': %s", fullname, error->message); - - gchar *target = g_path_get_basename(link); - char *ext = strrchr(target, '.'); - if (!ext || 0 != strcmp(ext + 1, "xml")) - error_msg_and_die("Invalid event symlink '%s': expected it to" - " point to another xml file", fullname); - *ext = '\0'; - g_hash_table_replace(g_event_config_symlinks, xstrdup(dent->d_name), target); - g_free(link); - /* don't free target, it is owned by the hash table now */ - continue; - } - - event_config_t *event_config = get_event_config(dent->d_name); - bool new_config = (!event_config); - if (new_config) - event_config = new_event_config(); - - load_event_description_from_file(event_config, fullname); - free(fullname); - - if (new_config) - g_hash_table_replace(g_event_config_list, xstrdup(dent->d_name), event_config); - } - closedir(dir); - - load_config_files(EVENTS_DIR); - - char *HOME = getenv("HOME"); - if (!HOME || !HOME[0]) - return; - HOME = concat_path_file(HOME, ".abrt/events"); - load_config_files(HOME); - free(HOME); -} - -/* Frees all loaded data */ -void free_event_config_data(void) -{ - if (g_event_config_list) - { - g_hash_table_destroy(g_event_config_list); - g_event_config_list = NULL; - } - if (g_event_config_symlinks) - { - g_hash_table_destroy(g_event_config_symlinks); - g_event_config_symlinks = NULL; - } -} - -event_config_t *get_event_config(const char *name) -{ - if (!g_event_config_list) - return NULL; - 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_event_config_list, name); -} - -GList *export_event_config(const char *event_name) -{ - GList *env_list = NULL; - - event_config_t *config = get_event_config(event_name); - if (config) - { - GList *lopt; - for (lopt = config->options; lopt; lopt = lopt->next) - { - event_option_t *opt = lopt->data; - if (!opt->eo_value) - continue; - char *var_val = xasprintf("%s=%s", opt->eo_name, opt->eo_value); - VERB3 log("Exporting '%s'", var_val); - env_list = g_list_prepend(env_list, var_val); - putenv(var_val); - } - } - - return env_list; -} - -void unexport_event_config(GList *env_list) -{ - while (env_list) - { - char *var_val = env_list->data; - VERB3 log("Unexporting '%s'", var_val); - safe_unsetenv(var_val); - env_list = g_list_remove(env_list, var_val); - free(var_val); - } -} - -/* return NULL if successful otherwise appropriate error message */ -static char *validate_event_option(event_option_t *opt) -{ - if (!opt->eo_allow_empty && (!opt->eo_value || !opt->eo_value[0])) - return xstrdup(_("Missing mandatory value")); - - /* if value is NULL and allow-empty yes than it doesn't make sence to check it */ - if (!opt->eo_value) - return NULL; - - const gchar *s = NULL; - if (!g_utf8_validate(opt->eo_value, -1, &s)) - return xasprintf(_("Invalid utf8 character '%c'"), *s); - - switch (opt->eo_type) { - case OPTION_TYPE_TEXT: - case OPTION_TYPE_PASSWORD: - break; - case OPTION_TYPE_NUMBER: - { - char *endptr; - errno = 0; - long r = strtol(opt->eo_value, &endptr, 10); - (void) r; - if (errno != 0 || endptr == opt->eo_value || *endptr != '\0') - return xasprintf(_("Invalid number '%s'"), opt->eo_value); - - break; - } - case OPTION_TYPE_BOOL: - if (strcmp(opt->eo_value, "yes") != 0 - && strcmp(opt->eo_value, "no") != 0 - && strcmp(opt->eo_value, "on") != 0 - && strcmp(opt->eo_value, "off") != 0 - && strcmp(opt->eo_value, "1") != 0 - && strcmp(opt->eo_value, "0") != 0) - { - return xasprintf(_("Invalid boolean value '%s'"), opt->eo_value); - } - break; - case OPTION_TYPE_HINT_HTML: - return NULL; - default: - return xstrdup(_("Unsupported option type")); - }; - - return NULL; -} - -GHashTable *validate_event(const char *event_name) -{ - event_config_t *config = get_event_config(event_name); - if (!config) - return NULL; - - GHashTable *errors = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); - GList *li; - - for (li = config->options; li; li = li->next) - { - event_option_t *opt = (event_option_t *)li->data; - char *err = validate_event_option(opt); - if (err) - g_hash_table_insert(errors, xstrdup(opt->eo_name), err); - } - - if (g_hash_table_size(errors)) - return errors; - - g_hash_table_destroy(errors); - - return NULL; -} diff --git a/src/lib/event_xml_parser.c b/src/lib/event_xml_parser.c deleted file mode 100644 index b2037cd9..00000000 --- a/src/lib/event_xml_parser.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - Copyright (C) 2011 ABRT Team - Copyright (C) 2011 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 "abrtlib.h" -#include "event_config.h" - -#define EVENT_ELEMENT "event" -#define LABEL_ELEMENT "label" -#define DESCRIPTION_ELEMENT "description" -#define LONG_DESCR_ELEMENT "long-description" -#define ALLOW_EMPTY_ELEMENT "allow-empty" -#define NOTE_HTML_ELEMENT "note-html" -#define CREATES_ELEMENT "creates-items" -#define OPTION_ELEMENT "option" -//#define ACTION_ELEMENT "action" -#define NAME_ELEMENT "name" -#define DEFAULT_VALUE_ELEMENT "default-value" - -#define REQUIRES_ELEMENT "requires-items" -#define EXCL_BY_DEFAULT_ELEMENT "exclude-items-by-default" -#define INCL_BY_DEFAULT_ELEMENT "include-items-by-default" -#define EXCL_ALWAYS_ELEMENT "exclude-items-always" -#define EXCL_BINARY_ELEMENT "exclude-binary-items" - - -struct my_parse_data -{ - event_config_t *event_config; - event_option_t *cur_option; - const char *cur_locale; - char *attribute_lang; -}; - -static const char *const option_types[] = -{ - [OPTION_TYPE_TEXT ] = "text", - [OPTION_TYPE_BOOL ] = "bool", - [OPTION_TYPE_PASSWORD ] = "password", - [OPTION_TYPE_NUMBER ] = "number", - [OPTION_TYPE_HINT_HTML] = "hint-html", - [OPTION_TYPE_INVALID ] = NULL -}; - -// Return xml:lang value for <foo xml:lang="value"> if value matches current locale, -// "" if foo has no xml:lang attribute at all, -// else (if xml:lang is for some other locale) return NULL -// -static char *get_element_lang(struct my_parse_data *parse_data, const gchar **att_names, const gchar **att_values) -{ - char *short_locale_end = strchr(parse_data->cur_locale, '_'); - VERB3 log("locale: %s", parse_data->cur_locale); - int i; - for (i = 0; att_names[i] != NULL; ++i) - { - VERB3 log("attr: %s:%s", att_names[i], att_values[i]); - if (strcmp(att_names[i], "xml:lang") == 0) - { - if (strcmp(att_values[i], parse_data->cur_locale) == 0) - { - VERB3 log("found translation for: %s", parse_data->cur_locale); - return xstrdup(att_values[i]); - } - - /* try to match shorter locale - * e.g: "cs" with cs_CZ - */ - if (short_locale_end - && strncmp(att_values[i], parse_data->cur_locale, short_locale_end - parse_data->cur_locale) == 0 - ) { - VERB3 log("found translation for shortlocale: %s", parse_data->cur_locale); - return xstrndup(att_values[i], short_locale_end - parse_data->cur_locale); - } - } - } - /* if the element has no attribute then it's a default non-localized value */ - if (i == 0) - return xstrdup(""); - /* if the element is in different language than the current locale */ - return NULL; -} - -static int cmp_event_option_name_with_string(gconstpointer a, gconstpointer b) -{ - const event_option_t *evopt = a; - /* "When it is not a match?" */ - return !evopt->eo_name || strcmp(evopt->eo_name, (char *)b) != 0; -} - -static void consume_cur_option(struct my_parse_data *parse_data) -{ - event_option_t *opt = parse_data->cur_option; - if (!opt) - return; - parse_data->cur_option = NULL; - - event_config_t *event_config = parse_data->event_config; - - /* Example of "nameless" option: <option type="hint-html"> - * The remaining code does not like "nameless" options - * (strcmp would segfault, etc), so provide invented name: - */ - if (!opt->eo_name) - opt->eo_name = xasprintf("%u", (unsigned)g_list_length(event_config->options)); - - GList *elem = g_list_find_custom(event_config->options, opt->eo_name, cmp_event_option_name_with_string); - if (elem) - { - /* we already have option with such name */ - event_option_t *old_opt = elem->data; - if (old_opt->eo_value) - { - /* ...and it already has a value, which - * overrides xml-defined default one: - */ - free(opt->eo_value); - opt->eo_value = old_opt->eo_value; - old_opt->eo_value = NULL; - } - //log("xml: replacing '%s' value:'%s'->'%s'", opt->eo_name, old_opt->eo_value, opt->eo_value); - free_event_option(old_opt); - elem->data = opt; - } - else - { - //log("xml: new value %s='%s'", opt->eo_name, opt->eo_value); - event_config->options = g_list_append(event_config->options, opt); - } -} - -// Called for opening tags <foo bar="baz"> -static void start_element(GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - //log("start: %s", element_name); - - struct my_parse_data *parse_data = user_data; - - if (strcmp(element_name, OPTION_ELEMENT) == 0) - { - if (parse_data->cur_option) - { - error_msg("error, option nested in option"); - return; - } - - event_option_t *opt = parse_data->cur_option = new_event_option(); - int i; - - for (i = 0; attribute_names[i] != NULL; ++i) - { - VERB2 log("attr: %s:%s", attribute_names[i], attribute_values[i]); - if (strcmp(attribute_names[i], "name") == 0) - { - free(opt->eo_name); - opt->eo_name = xstrdup(attribute_values[i]); - } - else if (strcmp(attribute_names[i], "type") == 0) - { - option_type_t type; - for (type = OPTION_TYPE_TEXT; type < OPTION_TYPE_INVALID; ++type) - { - if (strcmp(option_types[type], attribute_values[i]) == 0) - opt->eo_type = type; - } - } - } - } - else - if (strcmp(element_name, LABEL_ELEMENT) == 0 - || strcmp(element_name, DESCRIPTION_ELEMENT) == 0 - || strcmp(element_name, LONG_DESCR_ELEMENT) == 0 - || strcmp(element_name, NAME_ELEMENT) == 0 - || strcmp(element_name, NOTE_HTML_ELEMENT) == 0 - ) { - free(parse_data->attribute_lang); - parse_data->attribute_lang = get_element_lang(parse_data, attribute_names, attribute_values); - } -} - -// Called for close tags </foo> -static void end_element(GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - struct my_parse_data *parse_data = user_data; - - free(parse_data->attribute_lang); - parse_data->attribute_lang = NULL; - - if (strcmp(element_name, OPTION_ELEMENT) == 0) - { - consume_cur_option(parse_data); - } - if (strcmp(element_name, EVENT_ELEMENT) == 0) - { - consume_cur_option(parse_data); - } -} - -// Called for character data -// text is not nul-terminated -static void text(GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error) -{ - struct my_parse_data *parse_data = user_data; - event_config_t *ui = parse_data->event_config; - - const gchar *inner_element = g_markup_parse_context_get_element(context); - char *text_copy = xstrndup(text, text_len); - event_option_t *opt = parse_data->cur_option; - if (opt) - { - if (strcmp(inner_element, LABEL_ELEMENT) == 0) - { - if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ - { - /* set the value only if we found a value for the current locale - * OR the label is still not set and we found the default value - */ - if (parse_data->attribute_lang[0] != '\0' - || !opt->eo_label /* && parse_data->attribute_lang is "" - always true */ - ) { - VERB2 log("new label:'%s'", text_copy); - free(opt->eo_label); - opt->eo_label = text_copy; - } - } - return; - } - /* - * we can add a separate field for the default value - * in that case we can implement features like "reset to default value" - * but for now using "value" should be enough and clients doesn't - * have to know about the "defaul-value" - */ - if (strcmp(inner_element, DEFAULT_VALUE_ELEMENT) == 0) - { - VERB2 log("default value:'%s'", text_copy); - free(opt->eo_value); - opt->eo_value = text_copy; - return; - } - - if (strcmp(inner_element, NOTE_HTML_ELEMENT) == 0) - { - if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ - { - /* set the value only if we found a value for the current locale - * OR the label is still not set and we found the default value - */ - if (parse_data->attribute_lang[0] != '\0' - || !opt->eo_note_html /* && parse_data->attribute_lang is "" - always true */ - ) { - VERB2 log("html note:'%s'", text_copy); - free(opt->eo_note_html); - opt->eo_note_html = text_copy; - } - } - return; - } - - if (strcmp(inner_element, ALLOW_EMPTY_ELEMENT) == 0) - { - VERB2 log("allow-empty:'%s'", text_copy); - opt->eo_allow_empty = string_to_bool(text_copy); - return; - } - /* - if (strcmp(inner_element, DESCRIPTION_ELEMENT) == 0) - { - VERB2 log("tooltip:'%s'", text_copy); - free(opt->eo_description); - opt->eo_description = text_copy; - return; - } - */ - } - else - { - /* we're not in option, so the description is for the event */ - /* - if (strcmp(inner_element, ACTION_ELEMENT) == 0) - { - VERB2 log("action description:'%s'", text_copy); - free(ui->action); - ui->action = text_copy; - return; - } - */ - if (strcmp(inner_element, CREATES_ELEMENT) == 0) - { - VERB2 log("ec_creates_items:'%s'", text_copy); - free(ui->ec_creates_items); - ui->ec_creates_items = text_copy; - return; - } - if (strcmp(inner_element, NAME_ELEMENT) == 0) - { - if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ - { - /* set the value only if we found a value for the current locale - * OR the label is still not set and we found the default value - */ - if (parse_data->attribute_lang[0] != '\0' - || !ui->screen_name /* && parse_data->attribute_lang is "" - always true */ - ) { - VERB2 log("event name:'%s'", text_copy); - free(ui->screen_name); - ui->screen_name = text_copy; - } - } - return; - } - if (strcmp(inner_element, DESCRIPTION_ELEMENT) == 0) - { - VERB3 log("event description:'%s'", text_copy); - - if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ - { - /* set the value only if we found a value for the current locale - * OR the description is still not set and we found the default value - */ - if (parse_data->attribute_lang[0] != '\0' - || !ui->description /* && parse_data->attribute_lang is "" - always true */ - ) { - free(ui->description); - ui->description = text_copy; - } - } - return; - } - if (strcmp(inner_element, LONG_DESCR_ELEMENT) == 0) - { - VERB3 log("event long description:'%s'", text_copy); - - if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ - { - /* set the value only if we found a value for the current locale - * OR the description is still not set and we found the default value - */ - if (parse_data->attribute_lang[0] != '\0' - || !ui->long_descr /* && parse_data->attribute_lang is "" - always true */ - ) { - free(ui->long_descr); - ui->long_descr = text_copy; - } - } - return; - } - if (strcmp(inner_element, REQUIRES_ELEMENT) == 0) - { - free(ui->ec_requires_items); - ui->ec_requires_items = text_copy; - return; - } - if (strcmp(inner_element, EXCL_BY_DEFAULT_ELEMENT) == 0) - { - free(ui->ec_exclude_items_by_default); - ui->ec_exclude_items_by_default = text_copy; - return; - } - if (strcmp(inner_element, INCL_BY_DEFAULT_ELEMENT) == 0) - { - free(ui->ec_include_items_by_default); - ui->ec_include_items_by_default = text_copy; - return; - } - if (strcmp(inner_element, EXCL_ALWAYS_ELEMENT) == 0) - { - free(ui->ec_exclude_items_always); - ui->ec_exclude_items_always = text_copy; - return; - } - if (strcmp(inner_element, EXCL_BINARY_ELEMENT) == 0) - { - ui->ec_exclude_binary_items = string_to_bool(text_copy); - free(text_copy); - return; - } - } - free(text_copy); -} - - // Called for strings that should be re-saved verbatim in this same - // position, but are not otherwise interpretable. At the moment - // this includes comments and processing instructions. - // text is not nul-terminated -static void passthrough(GMarkupParseContext *context, - const gchar *passthrough_text, - gsize text_len, - gpointer user_data, - GError **error) -{ - VERB3 log("passthrough"); -} - -// Called on error, including one set by other -// methods in the vtable. The GError should not be freed. -static void error(GMarkupParseContext *context, - GError *error, - gpointer user_data) -{ - error_msg("error in XML parsing"); -} - -/* this function takes 2 parameters - * ui -> pointer to event_config_t - * filename -> filename to read - * event_config_t contains list of options, which is malloced by hits function - * and must be freed by the caller - */ - -void load_event_description_from_file(event_config_t *event_config, const char* filename) -{ - struct my_parse_data parse_data = { event_config, NULL, NULL , NULL }; - parse_data.cur_locale = setlocale(LC_ALL, NULL); - - GMarkupParser parser; - memset(&parser, 0, sizeof(parser)); /* just in case */ - parser.start_element = &start_element; - parser.end_element = &end_element; - parser.text = &text; - parser.passthrough = &passthrough; - parser.error = &error; - - GMarkupParseContext *context = g_markup_parse_context_new( - &parser, G_MARKUP_TREAT_CDATA_AS_TEXT, - &parse_data, /*GDestroyNotify:*/ NULL); - - FILE* fin = fopen(filename, "r"); - if (fin != NULL) - { - size_t read_bytes = 0; - char buff[1024]; - while ((read_bytes = fread(buff, 1, 1024, fin)) != 0) - { - g_markup_parse_context_parse(context, buff, read_bytes, NULL); - } - fclose(fin); - } - - g_markup_parse_context_free(context); - - consume_cur_option(&parse_data); /* just in case */ - free(parse_data.attribute_lang); /* just in case */ -} diff --git a/src/lib/get_cmdline.c b/src/lib/get_cmdline.c deleted file mode 100644 index 4bf58e8d..00000000 --- a/src/lib/get_cmdline.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - Copyright (C) 2009 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 "abrtlib.h" - -/* If s is a string with only printable ASCII chars - * and has no spaces, ", ', and \, copy it verbatim. - * Else, encapsulate it in single quotes, and - * encode ', " and \ with \c escapes. - * Control chars are encoded as \r, \n, \t, or \xNN. - * In all cases, terminating NUL is added - * and the pointer to it is returned. - */ -static char *append_escaped(char *start, const char *s) -{ - char *dst = start; - const unsigned char *p = (unsigned char *)s; - - while (1) - { - const unsigned char *old_p = p; - while (*p > ' ' && *p <= 0x7e && *p != '\"' && *p != '\'' && *p != '\\') - p++; - if (dst == start) - { - if (p != (unsigned char *)s && *p == '\0') - { - /* entire word does not need escaping and quoting */ - strcpy(dst, s); - dst += strlen(s); - return dst; - } - *dst++ = '\''; - } - - strncpy(dst, (char *)old_p, (p - old_p)); - dst += (p - old_p); - - if (*p == '\0') - { - *dst++ = '\''; - *dst = '\0'; - return dst; - } - - char hex_char_buf[5]; - const char *a; - switch (*p) - { - case '\r': a = "\\r"; break; - case '\n': a = "\\n"; break; - case '\t': a = "\\t"; break; - case '\'': a = "\\\'"; break; - case '\"': a = "\\\""; break; - case '\\': a = "\\\\"; break; - case ' ': a = " "; break; - default: - /* Build \xNN string */ - hex_char_buf[0] = '\\'; - hex_char_buf[1] = 'x'; - hex_char_buf[2] = "0123456789abcdef"[*p >> 4]; - hex_char_buf[3] = "0123456789abcdef"[*p & 0xf]; - hex_char_buf[4] = '\0'; - a = hex_char_buf; - } - strcpy(dst, a); - dst += strlen(a); - p++; - } -} - -static char* get_escaped(const char *path, char separator) -{ - char *escaped = NULL; - - int fd = open(path, O_RDONLY); - if (fd >= 0) - { - char *dst = NULL; - unsigned total_esc_len = 0; - while (total_esc_len < 1024 * 1024) /* paranoia check */ - { - /* read and escape one block */ - char buffer[4 * 1024 + 1]; - int len = read(fd, buffer, sizeof(buffer) - 1); - if (len <= 0) - break; - buffer[len] = '\0'; - - /* string CC can expand into '\xNN\xNN' and thus needs len*4 + 3 bytes, - * including terminating NUL. - * We add +1 for possible \n added at the very end. - */ - escaped = xrealloc(escaped, total_esc_len + len*4 + 4); - char *src = buffer; - dst = escaped + total_esc_len; - while (1) - { - /* escape till next NUL char */ - char *d = append_escaped(dst, src); - total_esc_len += (d - dst); - dst = d; - src += strlen(src) + 1; - if ((src - buffer) >= len) - break; - *dst++ = separator; - } - - } - - if (dst) - { - if (separator == '\n') - *dst++ = separator; - *dst = '\0'; - } - - close(fd); - } - - return escaped; -} - -char* get_cmdline(pid_t pid) -{ - char path[sizeof("/proc/%lu/cmdline") + sizeof(long)*3]; - sprintf(path, "/proc/%lu/cmdline", (long)pid); - return get_escaped(path, ' '); -} - -char* get_environ(pid_t pid) -{ - char path[sizeof("/proc/%lu/environ") + sizeof(long)*3]; - sprintf(path, "/proc/%lu/environ", (long)pid); - return get_escaped(path, '\n'); -} diff --git a/src/lib/glib_support.c b/src/lib/glib_support.c deleted file mode 100644 index fc4d364e..00000000 --- a/src/lib/glib_support.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2011 ABRT team - Copyright (C) 2011 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 "abrtlib.h" - -void list_free_with_free(GList *list) -{ - GList *li; - for (li = list; li; li = g_list_next(li)) - free(li->data); - g_list_free(list); -} diff --git a/src/lib/hash_sha1.c b/src/lib/hash_sha1.c deleted file mode 100644 index f1a9e0a6..00000000 --- a/src/lib/hash_sha1.c +++ /dev/null @@ -1,211 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Based on shasum from http://www.netsw.org/crypto/hash/ - * Majorly hacked up to use Dr Brian Gladman's sha1 code - * - * Copyright (C) 2002 Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. - * Copyright (C) 2003 Glenn L. McGrath - * Copyright (C) 2003 Erik Andersen - * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. - * - * --------------------------------------------------------------------------- - * Issue Date: 10/11/2002 - * - * This is a byte oriented version of SHA1 that operates on arrays of bytes - * stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor - * - * --------------------------------------------------------------------------- - */ -#include "abrtlib.h" -#include <byteswap.h> - -#if defined(__BIG_ENDIAN__) && __BIG_ENDIAN__ -# define SHA1_BIG_ENDIAN 1 -# define SHA1_LITTLE_ENDIAN 0 -#elif __BYTE_ORDER == __BIG_ENDIAN -# define SHA1_BIG_ENDIAN 1 -# define SHA1_LITTLE_ENDIAN 0 -#elif __BYTE_ORDER == __LITTLE_ENDIAN -# define SHA1_BIG_ENDIAN 0 -# define SHA1_LITTLE_ENDIAN 1 -#else -# error "Can't determine endianness" -#endif - -#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n)))) -/* for sha256: */ -#define rotr32(x,n) (((x) >> (n)) | ((x) << (32 - (n)))) -/* for sha512: */ -#define rotr64(x,n) (((x) >> (n)) | ((x) << (64 - (n)))) - - -/* Generic 64-byte helpers for 64-byte block hashes */ -static void common64_hash(sha1_ctx_t *ctx, const void *buffer, size_t len); -static void common64_end(sha1_ctx_t *ctx, int swap_needed); - - -/* sha1 specific code */ - -static void sha1_process_block64(sha1_ctx_t *ctx) -{ - static const uint32_t rconsts[] = { - 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 - }; - int i, j; - int cnt; - uint32_t W[16+16]; - uint32_t a, b, c, d, e; - - /* On-stack work buffer frees up one register in the main loop - * which otherwise will be needed to hold ctx pointer */ - for (i = 0; i < 16; i++) - if (SHA1_BIG_ENDIAN) - W[i] = W[i+16] = ((uint32_t*)ctx->wbuffer)[i]; - else - W[i] = W[i+16] = bswap_32(((uint32_t*)ctx->wbuffer)[i]); - - a = ctx->hash[0]; - b = ctx->hash[1]; - c = ctx->hash[2]; - d = ctx->hash[3]; - e = ctx->hash[4]; - - /* 4 rounds of 20 operations each */ - cnt = 0; - for (i = 0; i < 4; i++) { - j = 19; - do { - uint32_t work; - - work = c ^ d; - if (i == 0) { - work = (work & b) ^ d; - if (j <= 3) - goto ge16; - /* Used to do bswap_32 here, but this - * requires ctx (see comment above) */ - work += W[cnt]; - } else { - if (i == 2) - work = ((b | c) & d) | (b & c); - else /* i = 1 or 3 */ - work ^= b; - ge16: - W[cnt] = W[cnt+16] = rotl32(W[cnt+13] ^ W[cnt+8] ^ W[cnt+2] ^ W[cnt], 1); - work += W[cnt]; - } - work += e + rotl32(a, 5) + rconsts[i]; - - /* Rotate by one for next time */ - e = d; - d = c; - c = /* b = */ rotl32(b, 30); - b = a; - a = work; - cnt = (cnt + 1) & 15; - } while (--j >= 0); - } - - ctx->hash[0] += a; - ctx->hash[1] += b; - ctx->hash[2] += c; - ctx->hash[3] += d; - ctx->hash[4] += e; -} - -void sha1_begin(sha1_ctx_t *ctx) -{ - ctx->hash[0] = 0x67452301; - ctx->hash[1] = 0xefcdab89; - ctx->hash[2] = 0x98badcfe; - ctx->hash[3] = 0x10325476; - ctx->hash[4] = 0xc3d2e1f0; - ctx->total64 = 0; - /* for sha256: ctx->process_block = sha1_process_block64; */ -} - -void sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len) -{ - common64_hash(ctx, buffer, len); -} - -/* May be used also for sha256 */ -void sha1_end(sha1_ctx_t *ctx, void *resbuf) -{ - unsigned hash_size; - - /* SHA stores total in BE, need to swap on LE arches: */ - common64_end(ctx, /*swap_needed:*/ SHA1_LITTLE_ENDIAN); - - hash_size = 5; /* (ctx->process_block == sha1_process_block64) ? 5 : 8; */ - /* This way we do not impose alignment constraints on resbuf: */ - if (SHA1_LITTLE_ENDIAN) { - unsigned i; - for (i = 0; i < hash_size; ++i) - ctx->hash[i] = bswap_32(ctx->hash[i]); - } - memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * hash_size); -} - - -/* Generic 64-byte helpers for 64-byte block hashes */ - -/*#define PROCESS_BLOCK(ctx) ctx->process_block(ctx)*/ -#define PROCESS_BLOCK(ctx) sha1_process_block64(ctx) - -/* Feed data through a temporary buffer. - * The internal buffer remembers previous data until it has 64 - * bytes worth to pass on. - */ -static void common64_hash(sha1_ctx_t *ctx, const void *buffer, size_t len) -{ - unsigned bufpos = ctx->total64 & 63; - - ctx->total64 += len; - - while (1) { - unsigned remaining = 64 - bufpos; - if (remaining > len) - remaining = len; - /* Copy data into aligned buffer */ - memcpy(ctx->wbuffer + bufpos, buffer, remaining); - len -= remaining; - buffer = (const char *)buffer + remaining; - bufpos += remaining; - /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ - bufpos -= 64; - if (bufpos != 0) - break; - /* Buffer is filled up, process it */ - PROCESS_BLOCK(ctx); - /*bufpos = 0; - already is */ - } -} - -/* Process the remaining bytes in the buffer */ -static void common64_end(sha1_ctx_t *ctx, int swap_needed) -{ - unsigned bufpos = ctx->total64 & 63; - /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ - ctx->wbuffer[bufpos++] = 0x80; - - /* This loop iterates either once or twice, no more, no less */ - while (1) { - unsigned remaining = 64 - bufpos; - memset(ctx->wbuffer + bufpos, 0, remaining); - /* Do we have enough space for the length count? */ - if (remaining >= 8) { - /* Store the 64-bit counter of bits in the buffer */ - uint64_t t = ctx->total64 << 3; - if (swap_needed) - t = bswap_64(t); - /* wbuffer is suitably aligned for this */ - *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; - } - PROCESS_BLOCK(ctx); - if (remaining >= 8) - break; - bufpos = 0; - } -} diff --git a/src/lib/hash_sha1.h b/src/lib/hash_sha1.h deleted file mode 100644 index 850fd21f..00000000 --- a/src/lib/hash_sha1.h +++ /dev/null @@ -1,47 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Based on shasum from http://www.netsw.org/crypto/hash/ - * Majorly hacked up to use Dr Brian Gladman's sha1 code - * - * Copyright (C) 2002 Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. - * Copyright (C) 2003 Glenn L. McGrath - * Copyright (C) 2003 Erik Andersen - * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. - * - * --------------------------------------------------------------------------- - * Issue Date: 10/11/2002 - * - * This is a byte oriented version of SHA1 that operates on arrays of bytes - * stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor - * - * --------------------------------------------------------------------------- - */ -#ifndef HASH_SHA1_H -#define HASH_SHA1_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#define SHA1_RESULT_LEN (5 * 4) - -typedef struct sha1_ctx_t { - uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ - /* for sha256: void (*process_block)(struct md5_ctx_t*); */ - uint64_t total64; /* must be directly before hash[] */ - uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */ -} sha1_ctx_t; - -#define sha1_begin abrt_sha1_begin -void sha1_begin(sha1_ctx_t *ctx); -#define sha1_hash abrt_sha1_hash -void sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len); -#define sha1_end abrt_sha1_end -void sha1_end(sha1_ctx_t *ctx, void *resbuf); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/lib/hooklib.c b/src/lib/hooklib.c index 804a2394..365d5953 100644 --- a/src/lib/hooklib.c +++ b/src/lib/hooklib.c @@ -15,7 +15,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "abrtlib.h" +#include "libreport.h" #include "hooklib.h" #include <sys/statvfs.h> diff --git a/src/lib/is_in_string_list.c b/src/lib/is_in_string_list.c deleted file mode 100644 index 2eda61dd..00000000 --- a/src/lib/is_in_string_list.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (C) 2011 ABRT team - Copyright (C) 2011 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 "abrtlib.h" - -bool is_in_string_list(const char *name, char **v) -{ - while (*v) - { - if (strcmp(*v, name) == 0) - return true; - v++; - } - return false; -} diff --git a/src/lib/iso_date_string.c b/src/lib/iso_date_string.c deleted file mode 100644 index 4600ff7f..00000000 --- a/src/lib/iso_date_string.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2011 ABRT team - Copyright (C) 2011 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 "abrtlib.h" - -char *iso_date_string(time_t *pt) -{ - static char buf[sizeof("YYYY-MM-DD-HH:MM:SS") + 4]; - - time_t t; - struct tm *ptm = localtime(pt ? pt : (time(&t), &t)); - strftime(buf, sizeof(buf), "%Y-%m-%d-%H:%M:%S", ptm); - - return buf; -} diff --git a/src/lib/kernel-tainted.c b/src/lib/kernel-tainted.c deleted file mode 100644 index 115e44e0..00000000 --- a/src/lib/kernel-tainted.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - Copyright (C) 2011 ABRT team - Copyright (C) 2011 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 "abrtlib.h" - -/* From RHEL6 kernel/panic.c: */ -static const int tnts_short[] = { - 'P' , - 'F' , - 'S' , - 'R' , - 'M' , - 'B' , - 'U' , - 'D' , - 'A' , - 'W' , - 'C' , - 'I' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - '-' , - 'H' , - 'T' , -}; - -/** - * print_tainted - return a string to represent the kernel taint state. - * - * 'P' - Proprietary module has been loaded. - * 'F' - Module has been forcibly loaded. - * 'S' - SMP with CPUs not designed for SMP. - * 'R' - User forced a module unload. - * 'M' - System experienced a machine check exception. - * 'B' - System has hit bad_page. - * 'U' - Userspace-defined naughtiness. - * 'D' - Kernel has oopsed before - * 'A' - ACPI table overridden. - * 'W' - Taint on warning. - * 'C' - modules from drivers/staging are loaded. - * 'I' - Working around severe firmware bug. - * 'H' - Hardware is unsupported. - * T - Tech_preview - */ - - -static const char *const tnts_long[] = { - "Proprietary module has been loaded.", - "Module has been forcibly loaded.", - "SMP with CPUs not designed for SMP.", - "User forced a module unload.", - "System experienced a machine check exception.", - "System has hit bad_page.", - "Userspace-defined naughtiness.", - "Kernel has oopsed before.", - "ACPI table overridden.", - "Taint on warning.", - "Modules from drivers/staging are loaded.", - "Working around severe firmware bug.", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Hardware is unsupported.", - "Tech_preview", -}; - -char *kernel_tainted_short(unsigned tainted) -{ - char *tnt = xzalloc(ARRAY_SIZE(tnts_short) + 1); - int i = 0; - while (tainted) - { - if (0x1 & tainted) - tnt[i] = tnts_short[i]; - else - tnt[i] = '-'; - - ++i; - tainted >>= 1; - } - - return tnt; -} - -GList *kernel_tainted_long(unsigned tainted) -{ - int i = 0; - GList *tnt = NULL; - - while (tainted) - { - if (0x1 & tainted && tnts_long[i]) - tnt = g_list_append(tnt, xstrdup(tnts_long[i])); - - ++i; - tainted >>= 1; - } - - return tnt; -} diff --git a/src/lib/load_plugin_settings.c b/src/lib/load_plugin_settings.c deleted file mode 100644 index 3e4ebf9c..00000000 --- a/src/lib/load_plugin_settings.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) - Copyright (C) 2009 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 "abrtlib.h" - -/* Returns false if open failed. - * Returns empty hash if conf file is empty. - * TODO: better error detection? - */ -bool load_conf_file(const char *pPath, map_string_h *settings, bool skipKeysWithoutValue) -{ - FILE *fp = stdin; - if (strcmp(pPath, "-") != 0) - { - fp = fopen(pPath, "r"); - if (!fp) - return false; - } - - char *line; - while ((line = xmalloc_fgetline(fp)) != NULL) - { - bool in_quote = false; - /* We are reusing line buffer to form temporary - * "key\0value\0..." in its beginning - */ - char *value = NULL; - char *src; - char *dst; - for (src = dst = line; *src; src++) - { - char c = *src; - if (c == '"') - { - in_quote = !in_quote; - } - if (!in_quote) - { - if (isspace(c)) - { - continue; - } - if (c == '#' && dst == line) - { - break; - } - if (c == '=') - { - *dst++ = '\0'; /* terminate key */ - value = dst; /* remember where value starts */ - continue; - } - } - *dst++ = c; /* store next key or value char */ - } - *dst = '\0'; /* terminate value */ - - /* Skip broken or empty lines. */ - if (!value) - goto free_line; - - /* Skip lines with empty key. */ - if (line[0] == '\0') - goto free_line; - - if (skipKeysWithoutValue && value[0] == '\0') - goto free_line; - - /* Skip lines with unclosed quotes. */ - if (in_quote) - goto free_line; - - g_hash_table_replace(settings, xstrdup(line), xstrdup(value)); - free_line: - free(line); - } - - if (fp != stdin) - fclose(fp); - - return true; -} diff --git a/src/lib/logging.c b/src/lib/logging.c deleted file mode 100644 index 815efb5e..00000000 --- a/src/lib/logging.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2010 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. -*/ - -/* - * Utility routines. - * - */ -#include "abrtlib.h" - -void (*g_custom_logger)(const char*); -const char *msg_prefix = ""; -const char *msg_eol = "\n"; -int logmode = LOGMODE_STDIO; -int xfunc_error_retval = EXIT_FAILURE; -int g_verbose; - -void xfunc_die(void) -{ - exit(xfunc_error_retval); -} - -static void verror_msg_helper(const char *s, - va_list p, - const char* strerr, - int flags) -{ - char *msg; - int prefix_len, strerr_len, msgeol_len, used; - - if (!logmode) - return; - - used = vasprintf(&msg, s, p); - if (used < 0) - return; - - /* This is ugly and costs +60 bytes compared to multiple - * fprintf's, but is guaranteed to do a single write. - * This is needed for e.g. when multiple children - * can produce log messages simultaneously. */ - - prefix_len = msg_prefix[0] ? strlen(msg_prefix) + 2 : 0; - strerr_len = strerr ? strlen(strerr) : 0; - msgeol_len = strlen(msg_eol); - /* +3 is for ": " before strerr and for terminating NUL */ - msg = (char*) xrealloc(msg, prefix_len + used + strerr_len + msgeol_len + 3); - /* TODO: maybe use writev instead of memmoving? Need full_writev? */ - if (prefix_len) { - char *p; - memmove(msg + prefix_len, msg, used); - used += prefix_len; - p = stpcpy(msg, msg_prefix); - p[0] = ':'; - p[1] = ' '; - } - if (strerr) { - if (s[0]) { - msg[used++] = ':'; - msg[used++] = ' '; - } - strcpy(&msg[used], strerr); - used += strerr_len; - } - strcpy(&msg[used], msg_eol); - - if (flags & LOGMODE_STDIO) { - fflush(stdout); - full_write(STDERR_FILENO, msg, used + msgeol_len); - } - msg[used] = '\0'; /* remove msg_eol (usually "\n") */ - if (flags & LOGMODE_SYSLOG) { - syslog(LOG_ERR, "%s", msg + prefix_len); - } - if ((flags & LOGMODE_CUSTOM) && g_custom_logger) { - g_custom_logger(msg + prefix_len); - } - free(msg); -} - -void log_msg(const char *s, ...) -{ - va_list p; - - va_start(p, s); - verror_msg_helper(s, p, NULL, logmode); - va_end(p); -} - -void error_msg(const char *s, ...) -{ - va_list p; - - va_start(p, s); - verror_msg_helper(s, p, NULL, (logmode | LOGMODE_CUSTOM)); - va_end(p); -} - -void error_msg_and_die(const char *s, ...) -{ - va_list p; - - va_start(p, s); - verror_msg_helper(s, p, NULL, (logmode | LOGMODE_CUSTOM)); - va_end(p); - xfunc_die(); -} - -void perror_msg(const char *s, ...) -{ - va_list p; - - va_start(p, s); - /* Guard against "<error message>: Success" */ - verror_msg_helper(s, p, errno ? strerror(errno) : NULL, (logmode | LOGMODE_CUSTOM)); - va_end(p); -} - -void perror_msg_and_die(const char *s, ...) -{ - va_list p; - - va_start(p, s); - /* Guard against "<error message>: Success" */ - verror_msg_helper(s, p, errno ? strerror(errno) : NULL, (logmode | LOGMODE_CUSTOM)); - va_end(p); - xfunc_die(); -} - -void die_out_of_memory(void) -{ - error_msg_and_die("Out of memory, exiting"); -} diff --git a/src/lib/logging.h b/src/lib/logging.h deleted file mode 100644 index 316c1a22..00000000 --- a/src/lib/logging.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 2010 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. -*/ - -#ifndef LOGGING_H -#define LOGGING_H - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <sys/syslog.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define NORETURN __attribute__ ((noreturn)) - -enum { - LOGMODE_NONE = 0, - LOGMODE_STDIO = (1 << 0), - LOGMODE_SYSLOG = (1 << 1), - LOGMODE_BOTH = LOGMODE_SYSLOG + LOGMODE_STDIO, - LOGMODE_CUSTOM = (1 << 2), -}; - -#define g_custom_logger abrt_g_custom_logger -extern void (*g_custom_logger)(const char*); -#define msg_prefix abrt_msg_prefix -extern const char *msg_prefix; -#define msg_eol abrt_msg_eol -extern const char *msg_eol; -#define logmode abrt_logmode -extern int logmode; -#define xfunc_error_retval abrt_xfunc_error_retval -extern int xfunc_error_retval; - -/* Verbosity level */ -#define g_verbose abrt_g_verbose -extern int g_verbose; -/* VERB1 log("what you sometimes want to see, even on a production box") */ -#define VERB1 if (g_verbose >= 1) -/* VERB2 log("debug message, not going into insanely small details") */ -#define VERB2 if (g_verbose >= 2) -/* VERB3 log("lots and lots of details") */ -#define VERB3 if (g_verbose >= 3) -/* there is no level > 3 */ - -#define abrt_ -#define xfunc_die abrt_xfunc_die -void xfunc_die(void) NORETURN; -#define log_msg abrt_log_msg -void log_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))); -/* It's a macro, not function, since it collides with log() from math.h */ -#undef log -#define log(...) log_msg(__VA_ARGS__) -/* error_msg family will use g_custom_logger. log_msg does not. */ -#define error_msg abrt_error_msg -void error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))); -#define error_msg_and_die abrt_error_msg_and_die -void error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); -/* Reports error message with libc's errno error description attached. */ -#define perror_msg abrt_perror_msg -void perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))); -#define perror_msg_and_die abrt_perror_msg_and_die -void perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); -#define die_out_of_memory abrt_die_out_of_memory -void die_out_of_memory(void) NORETURN; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/lib/make_descr.c b/src/lib/make_descr.c deleted file mode 100644 index d0afc8cb..00000000 --- a/src/lib/make_descr.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - Copyright (C) 2010 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 "abrtlib.h" - - -char *make_description(problem_data_t *problem_data, char **names_to_skip, unsigned max_text_size, unsigned desc_flags) -{ - struct strbuf *buf_dsc = strbuf_new(); - - GList *list = g_hash_table_get_keys(problem_data); - list = g_list_sort(list, (GCompareFunc)strcmp); - GList *l; - - /* Print one-liners. Format: - * NAME1: <maybe more spaces>VALUE1 - * NAME2: <maybe more spaces>VALUE2 - */ - bool empty = true; - l = list; - while (l) - { - const char *key = l->data; - l = l->next; - - /* Skip items we are not interested in */ -//TODO: optimize by doing this once, not 3 times: - if (names_to_skip && is_in_string_list(key, names_to_skip)) - continue; - - struct problem_item *item = g_hash_table_lookup(problem_data, key); - if (!item) - continue; - - if ((desc_flags & MAKEDESC_SHOW_ONLY_LIST) && !(item->flags & CD_FLAG_LIST)) - continue; - - if ((item->flags & CD_FLAG_TXT) - && strlen(item->content) <= max_text_size - ) { - char *formatted = format_problem_item(item); - char *output = formatted ? formatted : item->content; - char *eol = strchr(output, '\n'); - if (!eol) - { - int pad = 16 - (strlen(key) + 2); - if (pad < 0) pad = 0; - strbuf_append_strf(buf_dsc, "%s: %*s%s\n", key, pad, "", output); - empty = false; - } - free(formatted); - } - } - - bool append_empty_line = !empty; - if (desc_flags & MAKEDESC_SHOW_FILES) - { - /* Print file info. Format: - * <empty line if needed> - * NAME1: <maybe more spaces>Binary file, NNN bytes - * NAME2: <maybe more spaces>Text file, NNN bytes - * - * In many cases, it is useful to know how big binary files are - * (for example, helps with diagnosing bug upload problems) - */ - l = list; - while (l) - { - const char *key = l->data; - l = l->next; - - /* Skip items we are not interested in */ - if (names_to_skip && is_in_string_list(key, names_to_skip)) - continue; - - struct problem_item *item = g_hash_table_lookup(problem_data, key); - if (!item) - continue; - - if ((desc_flags & MAKEDESC_SHOW_ONLY_LIST) && !(item->flags & CD_FLAG_LIST)) - continue; - - if ((item->flags & CD_FLAG_BIN) - || ((item->flags & CD_FLAG_TXT) && strlen(item->content) > max_text_size) - ) { - if (append_empty_line) - strbuf_append_char(buf_dsc, '\n'); - append_empty_line = false; - - struct stat statbuf; - int stat_err = 0; - if (item->flags & CD_FLAG_BIN) - stat_err = stat(item->content, &statbuf); - else - statbuf.st_size = strlen(item->content); - - /* We don't print item->content for CD_FLAG_BIN, as it is - * always "/path/to/dump/dir/KEY" - not informative. - */ - int pad = 16 - (strlen(key) + 2); - if (pad < 0) pad = 0; - strbuf_append_strf(buf_dsc, - (!stat_err ? "%s: %*s%s file, %llu bytes\n" : "%s: %*s%s file\n"), - key, - pad, "", - ((item->flags & CD_FLAG_BIN) ? "Binary" : "Text"), - (long long)statbuf.st_size - ); - empty = false; - } - } - } - - if (desc_flags & MAKEDESC_SHOW_MULTILINE) - { - /* Print multi-liners. Format: - * <empty line if needed> - * NAME: - * :LINE1 - * :LINE2 - * :LINE3 - */ - l = list; - while (l) - { - const char *key = l->data; - l = l->next; - - /* Skip items we are not interested in */ - if (names_to_skip && is_in_string_list(key, names_to_skip)) - continue; - - struct problem_item *item = g_hash_table_lookup(problem_data, key); - if (!item) - continue; - - if ((desc_flags & MAKEDESC_SHOW_ONLY_LIST) && !(item->flags & CD_FLAG_LIST)) - continue; - - if ((item->flags & CD_FLAG_TXT) - && strlen(item->content) <= max_text_size - ) { - char *formatted = format_problem_item(item); - char *output = formatted ? formatted : item->content; - char *eol = strchr(output, '\n'); - if (eol) - { - if (!empty) - strbuf_append_char(buf_dsc, '\n'); - strbuf_append_str(buf_dsc, key); - strbuf_append_str(buf_dsc, ":\n"); - for (;;) - { - eol = strchrnul(output, '\n'); - strbuf_append_strf(buf_dsc, ":%.*s\n", (int)(eol - output), output); - if (*eol == '\0' || eol[1] == '\0') - break; - output = eol + 1; - } - empty = false; - } - free(formatted); - } - } - } - - g_list_free(list); - - return strbuf_free_nobuf(buf_dsc); -} - -char* make_description_mailx(problem_data_t *problem_data) -{ - struct strbuf *buf_dsc = strbuf_new(); - struct strbuf *buf_additional_files = strbuf_new(); - struct strbuf *buf_duphash_file = strbuf_new(); - struct strbuf *buf_common_files = strbuf_new(); - - GHashTableIter iter; - char *name; - struct problem_item *value; - g_hash_table_iter_init(&iter, problem_data); - while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) - { - if (value->flags & CD_FLAG_TXT) - { - if ((strcmp(name, FILENAME_DUPHASH) != 0) - && (strcmp(name, FILENAME_ARCHITECTURE) != 0) - && (strcmp(name, FILENAME_KERNEL) != 0) - && (strcmp(name, FILENAME_PACKAGE) != 0) - ) { - strbuf_append_strf(buf_additional_files, "%s\n-----\n%s\n\n", name, value->content); - } - else if (strcmp(name, FILENAME_DUPHASH) == 0) - strbuf_append_strf(buf_duphash_file, "%s\n-----\n%s\n\n", name, value->content); - else - strbuf_append_strf(buf_common_files, "%s\n-----\n%s\n\n", name, value->content); - } - } - - char *common_files = strbuf_free_nobuf(buf_common_files); - char *duphash_file = strbuf_free_nobuf(buf_duphash_file); - char *additional_files = strbuf_free_nobuf(buf_additional_files); - - strbuf_append_strf(buf_dsc, "Duplicate check\n=====\n%s\n\n", duphash_file); - strbuf_append_strf(buf_dsc, "Common information\n=====\n%s\n\n", common_files); - strbuf_append_strf(buf_dsc, "Additional information\n=====\n%s\n", additional_files); - - free(common_files); - free(duphash_file); - free(additional_files); - - return strbuf_free_nobuf(buf_dsc); -} - -/* Items we don't want to include to bz / logger */ -static const char *const blacklisted_items[] = { - CD_DUMPDIR , - FILENAME_ANALYZER , - FILENAME_COREDUMP , - FILENAME_HOSTNAME , - FILENAME_DUPHASH , - FILENAME_UUID , - FILENAME_COUNT , - FILENAME_TAINTED_SHORT, - NULL -}; - -char* make_description_bz(problem_data_t *problem_data) -{ - return make_description( - problem_data, - (char**)blacklisted_items, - /*max_text_size:*/ CD_TEXT_ATT_SIZE, - MAKEDESC_SHOW_FILES | MAKEDESC_SHOW_MULTILINE - ); -} - -char* make_description_logger(problem_data_t *problem_data) -{ - return make_description( - problem_data, - (char**)blacklisted_items, - /*max_text_size:*/ CD_TEXT_ATT_SIZE, - MAKEDESC_SHOW_FILES | MAKEDESC_SHOW_MULTILINE - ); -} diff --git a/src/lib/overlapping_strcpy.c b/src/lib/overlapping_strcpy.c deleted file mode 100644 index 41c1c1a1..00000000 --- a/src/lib/overlapping_strcpy.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> - * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. - */ -#include "abrtlib.h" - -/* Like strcpy but can copy overlapping strings. */ -void overlapping_strcpy(char *dst, const char *src) -{ - /* Cheap optimization for dst == src case - - * better to have it here than in many callers. - */ - if (dst != src) - { - while ((*dst = *src) != '\0') - { - dst++; - src++; - } - } -} diff --git a/src/lib/parse_options.c b/src/lib/parse_options.c deleted file mode 100644 index 95c21ce5..00000000 --- a/src/lib/parse_options.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - Copyright (C) 2010 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 <getopt.h> -#include "abrtlib.h" -#include "parse_options.h" - -#define USAGE_OPTS_WIDTH 30 -#define USAGE_GAP 2 - -const char *g_progname; - -const char *abrt_init(char **argv) -{ - char *env_verbose = getenv("ABRT_VERBOSE"); - if (env_verbose) - g_verbose = atoi(env_verbose); - - g_progname = strrchr(argv[0], '/'); - if (g_progname) - g_progname++; - else - g_progname = argv[0]; - - char *pfx = getenv("ABRT_PROG_PREFIX"); - if (pfx && string_to_bool(pfx)) - msg_prefix = g_progname; - - return g_progname; -} - -void export_abrt_envvars(int pfx) -{ - putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose)); - if (pfx) - { - putenv((char*)"ABRT_PROG_PREFIX=1"); - msg_prefix = g_progname; - } -} - -void show_usage_and_die(const char *usage, const struct options *opt) -{ - fputs(_("Usage: "), stderr); - while (*usage) - { - int len = strchrnul(usage, '\b') - usage; - if (len > 0) - { - fprintf(stderr, "%.*s", len, usage); - usage += len; - } - if (*usage == '\b') - { - fputs(g_progname, stderr); - usage++; - } - } - fputs("\n\n", stderr); - - for (; opt->type != OPTION_END; opt++) - { - size_t pos; - int pad; - - if (opt->type == OPTION_GROUP) - { - fputc('\n', stderr); - if (*opt->help) - fprintf(stderr, "%s\n", opt->help); - continue; - } - - pos = fprintf(stderr, " "); - if (opt->short_name) - pos += fprintf(stderr, "-%c", opt->short_name); - - if (opt->short_name && opt->long_name) - pos += fprintf(stderr, ", "); - - if (opt->long_name) - pos += fprintf(stderr, "--%s", opt->long_name); - - if (opt->argh) - { - const char *fmt = " %s"; - if (opt->type == OPTION_OPTSTRING) - fmt = "[%s]"; - pos += fprintf(stderr, fmt, opt->argh); - } - - if (pos <= USAGE_OPTS_WIDTH) - pad = USAGE_OPTS_WIDTH - pos; - else - { - fputc('\n', stderr); - pad = USAGE_OPTS_WIDTH; - } - fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opt->help); - } - fputc('\n', stderr); - exit(1); -} - -static int parse_opt_size(const struct options *opt) -{ - unsigned size = 0; - for (; opt->type != OPTION_END; opt++) - size++; - - return size; -} - -unsigned parse_opts(int argc, char **argv, const struct options *opt, - const char *usage) -{ - int help = 0; - int size = parse_opt_size(opt); - const int LONGOPT_OFFSET = 256; - - struct strbuf *shortopts = strbuf_new(); - - struct option *longopts = xzalloc(sizeof(longopts[0]) * (size+2)); - struct option *curopt = longopts; - int ii; - for (ii = 0; ii < size; ++ii) - { - curopt->name = opt[ii].long_name; - /*curopt->flag = 0; - xzalloc did it */ - if (opt[ii].short_name) - curopt->val = opt[ii].short_name; - else - curopt->val = LONGOPT_OFFSET + ii; - - switch (opt[ii].type) - { - case OPTION_BOOL: - curopt->has_arg = no_argument; - if (opt[ii].short_name) - strbuf_append_char(shortopts, opt[ii].short_name); - break; - case OPTION_INTEGER: - case OPTION_STRING: - case OPTION_LIST: - curopt->has_arg = required_argument; - if (opt[ii].short_name) - strbuf_append_strf(shortopts, "%c:", opt[ii].short_name); - break; - case OPTION_OPTSTRING: - curopt->has_arg = optional_argument; - if (opt[ii].short_name) - strbuf_append_strf(shortopts, "%c::", opt[ii].short_name); - break; - case OPTION_GROUP: - case OPTION_END: - break; - } - //log("curopt[%d].name:'%s' .has_arg:%d .flag:%p .val:%d", (int)(curopt-longopts), - // curopt->name, curopt->has_arg, curopt->flag, curopt->val); - /* - * getopt_long() thinks that NULL name marks the end of longopts. - * Example: - * [0] name:'verbose' val:'v' - * [1] name:NULL val:'c' - * [2] name:'force' val:'f' - * ... ... ... - * In this case, --force won't be accepted! - * Therefore we can only advance if name is not NULL. - */ - if (curopt->name) - curopt++; - } - curopt->name = "help"; - curopt->has_arg = no_argument; - curopt->flag = &help; - curopt->val = 1; - /* xzalloc did it already: - curopt++; - curopt->name = NULL; - curopt->has_arg = 0; - curopt->flag = NULL; - curopt->val = 0; - */ - - unsigned retval = 0; - while (1) - { - int c = getopt_long(argc, argv, shortopts->buf, longopts, NULL); - - if (c == -1) - break; - - if (c == '?' || help) - { - free(longopts); - strbuf_free(shortopts); - show_usage_and_die(usage, opt); - } - - for (ii = 0; ii < size; ++ii) - { - if (opt[ii].short_name == c || LONGOPT_OFFSET + ii == c) - { - if (ii < sizeof(retval)*8) - retval |= (1 << ii); - - if (opt[ii].value != NULL) switch (opt[ii].type) - { - case OPTION_BOOL: - *(int*)(opt[ii].value) += 1; - break; - case OPTION_INTEGER: - *(int*)(opt[ii].value) = xatoi(optarg); - break; - case OPTION_STRING: - case OPTION_OPTSTRING: - if (optarg) - *(char**)(opt[ii].value) = (char*)optarg; - break; - case OPTION_LIST: - *(GList**)(opt[ii].value) = g_list_append(*(GList**)(opt[ii].value), optarg); - break; - case OPTION_GROUP: - case OPTION_END: - break; - } - } - } - } - - free(longopts); - strbuf_free(shortopts); - - return retval; -} diff --git a/src/lib/parse_options.h b/src/lib/parse_options.h deleted file mode 100644 index d86662e2..00000000 --- a/src/lib/parse_options.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 2010 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. -*/ -#ifndef PARSE_OPTIONS_H -#define PARSE_OPTIONS_H - -#ifdef __cplusplus -extern "C" { -#endif - -const char *abrt_init(char **argv); -#define export_abrt_envvars abrt_export_abrt_envvars -void export_abrt_envvars(int pfx); -#define g_progname abrt_g_progname -extern const char *g_progname; - - -enum parse_opt_type { - OPTION_BOOL, - OPTION_GROUP, - OPTION_STRING, - OPTION_INTEGER, - OPTION_OPTSTRING, - OPTION_LIST, - OPTION_END, -}; - -struct options { - enum parse_opt_type type; - int short_name; - const char *long_name; - void *value; - const char *argh; - const char *help; -}; - -/* - * s - short_name - * l - long_name - * v - value - * a - option parameter name (for help text) - * h - help - */ -#define OPT_END() { OPTION_END } -#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) } -#define OPT_BOOL( s, l, v, h) { OPTION_BOOL , (s), (l), (v), NULL , (h) } -#define OPT_INTEGER( s, l, v, h) { OPTION_INTEGER , (s), (l), (v), "NUM", (h) } -#define OPT_STRING( s, l, v, a, h) { OPTION_STRING , (s), (l), (v), (a) , (h) } -#define OPT_OPTSTRING(s, l, v, a, h) { OPTION_OPTSTRING, (s), (l), (v), (a) , (h) } -#define OPT_LIST( s, l, v, a, h) { OPTION_LIST , (s), (l), (v), (a) , (h) } - -#define OPT__VERBOSE(v) OPT_BOOL('v', "verbose", (v), _("Be verbose")) - -#define parse_opts abrt_parse_opts -unsigned parse_opts(int argc, char **argv, const struct options *opt, - const char *usage); - -#define show_usage_and_die abrt_show_usage_and_die -void show_usage_and_die(const char *usage, const struct options *opt); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/lib/parse_release.c b/src/lib/parse_release.c deleted file mode 100644 index b24f928c..00000000 --- a/src/lib/parse_release.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (C) 2010 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 "abrtlib.h" - -// caller is reposible for freeing *product* and *version* -static void parse_release(const char *release, char** product, char** version, bool append_rhel_version) -{ - if (strstr(release, "Rawhide")) - { - *product = xstrdup("Fedora"); - *version = xstrdup("rawhide"); - VERB3 log("%s: version:'%s' product:'%s'", __func__, *version, *product); - return; - } - - struct strbuf *buf_product = strbuf_new(); - if (strstr(release, "Fedora")) - strbuf_append_str(buf_product, "Fedora"); - else if (strstr(release, "Red Hat Enterprise Linux")) - strbuf_append_str(buf_product, "Red Hat Enterprise Linux"); - else - { - /* TODO: add logic for parsing other distros' names here */ - strbuf_append_str(buf_product, release); - } - - const char *r = strstr(release, "release"); - const char *space = r ? strchr(r, ' ') : NULL; - - struct strbuf *buf_version = strbuf_new(); - if (space) - { - space++; - while (*space != '\0' && *space != ' ') - { - /* Eat string like "5.2" */ - strbuf_append_char(buf_version, *space); - if (append_rhel_version - && strcmp(buf_product->buf, "Red Hat Enterprise Linux") == 0 - ) { - strbuf_append_char(buf_product, ' '); - strbuf_append_char(buf_product, *space); - } - append_rhel_version = false; - space++; - } - } - - *version = strbuf_free_nobuf(buf_version); - *product = strbuf_free_nobuf(buf_product); - - VERB3 log("%s: version:'%s' product:'%s'", __func__, *version, *product); -} - -void parse_release_for_bz(const char *release, char** product, char** version) -{ - /* Fedora/RH bugzilla uses "Red Hat Enterprise Linux N" product RHEL */ - parse_release(release, product, version, /*append_rhel_version:*/ true); -} - -void parse_release_for_rhts(const char *release, char** product, char** version) -{ - /* RHTS uses "Red Hat Enterprise Linux" product for RHEL */ - parse_release(release, product, version, /*append_rhel_version:*/ false); -} diff --git a/src/lib/problem_data.c b/src/lib/problem_data.c deleted file mode 100644 index 7ef1f681..00000000 --- a/src/lib/problem_data.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - Copyright (C) 2010 Denys Vlasenko (dvlasenk@redhat.com) - 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 "abrtlib.h" - -static void free_problem_item(void *ptr) -{ - if (ptr) - { - struct problem_item *item = (struct problem_item *)ptr; - free(item->content); - free(item); - } -} - -char *format_problem_item(struct problem_item *item) -{ - if (!item) - return xstrdup("(nullitem)"); - - if (item->flags & CD_FLAG_UNIXTIME) - { - errno = 0; - char *end; - time_t time = strtol(item->content, &end, 10); - if (!errno && !*end && end != item->content) - { - char timeloc[256]; - int success = strftime(timeloc, sizeof(timeloc), "%c", localtime(&time)); - if (success) - return xstrdup(timeloc); - } - } - return NULL; -} - -/* problem_data["name"] = { "content", CD_FLAG_foo_bits } */ - -problem_data_t *new_problem_data(void) -{ - return g_hash_table_new_full(g_str_hash, g_str_equal, - free, free_problem_item); -} - -void add_basics_to_problem_data(problem_data_t *pd) -{ - const char *analyzer = get_problem_item_content_or_NULL(pd, FILENAME_ANALYZER); - if (analyzer == NULL) - add_to_problem_data(pd, "analyzer", "libreport"); - - /* If application didn't provide dupe hash, we generate it - * from all components, so we at least eliminate the exact same - * reports - */ - if (get_problem_item_content_or_NULL(pd, FILENAME_DUPHASH) == NULL) - { - /* start hash */ - sha1_ctx_t sha1ctx; - sha1_begin(&sha1ctx); - - /* - * To avoid spurious hash differences, sort keys so that elements are - * always processed in the same order: - */ - GList *list = g_hash_table_get_keys(pd); - list = g_list_sort(list, (GCompareFunc)strcmp); - GList *l = list; - while (l) - { - const char *key = l->data; - l = l->next; - struct problem_item *item = g_hash_table_lookup(pd, key); - /* do not hash items which are binary (item->flags & CD_FLAG_BIN). - * Their ->content is full file name, with path. Path is always - * different and will make hash differ even if files are the same. - */ - if (item->flags & CD_FLAG_BIN) - continue; - sha1_hash(&sha1ctx, item->content, strlen(item->content)); - } - g_list_free(list); - - /* end hash */ - char hash_bytes[SHA1_RESULT_LEN]; - sha1_end(&sha1ctx, hash_bytes); - char hash_str[SHA1_RESULT_LEN*2 + 1]; - bin2hex(hash_str, hash_bytes, SHA1_RESULT_LEN)[0] = '\0'; - - add_to_problem_data(pd, FILENAME_DUPHASH, hash_str); - } - - pid_t pid = getpid(); - if (pid > 0) - { - char buf[PATH_MAX+1]; - char *exe = xasprintf("/proc/%u/exe", pid); - ssize_t read = readlink(exe, buf, PATH_MAX); - if (read > 0) - { - buf[read] = 0; - VERB2 log("reporting initiated from: %s", buf); - add_to_problem_data(pd, FILENAME_EXECUTABLE, buf); - } - free(exe); - -//#ifdef WITH_RPM - /* FIXME: component should be taken from rpm using librpm - * which means we need to link against it :( - * or run rpm -qf executable ?? - */ - /* Fedora/RHEL rpm specific piece of code */ - const char *component = get_problem_item_content_or_NULL(pd, FILENAME_COMPONENT); - //FIXME: this REALLY needs to go away, or every report will be assigned to abrt - if (component == NULL) // application didn't specify component - add_to_problem_data(pd, FILENAME_COMPONENT, "abrt"); -//#endif - } -} - -void add_to_problem_data_ext(problem_data_t *problem_data, - const char *name, - const char *content, - unsigned flags) -{ - if (!(flags & CD_FLAG_BIN)) - flags |= CD_FLAG_TXT; - if (!(flags & CD_FLAG_ISEDITABLE)) - flags |= CD_FLAG_ISNOTEDITABLE; - - struct problem_item *item = (struct problem_item *)xzalloc(sizeof(*item)); - item->content = xstrdup(content); - item->flags = flags; - g_hash_table_replace(problem_data, xstrdup(name), item); -} - -void add_to_problem_data(problem_data_t *problem_data, - const char *name, - const char *content) -{ - add_to_problem_data_ext(problem_data, name, content, CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE); -} - -const char *get_problem_item_content_or_die(problem_data_t *problem_data, const char *key) -{ - struct problem_item *item = get_problem_data_item_or_NULL(problem_data, key); - if (!item) - error_msg_and_die("Error accessing problem data: no ['%s']", key); - return item->content; -} - -const char *get_problem_item_content_or_NULL(problem_data_t *problem_data, const char *key) -{ - struct problem_item *item = get_problem_data_item_or_NULL(problem_data, key); - if (!item) - return NULL; - return item->content; -} - - -/* Miscellaneous helpers */ - -static const char *const editable_files[] = { - FILENAME_COMMENT , - FILENAME_BACKTRACE, - NULL -}; -static bool is_editable_file(const char *file_name) -{ - return is_in_string_list(file_name, (char**)editable_files); -} - -static const char *const always_text_files[] = { - FILENAME_CMDLINE , - FILENAME_BACKTRACE, - NULL -}; -static char* is_text_file(const char *name, ssize_t *sz) -{ - /* We were using magic.h API to check for file being text, but it thinks - * that file containing just "0" is not text (!!) - * So, we do it ourself. - */ - - int fd = open(name, O_RDONLY); - if (fd < 0) - return NULL; /* it's not text (because it does not exist! :) */ - - /* Maybe 64k limit is small. But _some_ limit is necessary: - * fields declared "text" may end up in editing fields and such. - * We don't want to accidentally end up with 100meg text in a textbox! - * So, don't remove this. If you really need to, raise the limit. - * - * Bumped up to 200k: saw 124740 byte /proc/PID/smaps file - */ - off_t size = lseek(fd, 0, SEEK_END); - if (size < 0 || size > 200*1024) - { - close(fd); - return NULL; /* it's not a SMALL text */ - } - lseek(fd, 0, SEEK_SET); - - char *buf = (char*)xmalloc(*sz); - ssize_t r = full_read(fd, buf, *sz); - close(fd); - if (r < 0) - { - free(buf); - return NULL; /* it's not text (because we can't read it) */ - } - if (r < *sz) - buf[r] = '\0'; - *sz = r; - - /* Some files in our dump directories are known to always be textual */ - const char *base = strrchr(name, '/'); - if (base) - { - base++; - if (is_in_string_list(base, (char**)always_text_files)) - return buf; - } - - /* Every once in a while, even a text file contains a few garbled - * or unexpected non-ASCII chars. We should not declare it "binary". - */ - const unsigned RATIO = 50; - unsigned total_chars = r + RATIO; - unsigned bad_chars = 1; /* 1 prevents division by 0 later */ - while (--r >= 0) - { - if (buf[r] >= 0x7f - /* among control chars, only '\t','\n' etc are allowed */ - || (buf[r] < ' ' && !isspace(buf[r])) - ) { - if (buf[r] == '\0') - { - /* We don't like NULs very much. Not text for sure! */ - free(buf); - return NULL; - } - bad_chars++; - } - } - - if ((total_chars / bad_chars) >= RATIO) - return buf; /* looks like text to me */ - - free(buf); - return NULL; /* it's binary */ -} - -void load_problem_data_from_dump_dir(problem_data_t *problem_data, struct dump_dir *dd, char **excluding) -{ - char *short_name; - char *full_name; - - dd_init_next_file(dd); - while (dd_get_next_file(dd, &short_name, &full_name)) - { - if (excluding && is_in_string_list(short_name, excluding)) - { - //log("Excluded:'%s'", short_name); - goto next; - } - - ssize_t sz = 4*1024; - char *text = NULL; - bool editable = is_editable_file(short_name); - - if (!editable) - { - text = is_text_file(full_name, &sz); - if (!text) - { - add_to_problem_data_ext(problem_data, - short_name, - full_name, - CD_FLAG_BIN + CD_FLAG_ISNOTEDITABLE - ); - goto next; - } - } - - char *content; - if (sz < 4*1024) /* did is_text_file read entire file? */ - { - /* yes */ - content = text; - } - else - { - /* no, need to read it all */ - free(text); - content = dd_load_text(dd, short_name); - } - /* Strip '\n' from one-line elements: */ - char *nl = strchr(content, '\n'); - if (nl && nl[1] == '\0') - *nl = '\0'; - - int flags = 0; - - if (editable) - flags |= CD_FLAG_TXT | CD_FLAG_ISEDITABLE; - else - flags |= CD_FLAG_TXT | CD_FLAG_ISNOTEDITABLE; - - static const char *const list_files[] = { - FILENAME_UID , - FILENAME_PACKAGE , - FILENAME_EXECUTABLE, - FILENAME_TIME , - FILENAME_COUNT , - NULL - }; - if (is_in_string_list(short_name, (char**)list_files)) - flags |= CD_FLAG_LIST; - - if (strcmp(short_name, FILENAME_TIME) == 0) - flags |= CD_FLAG_UNIXTIME; - - add_to_problem_data_ext(problem_data, - short_name, - content, - flags - ); - free(content); - next: - free(short_name); - free(full_name); - } -} - -problem_data_t *create_problem_data_from_dump_dir(struct dump_dir *dd) -{ - problem_data_t *problem_data = new_problem_data(); - load_problem_data_from_dump_dir(problem_data, dd, NULL); - return problem_data; -} - -/* - * Returns NULL-terminated char *vector[]. Result itself must be freed, - * but do no free list elements. IOW: do free(result), but never free(result[i])! - * If comma_separated_list is NULL or "", returns NULL. - */ -static char **build_exclude_vector(const char *comma_separated_list) -{ - char **exclude_items = NULL; - if (comma_separated_list && comma_separated_list[0]) - { - /* even w/o commas, we'll need two elements: - * exclude_items[0] = "name" - * exclude_items[1] = NULL - */ - unsigned cnt = 2; - - const char *cp = comma_separated_list; - while (*cp) - if (*cp++ == ',') - cnt++; - - /* We place the string directly after the char *vector[cnt]: */ - exclude_items = xzalloc(cnt * sizeof(exclude_items[0]) + (cp - comma_separated_list) + 1); - char *p = strcpy((char*)&exclude_items[cnt], comma_separated_list); - - char **pp = exclude_items; - *pp++ = p; - while (*p) - { - if (*p++ == ',') - { - p[-1] = '\0'; - *pp++ = p; - } - } - } - - return exclude_items; -} - -problem_data_t *create_problem_data_for_reporting(const char *dump_dir_name) -{ - char **exclude_items = build_exclude_vector(getenv("EXCLUDE_FROM_REPORT")); - struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (!dd) - return NULL; /* dd_opendir already emitted error msg */ - problem_data_t *problem_data = new_problem_data(); - load_problem_data_from_dump_dir(problem_data, dd, exclude_items); - dd_close(dd); - free(exclude_items); - return problem_data; -} - -void log_problem_data(problem_data_t *problem_data, const char *pfx) -{ - GHashTableIter iter; - char *name; - struct problem_item *value; - g_hash_table_iter_init(&iter, problem_data); - while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) - { - log("%s[%s]:'%s' 0x%x", - pfx, name, - value->content, - value->flags - ); - } -} diff --git a/src/lib/read_write.c b/src/lib/read_write.c deleted file mode 100644 index fe85fcfb..00000000 --- a/src/lib/read_write.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Utility routines. - * - * Licensed under GPLv2 or later, see file COPYING in this tarball for details. - */ -#include "abrtlib.h" - -/* Die with an error message if we can't read the entire buffer. */ -void xread(int fd, void *buf, size_t count) -{ - if (count) - { - ssize_t size = full_read(fd, buf, count); - if ((size_t)size != count) - error_msg_and_die("short read"); - } -} - -ssize_t safe_read(int fd, void *buf, size_t count) -{ - ssize_t n; - - do { - n = read(fd, buf, count); - } while (n < 0 && errno == EINTR); - - return n; -} - -ssize_t safe_write(int fd, const void *buf, size_t count) -{ - ssize_t n; - - do { - n = write(fd, buf, count); - } while (n < 0 && errno == EINTR); - - return n; -} - -ssize_t full_read(int fd, void *buf, size_t len) -{ - ssize_t cc; - ssize_t total; - - total = 0; - - while (len) - { - cc = safe_read(fd, buf, len); - - if (cc < 0) - { - if (total) - { - /* we already have some! */ - /* user can do another read to know the error code */ - return total; - } - return cc; /* read() returns -1 on failure. */ - } - if (cc == 0) - break; - buf = ((char *)buf) + cc; - total += cc; - len -= cc; - } - - return total; -} - -ssize_t full_write(int fd, const void *buf, size_t len) -{ - ssize_t cc; - ssize_t total; - - total = 0; - - while (len) - { - cc = safe_write(fd, buf, len); - - if (cc < 0) - { - if (total) - { - /* we already wrote some! */ - /* user can do another write to know the error code */ - return total; - } - return cc; /* write() returns -1 on failure. */ - } - - total += cc; - buf = ((const char *)buf) + cc; - len -= cc; - } - - return total; -} - -ssize_t full_write_str(int fd, const char *buf) -{ - return full_write(fd, buf, strlen(buf)); -} diff --git a/src/lib/read_write.h b/src/lib/read_write.h deleted file mode 100644 index dc85f33b..00000000 --- a/src/lib/read_write.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2010 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. -*/ - -#ifndef READ_WRITE_H -#define READ_WRITE_H - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> - -#ifdef __cplusplus -extern "C" { -#endif - - -// NB: will return short read on error, not -1, -// if some data was read before error occurred -#define xread abrt_xread -void xread(int fd, void *buf, size_t count); - -#define safe_read abrt_safe_read -ssize_t safe_read(int fd, void *buf, size_t count); -#define safe_write abrt_safe_write -ssize_t safe_write(int fd, const void *buf, size_t count); - -#define full_read abrt_full_read -ssize_t full_read(int fd, void *buf, size_t count); -#define full_write abrt_full_write -ssize_t full_write(int fd, const void *buf, size_t count); - -#define full_write_str abrt_full_write_str -ssize_t full_write_str(int fd, const char *buf); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/lib/report.c b/src/lib/report.c deleted file mode 100644 index 137f7b16..00000000 --- a/src/lib/report.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - Copyright (C) 2011 ABRT Team - Copyright (C) 2011 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 "abrtlib.h" -#include "report.h" - -int report_problem_in_dir(const char *dirname, int flags) -{ - const char *path; - /* - if is isatty - -> run cli reporter - path = "cli" - */ - - char *args[5], **pp; - pp = args; - *pp++ = (char *)"bug-reporting-wizard"; - if (!(flags & LIBREPORT_ANALYZE)) - *pp++ = (char *)"--report-only"; - *pp++ = (char *)"--"; - *pp++ = (char *)dirname; - *pp++ = NULL; - - pid_t pid = vfork(); - if (pid < 0) /* error */ - { - perror_msg("vfork"); - return -1; - } - - if (pid == 0) /* child */ - { - /* Some callers set SIGCHLD to SIG_IGN. - * However, reporting spawns child processes. - * Suppressing child death notification terribly confuses some of them. - * Just in case, undo it. - * Note that we do it in the child, so the parent is never affected. - */ - signal(SIGCHLD, SIG_DFL); - path = BIN_DIR"/bug-reporting-wizard"; - VERB1 log("Executing: %s", path); - execv(path, args); - /* Did not find the desired executable in the installation directory. - * Trying to find it in PATH - */ - path = "bug-reporting-wizard"; - execvp(path, args); - perror_msg_and_die("Can't execute %s", path); - } - - /* parent */ - if (flags & LIBREPORT_WAIT) - { - int status; - pid_t p = waitpid(pid, &status, 0); - if (p <= 0) - { - perror_msg("can't waitpid"); - return -1; - } - if (WIFEXITED(status)) - { - VERB2 log("reporting finished with exitcode %d", WEXITSTATUS(status)); - return WEXITSTATUS(status); - } - /* child died from a signal: WIFSIGNALED(status) should be true */ - VERB2 log("reporting killed by signal %d", WTERMSIG(status)); - return WTERMSIG(status) + 128; - } - - return 0; -} - -int report_problem_in_memory(problem_data_t *pd, int flags) -{ - int result = 0; - struct dump_dir *dd = create_dump_dir_from_problem_data(pd, "/tmp"/* /var/tmp ?? */); - if (!dd) - return -1; - char *dir_name = xstrdup(dd->dd_dirname); - dd_close(dd); - VERB2 log("Temp problem dir: '%s'", dir_name); - -// TODO: if !LIBREPORT_WAIT pass LIBREPORT_DEL_DIR, and teach bug-reporting-wizard -// an option to delete directory after reporting? -// It will make !LIBREPORT_WAIT reporting possible - result = report_problem_in_dir(dir_name, flags); - - /* If we wait for reporter to finish, we should clean the tmp dir. - * We can also reload the problem data if requested. - */ - if (flags & LIBREPORT_WAIT) - { - if (flags & LIBREPORT_RELOAD_DATA) - g_hash_table_remove_all(pd); - dd = dd_opendir(dir_name, 0); - if (dd) - { - if (flags & LIBREPORT_RELOAD_DATA) - load_problem_data_from_dump_dir(pd, dd, NULL); - dd_delete(dd); - } - } - - free(dir_name); - return result; -} - -int report_problem(problem_data_t *pd) -{ - return report_problem_in_memory(pd, LIBREPORT_WAIT); -} diff --git a/src/lib/run_event.c b/src/lib/run_event.c deleted file mode 100644 index 0d291287..00000000 --- a/src/lib/run_event.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com) - Copyright (C) 2009 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 <glob.h> -#include <regex.h> -#include "abrtlib.h" - -struct run_event_state *new_run_event_state() -{ - return xzalloc(sizeof(struct run_event_state)); -} - -void free_run_event_state(struct run_event_state *state) -{ - if (state) - { - free_commands(state); - free(state); - } -} - - -/* Asynchronous command execution */ - -/* It is not yet clear whether we need to re-parse event config file - * and re-check the elements in dump dir after each command. - * - * Consider this config file: - * - * EVENT=e cmd1 - * EVENT=e foo=bar cmd2 - * EVENT=e foo=baz cmd3 - * - * Imagine that element foo existed and was equal to bar at the beginning. - * After cmd1, should we execute cmd2 if element foo disappeared? - * After cmd1/2, should we execute cmd3 if element foo changed value to baz? - * - * We used to read entire config file and select a list of commands to execute, - * checking all conditions in the beginning. It is a bit more simple to code up. - * - * This proved to be bad for use cases where, for example, post-create rule - * for a specified package needs to run: - * - * EVENT=post-create - * abrt-action-save-package-data - * EVENT=post-create component=mypkg - * my_handling - * - * Problem here is that "component" element is created by - * abrt-action-save-package-data! Pre-selecting rules excludes second rule. - * - * Now we read entire config but do NOT select commands to execute, - * we check conditions of every next rule *directly before its execution*. - * - * It's possible we'd want to switch to an algorightm which makes in unnecessary - * to properly order rules in config files(s). Now these two rules must not - * be reordered, or else second one won't work: - * EVENT=post-create echo foo >bar - * EVENT=post-create foo=bar do_something - * but this might be not so easy to ensure when include files are involved... - * - * Anyway, list of commands machinery is encapsulated in struct run_event_state, - * and public async API: - * prepare_commands(state, dir, event); - * spawn_next_command(state, dir, event); - * free_commands(state); - * does not expose the way we select rules to execute. - */ -struct rule { - GList *conditions; - char *command; /* never NULL */ -}; - -static void free_rule_list(GList *rule_list) -{ - while (rule_list) - { - struct rule *cur_rule = rule_list->data; - list_free_with_free(cur_rule->conditions); - free(cur_rule->command); - free(cur_rule); - - GList *next = rule_list->next; - g_list_free_1(rule_list); - rule_list = next; - } -} - -/* Stop-gap measure against infinite recursion */ -#define MAX_recursion_depth 32 - -static GList *load_rule_list(GList *rule_list, - const char *conf_file_name, - unsigned recursion_depth -) { - FILE *conffile = fopen(conf_file_name, "r"); - if (!conffile) - { - error_msg("Can't open '%s'", conf_file_name); - return rule_list; - } - - /* Read and remember rules */ - char *next_line = xmalloc_fgetline(conffile); - while (next_line) - { - /* Read and concatenate all lines in a rule */ - char *line = next_line; - while (1) - { - next_line = xmalloc_fgetline(conffile); - if (!next_line || !isblank(next_line[0])) - break; - char *old_line = line; - line = xasprintf("%s\n%s", line, next_line); - free(old_line); - free(next_line); - } - - char *p = skip_whitespace(line); - if (*p == '\0' || *p == '#') - goto next_line; /* empty or comment line, skip */ - - //VERB3 log("%s: line '%s'", __func__, p); - - /* Handle "include" directive */ - if (recursion_depth < MAX_recursion_depth - && strncmp(p, "include", strlen("include")) == 0 - && isblank(p[strlen("include")]) - ) { - /* "include GLOB_PATTERN" */ - p = skip_whitespace(p + strlen("include")); - - const char *last_slash; - char *name_to_glob; - if (*p != '/' - && (last_slash = strrchr(conf_file_name, '/')) != NULL - ) - /* GLOB_PATTERN is relative, and this include is in path/to/file.conf - * Construct path/to/GLOB_PATTERN: - */ - name_to_glob = xasprintf("%.*s%s", (int)(last_slash - conf_file_name + 1), conf_file_name, p); - else - /* Either GLOB_PATTERN is absolute, or this include is in file.conf - * (no slashes in its name). Use unchanged GLOB_PATTERN: - */ - name_to_glob = xstrdup(p); - - glob_t globbuf; - memset(&globbuf, 0, sizeof(globbuf)); - //VERB3 log("%s: globbing '%s'", __func__, name_to_glob); - glob(name_to_glob, 0, NULL, &globbuf); - free(name_to_glob); - char **name = globbuf.gl_pathv; - if (name) while (*name) - { - //VERB3 log("%s: recursing into '%s'", __func__, *name); - rule_list = load_rule_list(rule_list, *name, recursion_depth + 1); - //VERB3 log("%s: returned from '%s'", __func__, *name); - name++; - } - globfree(&globbuf); - goto next_line; - } - - /* Rule has form: [VAR=VAL]... PROG [ARGS] */ - struct rule *cur_rule = xzalloc(sizeof(*cur_rule)); - - while (1) /* word loop */ - { - char *end_word = skip_non_whitespace(p); - - /* If there is no '=' in this word... */ - char *line_val = strchr(p, '='); - if (!line_val || line_val >= end_word) - break; /* ...we found the start of a command */ - - cur_rule->conditions = g_list_append(cur_rule->conditions, xstrndup(p, end_word - p)); - - /* Go to next word */ - p = skip_whitespace(end_word); - } /* end of word loop */ - - VERB1 log("Adding '%s'", p); - cur_rule->command = xstrdup(p); - - rule_list = g_list_append(rule_list, cur_rule); - - next_line: - free(line); - } /* end of line loop */ - - fclose(conffile); - - return rule_list; -} - -static int regcmp_lines(char *val, const char *regex) -{ - regex_t rx; - int r = regcomp(&rx, regex, REG_NOSUB); //TODO: and REG_EXTENDED? - //log("REGEX:'%s':%d", regex, r); - if (r) - { - //char errbuf[256]; - //size_t needsz = regerror(r, &rx, errbuf, sizeof(errbuf)); - error_msg("Bad regexp '%s'", regex); // TODO: use errbuf? - return r; - } - - /* Check every line */ - while (1) - { - char *eol = strchr(val, '\n'); - if (eol) - *eol = '\0'; - r = regexec(&rx, val, 0, NULL, /*eflags:*/ 0); - //log("REGCMP:'%s':%d", val, r); - if (eol) - *eol = '\n'; - if (r == 0 || !eol) - break; - val = eol + 1; - } - /* Here, r == 0 if match was found */ - regfree(&rx); - return r; -} - -/* Deletes rules in *pp_rule_list, starting from first (remaining) rule, - * until it finds a rule with all conditions satisfied. - * In this case, it deletes this rule and returns this rule's cmd. - * Else (if it didn't find such rule), it deletes all rules and returns NULL. - * In case of error (dump_dir can't be opened), deletes all rules and returns NULL. - * - * Intended usage: - * list = load_rule_list(...); - * while ((cmd = pop_next_command(&list, ...)) != NULL) - * run(cmd); - */ -static char* pop_next_command(GList **pp_rule_list, - char **pp_event_name, /* reports EVENT value thru this, if not NULL on entry */ - struct dump_dir **pp_dd, /* use *pp_dd for access to dump dir, if non-NULL */ - const char *dump_dir_name, - const char *pfx, - unsigned pfx_len -) -{ - char *command = NULL; - struct dump_dir *dd = pp_dd ? *pp_dd : NULL; - - GList *rule_list = *pp_rule_list; - while (rule_list) - { - struct rule *cur_rule = rule_list->data; - - GList *condition = cur_rule->conditions; - while (condition) - { - const char *cond_str = condition->data; - const char *eq_sign = strchr(cond_str, '='); - - /* Is it "EVENT=foo"? */ - if (strncmp(cond_str, "EVENT=", 6) == 0) - { - if (strncmp(eq_sign + 1, pfx, pfx_len) != 0) - goto next_rule; /* prefix doesn't match */ - if (pp_event_name) - { - free(*pp_event_name); - *pp_event_name = xstrdup(eq_sign + 1); - } - } - else - { - /* Read from dump dir and compare */ - if (!dd) - { - /* Without dir to match, we assume match for all conditions */ - if (!dump_dir_name) - goto next_cond; - dd = dd_opendir(dump_dir_name, /*flags:*/ 0); - if (!dd) - { - free_rule_list(rule_list); - *pp_rule_list = NULL; - goto ret; /* error (note: dd_opendir logged error msg) */ - } - } - /* Is it "VAR~=REGEX"? */ - int regex = (eq_sign > cond_str && eq_sign[-1] == '~'); - char *var_name = xstrndup(cond_str, eq_sign - cond_str - regex); - char *real_val = dd_load_text_ext(dd, var_name, DD_FAIL_QUIETLY_ENOENT); - free(var_name); - int vals_differ = regex ? regcmp_lines(real_val, eq_sign + 1) : strcmp(real_val, eq_sign + 1); - free(real_val); - - /* Do values match? */ - if (vals_differ) /* no */ - { - //VERB3 log("var '%s': '%.*s'!='%s', skipping line", - // p, - // (int)(strchrnul(real_val, '\n') - real_val), real_val, - // eq_sign); - goto next_rule; - } - } - next_cond: - /* We are here if current condition is satisfied */ - - condition = condition->next; - } - /* We are here if all conditions are satisfied */ - - command = cur_rule->command; - - next_rule: - *pp_rule_list = rule_list->next; - g_list_free_1(rule_list); - - list_free_with_free(cur_rule->conditions); - /*free(cur_rule->command); - WRONG! we might be returning it! */ - if (command) - { - /* We found rule to run, return it */ - free(cur_rule); - break; - } - free(cur_rule->command); /* _now_ it is ok */ - free(cur_rule); - - rule_list = *pp_rule_list; - } /* while (rule_list) */ - - ret: - if (pp_dd) - *pp_dd = dd; - else - dd_close(dd); - return command; -} - -void free_commands(struct run_event_state *state) -{ - free_rule_list(state->rule_list); - state->rule_list = NULL; - state->command_out_fd = -1; - state->command_pid = 0; -} - -int prepare_commands(struct run_event_state *state, - const char *dump_dir_name, - const char *event -) { - free_commands(state); - - state->children_count = 0; - - GList *rule_list = load_rule_list(NULL, CONF_DIR"/abrt_event.conf", /*recursion_depth:*/ 0); - state->rule_list = rule_list; - return rule_list != NULL; -} - -int spawn_next_command(struct run_event_state *state, - const char *dump_dir_name, - const char *event -) { - char *cmd = pop_next_command(&state->rule_list, - NULL, /* don't return event_name */ - NULL, /* NULL &dd: we match by... */ - dump_dir_name, /* ...dirname */ - event, strlen(event)+1 /* for this event name exactly (not prefix) */ - ); - if (!cmd) - return -1; - - /* We count it even if fork fails. The counter isn't meant - * to count *successful* forks, it is meant to let caller know - * whether the event we run has *any* handlers configured, or not. - */ - state->children_count++; - - VERB1 log("Executing '%s'", cmd); - - /* Export some useful environment variables for children */ - char *env_vec[3]; - /* Just exporting dump_dir_name isn't always ok: it can be "." - * and some children want to cd to other directory but still - * be able to find dump directory by using $DUMP_DIR... - */ - char *full_name = realpath(dump_dir_name, NULL); - env_vec[0] = xasprintf("DUMP_DIR=%s", (full_name ? full_name : dump_dir_name)); - free(full_name); - env_vec[1] = xasprintf("EVENT=%s", event); - env_vec[2] = NULL; - - char *argv[4]; - argv[0] = (char*)"/bin/sh"; // TODO: honor $SHELL? - argv[1] = (char*)"-c"; - argv[2] = cmd; - argv[3] = NULL; - - int pipefds[2]; - state->command_pid = fork_execv_on_steroids( - EXECFLG_INPUT_NUL + EXECFLG_OUTPUT + EXECFLG_ERR2OUT, - argv, - pipefds, - /* env_vec: */ env_vec, - /* dir: */ dump_dir_name, - /* uid(unused): */ 0 - ); - state->command_out_fd = pipefds[0]; - - free(env_vec[0]); - free(env_vec[1]); - free(cmd); - - return 0; -} - - -/* Synchronous command execution: - */ -int run_event_on_dir_name(struct run_event_state *state, - const char *dump_dir_name, - const char *event -) { - prepare_commands(state, dump_dir_name, event); - - /* Execute every command in shell */ - - int retval = 0; - while (spawn_next_command(state, dump_dir_name, event) >= 0) - { - /* Consume log from stdout */ - FILE *fp = fdopen(state->command_out_fd, "r"); - if (!fp) - die_out_of_memory(); - char *buf; - while ((buf = xmalloc_fgetline(fp)) != NULL) - { - if (state->logging_callback) - buf = state->logging_callback(buf, state->logging_param); - free(buf); - } - fclose(fp); /* Got EOF, close. This also closes state->command_out_fd */ - - /* Wait for child to actually exit, collect status */ - int status; - waitpid(state->command_pid, &status, 0); - - retval = WEXITSTATUS(status); - if (WIFSIGNALED(status)) - retval = WTERMSIG(status) + 128; - if (retval != 0) - break; - - if (state->post_run_callback) - { - retval = state->post_run_callback(dump_dir_name, state->post_run_param); - if (retval != 0) - break; - } - } - - free_commands(state); - - return retval; -} - -int run_event_on_problem_data(struct run_event_state *state, problem_data_t *data, const char *event) -{ - state->children_count = 0; - - struct dump_dir *dd = create_dump_dir_from_problem_data(data, NULL); - if (!dd) - return -1; - char *dir_name = xstrdup(dd->dd_dirname); - dd_close(dd); - - int r = run_event_on_dir_name(state, dir_name, event); - - g_hash_table_remove_all(data); - dd = dd_opendir(dir_name, /*flags:*/ 0); - free(dir_name); - if (dd) - { - load_problem_data_from_dump_dir(data, dd, NULL); - dd_delete(dd); - } - - return r; -} - -char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx) -{ - struct strbuf *result = strbuf_new(); - - GList *rule_list = load_rule_list(NULL, CONF_DIR"/abrt_event.conf", /*recursion_depth:*/ 0); - - unsigned pfx_len = strlen(pfx); - for (;;) - { - /* Retrieve each cmd, and fetch its EVENT=foo value */ - char *event_name = NULL; - char *cmd = pop_next_command(&rule_list, - &event_name, /* return event_name */ - (dd ? &dd : NULL), /* match this dd... */ - dump_dir_name, /* ...or if NULL, this dirname */ - pfx, pfx_len /* for events with this prefix */ - ); - if (!cmd) - break; - free(cmd); - - if (event_name) - { - /* Append "EVENT\n" - only if it is not there yet */ - unsigned e_len = strlen(event_name); - char *p = result->buf; - while (p && *p) - { - if (strncmp(p, event_name, e_len) == 0 && p[e_len] == '\n') - goto skip; /* This event is already in the result */ - p = strchr(p, '\n'); - if (p) - p++; - } - strbuf_append_strf(result, "%s\n", event_name); - skip: - free(event_name); - } - } - - return strbuf_free_nobuf(result); -} diff --git a/src/lib/skip_whitespace.c b/src/lib/skip_whitespace.c deleted file mode 100644 index 816928bf..00000000 --- a/src/lib/skip_whitespace.c +++ /dev/null @@ -1,22 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> - * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. - */ -#include "abrtlib.h" - -char* skip_whitespace(const char *s) -{ - /* NB: isspace('\0') returns 0 */ - while (isspace(*s)) ++s; - - return (char *) s; -} - -char* skip_non_whitespace(const char *s) -{ - while (*s && !isspace(*s)) ++s; - - return (char *) s; -} diff --git a/src/lib/spawn.c b/src/lib/spawn.c deleted file mode 100644 index 188b63bd..00000000 --- a/src/lib/spawn.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Utility routines. - * - * Licensed under GPLv2, see file COPYING in this tarball for details. - */ -#include "abrtlib.h" - -static char *concat_str_vector(char **strings) -{ - if (!strings[0]) - return xzalloc(1); // returns "" - - unsigned len = 0; - char **spp = strings; - while (*spp) - len += strlen(*spp++) + 1; - - char *result = xmalloc(len); - - char *r = result; - spp = strings; - while (*spp) { - r = stpcpy(r, *spp++); - *r++ = ' '; - } - *--r = '\0'; - - return result; -} - -/* Returns pid */ -pid_t fork_execv_on_steroids(int flags, - char **argv, - int *pipefds, - char **env_vec, - const char *dir, - uid_t uid) -{ - pid_t child; - /* Reminder: [0] is read end, [1] is write end */ - int pipe_to_child[2]; - int pipe_fm_child[2]; - - /* Sanitize flags */ - if (!pipefds) - flags &= ~(EXECFLG_INPUT | EXECFLG_OUTPUT); - - if (flags & EXECFLG_INPUT) - xpipe(pipe_to_child); - if (flags & EXECFLG_OUTPUT) - xpipe(pipe_fm_child); - - fflush(NULL); - child = fork(); - if (child == -1) { - perror_msg_and_die("fork"); - } - if (child == 0) { - /* Child */ - - if (dir) - xchdir(dir); - - if (flags & EXECFLG_SETGUID) { - struct passwd* pw = getpwuid(uid); - gid_t gid = pw ? pw->pw_gid : uid; - setgroups(1, &gid); - xsetregid(gid, gid); - xsetreuid(uid, uid); - } - - if (env_vec) { - /* Note: we use the glibc extension that putenv("var") - * *unsets* $var if "var" string has no '=' */ - while (*env_vec) - putenv(*env_vec++); - } - - /* Play with stdio descriptors */ - if (flags & EXECFLG_INPUT) { - xmove_fd(pipe_to_child[0], STDIN_FILENO); - close(pipe_to_child[1]); - } else if (flags & EXECFLG_INPUT_NUL) { - xmove_fd(xopen("/dev/null", O_RDWR), STDIN_FILENO); - } - if (flags & EXECFLG_OUTPUT) { - xmove_fd(pipe_fm_child[1], STDOUT_FILENO); - close(pipe_fm_child[0]); - } else if (flags & EXECFLG_OUTPUT_NUL) { - xmove_fd(xopen("/dev/null", O_RDWR), STDOUT_FILENO); - } - - /* This should be done BEFORE stderr redirect */ - VERB1 { - char *r = concat_str_vector(argv); - log("Executing: %s", r); - free(r); - } - - if (flags & EXECFLG_ERR2OUT) { - /* Want parent to see errors in the same stream */ - xdup2(STDOUT_FILENO, STDERR_FILENO); - } else if (flags & EXECFLG_ERR_NUL) { - xmove_fd(xopen("/dev/null", O_RDWR), STDERR_FILENO); - } - - if (flags & EXECFLG_SETSID) - setsid(); - - execvp(argv[0], argv); - if (!(flags & EXECFLG_QUIET)) - perror_msg("Can't execute '%s'", argv[0]); - exit(127); /* shell uses this exit code in this case */ - } - - if (flags & EXECFLG_INPUT) { - close(pipe_to_child[0]); - pipefds[1] = pipe_to_child[1]; - } - if (flags & EXECFLG_OUTPUT) { - close(pipe_fm_child[1]); - pipefds[0] = pipe_fm_child[0]; - } - - return child; -} - -char *run_in_shell_and_save_output(int flags, - const char *cmd, - const char *dir, - size_t *size_p) -{ - flags |= EXECFLG_OUTPUT; - flags &= ~EXECFLG_INPUT; - - const char *argv[] = { "/bin/sh", "-c", cmd, NULL }; - int pipeout[2]; - pid_t child = fork_execv_on_steroids(flags, (char **)argv, pipeout, - /*env_vec:*/ NULL, dir, /*uid (unused):*/ 0); - - size_t pos = 0; - char *result = NULL; - while (1) { - result = (char*) xrealloc(result, pos + 4*1024 + 1); - size_t sz = safe_read(pipeout[0], result + pos, 4*1024); - if (sz <= 0) { - break; - } - pos += sz; - } - result[pos] = '\0'; - if (size_p) - *size_p = pos; - close(pipeout[0]); - waitpid(child, NULL, 0); - - return result; -} diff --git a/src/lib/stdio_helpers.c b/src/lib/stdio_helpers.c deleted file mode 100644 index 81cf5d75..00000000 --- a/src/lib/stdio_helpers.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Utility routines. - * - * Copyright (C) 2001 Matt Krai - * Copyright (C) 2004 Erik Andersen <andersen@codepoet.org> - * Copyright (C) 2005, 2006 Rob Landley <rob@landley.net> - * Copyright (C) 2010 ABRT Team - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ -#include "abrtlib.h" - -//TODO: add sanitizing upper limit (e.g 64K, 1M, or configurable). -//This is why we don't use GNU's getline: it doesn't have -//any upper sanity bound on line size. - -static char *xmalloc_fgets_internal(FILE *file, int *sizep) -{ - unsigned idx = 0; - char *linebuf = NULL; - - while (1) { - char *r; - - linebuf = xrealloc(linebuf, idx + 0x100); - r = fgets(&linebuf[idx], 0x100, file); - if (!r) { - /* need to terminate the line */ - linebuf[idx] = '\0'; - break; - } - - /* stupid. fgets knows the len, it should report it somehow */ - unsigned len = strlen(&linebuf[idx]); - - idx += len; - if (len < 0xff || linebuf[idx - 1] == '\n') - break; /* we found \n or EOF */ - } - - *sizep = idx; - - if (!idx) { - /* The very first fgets returned NULL. It's EOF (or error) */ - free(linebuf); - linebuf = NULL; - } - return linebuf; -} - -char *xmalloc_fgets(FILE *file) -{ - int sz; - char *r = xmalloc_fgets_internal(file, &sz); - if (!r) - return r; - return xrealloc(r, sz + 1); -} - -char *xmalloc_fgetline(FILE *file) -{ - int sz; - char *r = xmalloc_fgets_internal(file, &sz); - if (!r) - return r; - if (r[sz - 1] == '\n') - r[--sz] = '\0'; - return xrealloc(r, sz + 1); -} diff --git a/src/lib/steal_directory.c b/src/lib/steal_directory.c deleted file mode 100644 index 6991da18..00000000 --- a/src/lib/steal_directory.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (C) 2011 ABRT Team - Copyright (C) 2011 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 "abrtlib.h" - -struct dump_dir *steal_directory(const char *base_dir, const char *dump_dir_name) -{ - const char *base_name = strrchr(dump_dir_name, '/'); - if (base_name) - base_name++; - else - base_name = dump_dir_name; - - struct dump_dir *dd_dst; - unsigned count = 100; - char *dst_dir_name = concat_path_file(base_dir, base_name); - while (1) - { - dd_dst = dd_create(dst_dir_name, (uid_t)-1, 0640); - free(dst_dir_name); - if (dd_dst) - break; - if (--count == 0) - { - error_msg("Can't create new dump dir in '%s'", base_dir); - return NULL; - } - struct timeval tv; - gettimeofday(&tv, NULL); - dst_dir_name = xasprintf("%s/%s.%u", base_dir, base_name, (int)tv.tv_usec); - } - - VERB1 log("Creating copy in '%s'", dd_dst->dd_dirname); - if (copy_file_recursive(dump_dir_name, dd_dst->dd_dirname) < 0) - { - /* error. copy_file_recursive already emitted error message */ - /* Don't leave half-copied dir lying around */ - dd_delete(dd_dst); - return NULL; - } - - return dd_dst; -} diff --git a/src/lib/strbuf.c b/src/lib/strbuf.c deleted file mode 100644 index 572f11cc..00000000 --- a/src/lib/strbuf.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - String buffer implementation - - Copyright (C) 2009 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 "abrtlib.h" - -int prefixcmp(const char *str, const char *prefix) -{ - for (; ; str++, prefix++) - if (!*prefix) - return 0; - else if (*str != *prefix) - return (unsigned char)*prefix - (unsigned char)*str; -} - -int suffixcmp(const char *str, const char *suffix) -{ - int len_minus_suflen = strlen(str) - strlen(suffix); - if (len_minus_suflen < 0) - return len_minus_suflen; - else - return strcmp(str + len_minus_suflen, suffix); -} - -/* - * Trims whitespace characters both from left and right side of a string. - * Modifies the string in-place. Returns the trimmed string. - */ -char *strtrim(char *str) -{ - if (!str) - return NULL; - - // Remove leading spaces. - overlapping_strcpy(str, skip_whitespace(str)); - - // Remove trailing spaces. - int i = strlen(str); - while (--i >= 0) - { - if (!isspace(str[i])) - break; - } - str[++i] = '\0'; - return str; -} - -struct strbuf *strbuf_new(void) -{ - struct strbuf *buf = xzalloc(sizeof(*buf)); - /*buf->len = 0; - done by xzalloc */ - buf->alloc = 8; - buf->buf = xzalloc(8); - return buf; -} - -void strbuf_free(struct strbuf *strbuf) -{ - if (!strbuf) - return; - free(strbuf->buf); - free(strbuf); -} - -char *strbuf_free_nobuf(struct strbuf *strbuf) -{ - char *ret = strbuf->buf; - free(strbuf); - return ret; -} - - -void strbuf_clear(struct strbuf *strbuf) -{ - assert(strbuf->alloc > 0); - strbuf->len = 0; - strbuf->buf[0] = '\0'; -} - -/* Ensures that the buffer can be extended by N+1 characters - * without touching malloc/realloc. - * Returns pointer where appended chars can be stored by the caller; - * increments ->len by N (therefore callers don't need to do it). - */ -static char *strbuf_grow(struct strbuf *strbuf, unsigned increment) -{ - unsigned len = strbuf->len; - unsigned need = strbuf->len = len + increment; - unsigned cur_size = strbuf->alloc; - if (cur_size <= need) - { - while (cur_size <= need) - cur_size += 64 + cur_size / 8; - strbuf->alloc = cur_size; - strbuf->buf = xrealloc(strbuf->buf, cur_size); - } - char *p = strbuf->buf + len; - return p; -} - -struct strbuf *strbuf_append_char(struct strbuf *strbuf, char c) -{ - char *p = strbuf_grow(strbuf, 1); - *p++ = c; - *p = '\0'; - return strbuf; -} - -struct strbuf *strbuf_append_str(struct strbuf *strbuf, const char *str) -{ - unsigned len = strlen(str); - char *p = strbuf_grow(strbuf, len); - assert(strbuf->len < strbuf->alloc); - strcpy(p, str); - return strbuf; -} - -struct strbuf *strbuf_prepend_str(struct strbuf *strbuf, const char *str) -{ - unsigned cur_len = strbuf->len; - unsigned inc_len = strlen(str); - strbuf_grow(strbuf, inc_len); - assert(strbuf->len < strbuf->alloc); - memmove(strbuf->buf + inc_len, strbuf->buf, cur_len); - memcpy(strbuf->buf, str, inc_len); - return strbuf; -} - -struct strbuf *strbuf_append_strf(struct strbuf *strbuf, const char *format, ...) -{ - va_list p; - char *string_ptr; - - va_start(p, format); - string_ptr = xvasprintf(format, p); - va_end(p); - - strbuf_append_str(strbuf, string_ptr); - free(string_ptr); - return strbuf; -} - -struct strbuf *strbuf_prepend_strf(struct strbuf *strbuf, const char *format, ...) -{ - va_list p; - char *string_ptr; - - va_start(p, format); - string_ptr = xvasprintf(format, p); - va_end(p); - - strbuf_prepend_str(strbuf, string_ptr); - free(string_ptr); - return strbuf; -} diff --git a/src/lib/strbuf.h b/src/lib/strbuf.h deleted file mode 100644 index 44c6599a..00000000 --- a/src/lib/strbuf.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - strbuf.h - string buffer - - Copyright (C) 2009 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. -*/ -#ifndef STRBUF_H -#define STRBUF_H - -#ifdef __cplusplus -extern "C" { -#endif - -struct strbuf -{ - /* Size of the allocated buffer. Always > 0. */ - int alloc; - /* Length of the string, without the ending \0. */ - int len; - char *buf; -}; - -/** - * Creates and initializes a new string buffer. - * @returns - * It never returns NULL. The returned pointer must be released by - * calling the function strbuf_free(). - */ -#define strbuf_new abrt_strbuf_new -struct strbuf *strbuf_new(void); - -/** - * Releases the memory held by the string buffer. - * @param strbuf - * If the strbuf is NULL, no operation is performed. - */ -#define strbuf_free abrt_strbuf_free -void strbuf_free(struct strbuf *strbuf); - -/** - * Releases the strbuf, but not the internal buffer. The internal - * string buffer is returned. Caller is responsible to release the - * returned memory using free(). - */ -#define strbuf_free_nobuf abrt_strbuf_free_nobuf -char* strbuf_free_nobuf(struct strbuf *strbuf); - -/** - * The string content is set to an empty string, erasing any previous - * content and leaving its length at 0 characters. - */ -#define strbuf_clear abrt_strbuf_clear -void strbuf_clear(struct strbuf *strbuf); - -/** - * The current content of the string buffer is extended by adding a - * character c at its end. - */ -#define strbuf_append_char abrt_strbuf_append_char -struct strbuf *strbuf_append_char(struct strbuf *strbuf, char c); - -/** - * The current content of the string buffer is extended by adding a - * string str at its end. - */ -#define strbuf_append_str abrt_strbuf_append_str -struct strbuf *strbuf_append_str(struct strbuf *strbuf, - const char *str); - -/** - * The current content of the string buffer is extended by inserting a - * string str at its beginning. - */ -#define strbuf_prepend_str abrt_strbuf_prepend_str -struct strbuf *strbuf_prepend_str(struct strbuf *strbuf, - const char *str); - -/** - * The current content of the string buffer is extended by adding a - * sequence of data formatted as the format argument specifies. - */ -#define strbuf_append_strf abrt_strbuf_append_strf -struct strbuf *strbuf_append_strf(struct strbuf *strbuf, - const char *format, ...); - -/** - * The current content of the string buffer is extended by inserting a - * sequence of data formatted as the format argument specifies at the - * buffer beginning. - */ -#define strbuf_prepend_strf abrt_strbuf_prepend_strf -struct strbuf *strbuf_prepend_strf(struct strbuf *strbuf, - const char *format, ...); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/lib/time.c b/src/lib/time.c deleted file mode 100644 index 37ade2cc..00000000 --- a/src/lib/time.c +++ /dev/null @@ -1,65 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Utility routines. - * - * Licensed under GPL version 2, see file LICENSE in this tarball for details. - */ -#include "abrtlib.h" - -#define ENABLE_MONOTONIC_SYSCALL 1 - -#if ENABLE_MONOTONIC_SYSCALL - -#include <sys/syscall.h> -/* Old glibc (< 2.3.4) does not provide this constant. We use syscall - * directly so this definition is safe. */ -#ifndef CLOCK_MONOTONIC -#define CLOCK_MONOTONIC 1 -#endif - -/* libc has incredibly messy way of doing this, - * typically requiring -lrt. We just skip all this mess */ -static void get_mono(struct timespec *ts) -{ - if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, ts)) - error_msg_and_die("clock_gettime(MONOTONIC) failed"); -} -unsigned long long monotonic_ns(void) -{ - struct timespec ts; - get_mono(&ts); - return ts.tv_sec * 1000000000ULL + ts.tv_nsec; -} -unsigned long long monotonic_us(void) -{ - struct timespec ts; - get_mono(&ts); - return ts.tv_sec * 1000000ULL + ts.tv_nsec/1000; -} -unsigned monotonic_sec(void) -{ - struct timespec ts; - get_mono(&ts); - return ts.tv_sec; -} - -#else - -unsigned long long monotonic_ns(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000; -} -unsigned long long monotonic_us(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000000ULL + tv.tv_usec; -} -unsigned monotonic_sec(void) -{ - return time(NULL); -} - -#endif diff --git a/src/lib/xatonum.c b/src/lib/xatonum.c deleted file mode 100644 index 1a92db7f..00000000 --- a/src/lib/xatonum.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Utility routines. - * - * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> - * - * Licensed under GPLv2, see file LICENSE in this tarball for details. - */ -#include "abrtlib.h" - -unsigned xatou(const char *numstr) -{ - unsigned long r; - int old_errno; - char *e; - - if (*numstr < '0' || *numstr > '9') - goto inval; - - old_errno = errno; - errno = 0; - r = strtoul(numstr, &e, 10); - if (errno || numstr == e || *e != '\0' || r > UINT_MAX) - goto inval; /* error / no digits / illegal trailing chars */ - errno = old_errno; /* Ok. So restore errno. */ - return r; - -inval: - error_msg_and_die("invalid number '%s'", numstr); -} - -int xatoi_positive(const char *numstr) -{ - unsigned r = xatou(numstr); - if (r > (unsigned)INT_MAX) - error_msg_and_die("invalid number '%s'", numstr); - return r; -} - -int xatoi(const char *numstr) -{ - unsigned r; - - if (*numstr != '-') - return xatoi_positive(numstr); - - r = xatou(numstr + 1); - if (r > (unsigned)INT_MAX + 1) - error_msg_and_die("invalid number '%s'", numstr); - return - (int)r; -} diff --git a/src/lib/xconnect.c b/src/lib/xconnect.c deleted file mode 100644 index 0d02b1a4..00000000 --- a/src/lib/xconnect.c +++ /dev/null @@ -1,415 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Utility routines. - * - * Connect to host at port using address resolution from getaddrinfo - * - * Licensed under GPLv2, see file LICENSE in this tarball for details. - */ -#include "abrtlib.h" -#include <sys/socket.h> /* netinet/in.h needs it */ -#include <netinet/in.h> -#include <net/if.h> -#include <sys/un.h> -#include <netdb.h> - -#define ENABLE_FEATURE_IPV6 1 -#define ENABLE_FEATURE_PREFER_IPV4_ADDRESS 1 - -static const int const_int_1 = 1; - -void setsockopt_reuseaddr(int fd) -{ - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_1, sizeof(const_int_1)); -} -int setsockopt_broadcast(int fd) -{ - return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1)); -} -int setsockopt_bindtodevice(int fd, const char *iface) -{ - int r; - struct ifreq ifr; - strncpy(ifr.ifr_name, iface, IFNAMSIZ); - /* NB: passing (iface, strlen(iface) + 1) does not work! - * (maybe it works on _some_ kernels, but not on 2.6.26) - * Actually, ifr_name is at offset 0, and in practice - * just giving char[IFNAMSIZ] instead of struct ifreq works too. - * But just in case it's not true on some obscure arch... */ - r = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)); - if (r) - perror_msg("can't bind to interface %s", iface); - return r; -} - -len_and_sockaddr* get_sock_lsa(int fd) -{ - len_and_sockaddr lsa; - len_and_sockaddr *lsa_ptr; - - lsa.len = LSA_SIZEOF_SA; - if (getsockname(fd, &lsa.u.sa, &lsa.len) != 0) - return NULL; - - lsa_ptr = (len_and_sockaddr *)xzalloc(LSA_LEN_SIZE + lsa.len); - if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */ - lsa_ptr->len = lsa.len; - getsockname(fd, &lsa_ptr->u.sa, &lsa_ptr->len); - } else { - memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len); - } - return lsa_ptr; -} - -void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) -{ - if (connect(s, s_addr, addrlen) < 0) { - close(s); - if (s_addr->sa_family == AF_INET) - perror_msg_and_die("%s (%s)", - "cannot connect to remote host", - inet_ntoa(((struct sockaddr_in *)s_addr)->sin_addr)); - perror_msg_and_die("cannot connect to remote host"); - } -} - -/* Return port number for a service. - * If "port" is a number use it as the port. - * If "port" is a name it is looked up in /etc/services, - * if it isnt found return default_port - */ -unsigned lookup_port(const char *port, const char *protocol, unsigned default_port) -{ - unsigned port_nr = default_port; - if (port) { - int old_errno; - char *end; - - /* Since this is a lib function, we're not allowed to reset errno to 0. - * Doing so could break an app that is deferring checking of errno. */ - old_errno = errno; - errno = 0; - port_nr = strtoul(port, &end, 10); - if (errno || *end || port_nr > 65535) { - struct servent *tserv = getservbyname(port, protocol); - port_nr = default_port; - if (tserv) - port_nr = ntohs(tserv->s_port); - } - errno = old_errno; - } - return (uint16_t)port_nr; -} - -int get_nport(const struct sockaddr *sa) -{ -#if ENABLE_FEATURE_IPV6 - if (sa->sa_family == AF_INET6) { - return ((struct sockaddr_in6*)sa)->sin6_port; - } -#endif - if (sa->sa_family == AF_INET) { - return ((struct sockaddr_in*)sa)->sin_port; - } - /* What? UNIX socket? IPX?? :) */ - return -1; -} - -void set_nport(len_and_sockaddr *lsa, unsigned port) -{ -#if ENABLE_FEATURE_IPV6 - if (lsa->u.sa.sa_family == AF_INET6) { - lsa->u.sin6.sin6_port = port; - return; - } -#endif - if (lsa->u.sa.sa_family == AF_INET) { - lsa->u.sin.sin_port = port; - return; - } - /* What? UNIX socket? IPX?? :) */ -} - -/* We hijack this constant to mean something else */ -/* It doesn't hurt because we will remove this bit anyway */ -#define DIE_ON_ERROR AI_CANONNAME - -/* host: "1.2.3.4[:port]", "www.google.com[:port]" - * port: if neither of above specifies port # */ -static len_and_sockaddr* str2sockaddr( - const char *host, int port, - sa_family_t af, - int ai_flags) -{ - int rc; - len_and_sockaddr *r; - struct addrinfo *result = NULL; - struct addrinfo *used_res; - const char *org_host = host; /* only for error msg */ - const char *cp; - struct addrinfo hint; - - r = NULL; - - /* Ugly parsing of host:addr */ - if (ENABLE_FEATURE_IPV6 && host[0] == '[') { - /* Even uglier parsing of [xx]:nn */ - host++; - cp = strchr(host, ']'); - if (!cp || (cp[1] != ':' && cp[1] != '\0')) { - /* Malformed: must be [xx]:nn or [xx] */ - error_msg("bad address '%s'", org_host); - if (ai_flags & DIE_ON_ERROR) - xfunc_die(); - return NULL; - } - } else { - cp = strrchr(host, ':'); - if (ENABLE_FEATURE_IPV6 && cp && strchr(host, ':') != cp) { - /* There is more than one ':' (e.g. "::1") */ - cp = NULL; /* it's not a port spec */ - } - } - if (cp) { /* points to ":" or "]:" */ - int sz = cp - host + 1; - char *hbuf = (char*)alloca(sz); - hbuf[--sz] = '\0'; - host = strncpy(hbuf, host, sz); - if (ENABLE_FEATURE_IPV6 && *cp != ':') { - cp++; /* skip ']' */ - if (*cp == '\0') /* [xx] without port */ - goto skip; - } - cp++; /* skip ':' */ - char *end; - errno = 0; - port = strtoul(cp, &end, 10); - if (errno || *end || (unsigned)port > 0xffff) { - error_msg("bad port spec '%s'", org_host); - if (ai_flags & DIE_ON_ERROR) - xfunc_die(); - return NULL; - } - skip: ; - } - - memset(&hint, 0 , sizeof(hint)); -#if !ENABLE_FEATURE_IPV6 - hint.ai_family = AF_INET; /* do not try to find IPv6 */ -#else - hint.ai_family = af; -#endif - /* Needed. Or else we will get each address thrice (or more) - * for each possible socket type (tcp,udp,raw...): */ - hint.ai_socktype = SOCK_STREAM; - hint.ai_flags = ai_flags & ~DIE_ON_ERROR; - rc = getaddrinfo(host, NULL, &hint, &result); - if (rc || !result) { - error_msg("bad address '%s'", org_host); - if (ai_flags & DIE_ON_ERROR) - xfunc_die(); - goto ret; - } - used_res = result; -#if ENABLE_FEATURE_PREFER_IPV4_ADDRESS - while (1) { - if (used_res->ai_family == AF_INET) - break; - used_res = used_res->ai_next; - if (!used_res) { - used_res = result; - break; - } - } -#endif - r = (len_and_sockaddr *)xmalloc(offsetof(len_and_sockaddr, u.sa) + used_res->ai_addrlen); - r->len = used_res->ai_addrlen; - memcpy(&r->u.sa, used_res->ai_addr, used_res->ai_addrlen); - set_nport(r, htons(port)); - ret: - freeaddrinfo(result); - return r; -} -#if !ENABLE_FEATURE_IPV6 -#define str2sockaddr(host, port, af, ai_flags) str2sockaddr(host, port, ai_flags) -#endif - -#if ENABLE_FEATURE_IPV6 -len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af) -{ - return str2sockaddr(host, port, af, 0); -} - -len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af) -{ - return str2sockaddr(host, port, af, DIE_ON_ERROR); -} -#endif - -len_and_sockaddr* host2sockaddr(const char *host, int port) -{ - return str2sockaddr(host, port, AF_UNSPEC, 0); -} - -len_and_sockaddr* xhost2sockaddr(const char *host, int port) -{ - return str2sockaddr(host, port, AF_UNSPEC, DIE_ON_ERROR); -} - -len_and_sockaddr* xdotted2sockaddr(const char *host, int port) -{ - return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR); -} - -#undef xsocket_type -int xsocket_type(len_and_sockaddr **lsap, int family, int sock_type) -{ - len_and_sockaddr *lsa; - int fd; - int len; - -#if ENABLE_FEATURE_IPV6 - if (family == AF_UNSPEC) { - fd = socket(AF_INET6, sock_type, 0); - if (fd >= 0) { - family = AF_INET6; - goto done; - } - family = AF_INET; - } -#endif - fd = xsocket(family, sock_type, 0); - len = sizeof(struct sockaddr_in); -#if ENABLE_FEATURE_IPV6 - if (family == AF_INET6) { - done: - len = sizeof(struct sockaddr_in6); - } -#endif - lsa = (len_and_sockaddr *)xzalloc(offsetof(len_and_sockaddr, u.sa) + len); - lsa->len = len; - lsa->u.sa.sa_family = family; - *lsap = lsa; - return fd; -} - -int xsocket_stream(len_and_sockaddr **lsap) -{ - return xsocket_type(lsap, AF_UNSPEC, SOCK_STREAM); -} - -static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) -{ - int fd; - len_and_sockaddr *lsa; - - if (bindaddr && bindaddr[0]) { - lsa = xdotted2sockaddr(bindaddr, port); - /* user specified bind addr dictates family */ - fd = xsocket(lsa->u.sa.sa_family, sock_type, 0); - } else { - fd = xsocket_type(&lsa, AF_UNSPEC, sock_type); - set_nport(lsa, htons(port)); - } - setsockopt_reuseaddr(fd); - xbind(fd, &lsa->u.sa, lsa->len); - free(lsa); - return fd; -} - -int create_and_bind_stream_or_die(const char *bindaddr, int port) -{ - return create_and_bind_or_die(bindaddr, port, SOCK_STREAM); -} - -int create_and_bind_dgram_or_die(const char *bindaddr, int port) -{ - return create_and_bind_or_die(bindaddr, port, SOCK_DGRAM); -} - - -int create_and_connect_stream_or_die(const char *peer, int port) -{ - int fd; - len_and_sockaddr *lsa; - - lsa = xhost2sockaddr(peer, port); - fd = xsocket(lsa->u.sa.sa_family, SOCK_STREAM, 0); - setsockopt_reuseaddr(fd); - xconnect(fd, &lsa->u.sa, lsa->len); - free(lsa); - return fd; -} - -int xconnect_stream(const len_and_sockaddr *lsa) -{ - int fd = xsocket(lsa->u.sa.sa_family, SOCK_STREAM, 0); - xconnect(fd, &lsa->u.sa, lsa->len); - return fd; -} - -/* We hijack this constant to mean something else */ -/* It doesn't hurt because we will add this bit anyway */ -#define IGNORE_PORT NI_NUMERICSERV -static char* sockaddr2str(const struct sockaddr *sa, int flags) -{ - char host[128]; - char serv[16]; - int rc; - socklen_t salen; - - salen = LSA_SIZEOF_SA; -#if ENABLE_FEATURE_IPV6 - if (sa->sa_family == AF_INET) - salen = sizeof(struct sockaddr_in); - if (sa->sa_family == AF_INET6) - salen = sizeof(struct sockaddr_in6); -#endif - rc = getnameinfo(sa, salen, - host, sizeof(host), - /* can do ((flags & IGNORE_PORT) ? NULL : serv) but why bother? */ - serv, sizeof(serv), - /* do not resolve port# into service _name_ */ - flags | NI_NUMERICSERV - ); - if (rc) - return NULL; - if (flags & IGNORE_PORT) - return xstrdup(host); -#if ENABLE_FEATURE_IPV6 - if (sa->sa_family == AF_INET6) { - if (strchr(host, ':')) /* heh, it's not a resolved hostname */ - return xasprintf("[%s]:%s", host, serv); - /*return xasprintf("%s:%s", host, serv);*/ - /* - fall through instead */ - } -#endif - /* For now we don't support anything else, so it has to be INET */ - /*if (sa->sa_family == AF_INET)*/ - return xasprintf("%s:%s", host, serv); - /*return xstrdup(host);*/ -} - -char* xmalloc_sockaddr2host(const struct sockaddr *sa) -{ - return sockaddr2str(sa, 0); -} - -char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa) -{ - return sockaddr2str(sa, IGNORE_PORT); -} - -char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa) -{ - return sockaddr2str(sa, NI_NAMEREQD | IGNORE_PORT); -} -char* xmalloc_sockaddr2dotted(const struct sockaddr *sa) -{ - return sockaddr2str(sa, NI_NUMERICHOST); -} - -char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa) -{ - return sockaddr2str(sa, NI_NUMERICHOST | IGNORE_PORT); -} diff --git a/src/lib/xfuncs.c b/src/lib/xfuncs.c deleted file mode 100644 index 3766d231..00000000 --- a/src/lib/xfuncs.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - Copyright (C) 2010 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. -*/ - -/* - * Utility routines. - * - */ -#include "abrtlib.h" - -/* Turn on nonblocking I/O on a fd */ -int ndelay_on(int fd) -{ - int flags = fcntl(fd, F_GETFL); - if (flags & O_NONBLOCK) - return 0; - return fcntl(fd, F_SETFL, flags | O_NONBLOCK); -} - -int ndelay_off(int fd) -{ - int flags = fcntl(fd, F_GETFL); - if (!(flags & O_NONBLOCK)) - return 0; - return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); -} - -int close_on_exec_on(int fd) -{ - return fcntl(fd, F_SETFD, FD_CLOEXEC); -} - -// Die if we can't allocate size bytes of memory. -void* xmalloc(size_t size) -{ - void *ptr = malloc(size); - if (ptr == NULL && size != 0) - die_out_of_memory(); - return ptr; -} - -// Die if we can't resize previously allocated memory. (This returns a pointer -// to the new memory, which may or may not be the same as the old memory. -// It'll copy the contents to a new chunk and free the old one if necessary.) -void* xrealloc(void *ptr, size_t size) -{ - ptr = realloc(ptr, size); - if (ptr == NULL && size != 0) - die_out_of_memory(); - return ptr; -} - -// Die if we can't allocate and zero size bytes of memory. -void* xzalloc(size_t size) -{ - void *ptr = xmalloc(size); - memset(ptr, 0, size); - return ptr; -} - -// Die if we can't copy a string to freshly allocated memory. -char* xstrdup(const char *s) -{ - char *t; - if (s == NULL) - return NULL; - - t = strdup(s); - - if (t == NULL) - die_out_of_memory(); - - return t; -} - -// Die if we can't allocate n+1 bytes (space for the null terminator) and copy -// the (possibly truncated to length n) string into it. -char* xstrndup(const char *s, int n) -{ - int m; - char *t; - - /* We can just xmalloc(n+1) and strncpy into it, */ - /* but think about xstrndup("abc", 10000) wastage! */ - m = n; - t = (char*) s; - while (m) - { - if (!*t) break; - m--; - t++; - } - n -= m; - t = (char*) xmalloc(n + 1); - t[n] = '\0'; - - return (char*) memcpy(t, s, n); -} - -void xpipe(int filedes[2]) -{ - if (pipe(filedes)) - perror_msg_and_die("can't create pipe"); -} - -void xdup(int from) -{ - if (dup(from) < 0) - perror_msg_and_die("can't duplicate file descriptor"); -} - -void xdup2(int from, int to) -{ - if (dup2(from, to) != to) - perror_msg_and_die("can't duplicate file descriptor"); -} - -// "Renumber" opened fd -void xmove_fd(int from, int to) -{ - if (from == to) - return; - xdup2(from, to); - close(from); -} - -// Die with an error message if we can't write the entire buffer. -void xwrite(int fd, const void *buf, size_t count) -{ - if (count == 0) - return; - ssize_t size = full_write(fd, buf, count); - if ((size_t)size != count) - error_msg_and_die("short write"); -} - -void xwrite_str(int fd, const char *str) -{ - xwrite(fd, str, strlen(str)); -} - -// Die with an error message if we can't lseek to the right spot. -off_t xlseek(int fd, off_t offset, int whence) -{ - off_t off = lseek(fd, offset, whence); - if (off == (off_t)-1) { - if (whence == SEEK_SET) - perror_msg_and_die("lseek(%llu)", (long long)offset); - perror_msg_and_die("lseek"); - } - return off; -} - -void xchdir(const char *path) -{ - if (chdir(path)) - perror_msg_and_die("chdir(%s)", path); -} - -char* xvasprintf(const char *format, va_list p) -{ - int r; - char *string_ptr; - -#if 1 - // GNU extension - r = vasprintf(&string_ptr, format, p); -#else - // Bloat for systems that haven't got the GNU extension. - va_list p2; - va_copy(p2, p); - r = vsnprintf(NULL, 0, format, p); - string_ptr = xmalloc(r+1); - r = vsnprintf(string_ptr, r+1, format, p2); - va_end(p2); -#endif - - if (r < 0) - die_out_of_memory(); - return string_ptr; -} - -// Die with an error message if we can't malloc() enough space and do an -// sprintf() into that space. -char* xasprintf(const char *format, ...) -{ - va_list p; - char *string_ptr; - - va_start(p, format); - string_ptr = xvasprintf(format, p); - va_end(p); - - return string_ptr; -} - -void xsetenv(const char *key, const char *value) -{ - if (setenv(key, value, 1)) - die_out_of_memory(); -} - -void safe_unsetenv(const char *var_val) -{ - //char *name = xstrndup(var_val, strchrnul(var_val, '=') - var_val); - //unsetenv(name); - //free(name); - - /* Avoid malloc/free (name is usually very short) */ - unsigned len = strchrnul(var_val, '=') - var_val; - char name[len + 1]; - memcpy(name, var_val, len); - name[len] = '\0'; - unsetenv(name); -} - -// Die with an error message if we can't open a new socket. -int xsocket(int domain, int type, int protocol) -{ - int r = socket(domain, type, protocol); - if (r < 0) - { - const char *s = "INET"; - if (domain == AF_PACKET) s = "PACKET"; - if (domain == AF_NETLINK) s = "NETLINK"; - if (domain == AF_INET6) s = "INET6"; - perror_msg_and_die("socket(AF_%s)", s); - } - - return r; -} - -// Die with an error message if we can't bind a socket to an address. -void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) -{ - if (bind(sockfd, my_addr, addrlen)) - perror_msg_and_die("bind"); -} - -// Die with an error message if we can't listen for connections on a socket. -void xlisten(int s, int backlog) -{ - if (listen(s, backlog)) - perror_msg_and_die("listen"); -} - -// Die with an error message if sendto failed. -// Return bytes sent otherwise -ssize_t xsendto(int s, const void *buf, size_t len, - const struct sockaddr *to, - socklen_t tolen) -{ - ssize_t ret = sendto(s, buf, len, 0, to, tolen); - if (ret < 0) - { - close(s); - perror_msg_and_die("sendto"); - } - return ret; -} - -// xstat() - a stat() which dies on failure with meaningful error message -void xstat(const char *name, struct stat *stat_buf) -{ - if (stat(name, stat_buf)) - perror_msg_and_die("can't stat '%s'", name); -} - -// Die if we can't open a file and return a fd -int xopen3(const char *pathname, int flags, int mode) -{ - int ret; - ret = open(pathname, flags, mode); - if (ret < 0) - perror_msg_and_die("can't open '%s'", pathname); - return ret; -} - -// Die if we can't open an existing file and return a fd -int xopen(const char *pathname, int flags) -{ - return xopen3(pathname, flags, 0666); -} - -void xunlink(const char *pathname) -{ - if (unlink(pathname)) - perror_msg_and_die("Can't remove file '%s'", pathname); -} - -#if 0 //UNUSED -// Warn if we can't open a file and return a fd. -int open3_or_warn(const char *pathname, int flags, int mode) -{ - int ret; - ret = open(pathname, flags, mode); - if (ret < 0) - perror_msg("can't open '%s'", pathname); - return ret; -} - -// Warn if we can't open a file and return a fd. -int open_or_warn(const char *pathname, int flags) -{ - return open3_or_warn(pathname, flags, 0666); -} -#endif - -/* Just testing dent->d_type == DT_REG is wrong: some filesystems - * do not report the type, they report DT_UNKNOWN for every dirent - * (and this is not a bug in filesystem, this is allowed by standards). - */ -int is_regular_file(struct dirent *dent, const char *dirname) -{ - if (dent->d_type == DT_REG) - return 1; - if (dent->d_type != DT_UNKNOWN) - return 0; - - char *fullname = xasprintf("%s/%s", dirname, dent->d_name); - struct stat statbuf; - int r = lstat(fullname, &statbuf); - free(fullname); - - return r == 0 && S_ISREG(statbuf.st_mode); -} - -/* Is it "." or ".."? */ -/* abrtlib candidate */ -bool dot_or_dotdot(const char *filename) -{ - if (filename[0] != '.') return false; - if (filename[1] == '\0') return true; - if (filename[1] != '.') return false; - if (filename[2] == '\0') return true; - return false; -} - -/* Find out if the last character of a string matches the one given. - * Don't underrun the buffer if the string length is 0. - */ -char *last_char_is(const char *s, int c) -{ - if (s && *s) - { - s += strlen(s) - 1; - if ((unsigned char)*s == c) - return (char*)s; - } - return NULL; -} - -bool string_to_bool(const char *s) -{ - if (s[0] == '1' && s[1] == '\0') - return true; - if (strcasecmp(s, "on") == 0) - return true; - if (strcasecmp(s, "yes") == 0) - return true; - if (strcasecmp(s, "true") == 0) - return true; - return false; -} - -void xseteuid(uid_t euid) -{ - if (seteuid(euid) != 0) - perror_msg_and_die("can't set %cid %lu", 'u', (long)euid); -} - -void xsetegid(gid_t egid) -{ - if (setegid(egid) != 0) - perror_msg_and_die("can't set %cid %lu", 'g', (long)egid); -} - -void xsetreuid(uid_t ruid, uid_t euid) -{ - if (setreuid(ruid, euid) != 0) - perror_msg_and_die("can't set %cid %lu", 'u', (long)ruid); -} - -void xsetregid(gid_t rgid, gid_t egid) -{ - if (setregid(rgid, egid) != 0) - perror_msg_and_die("can't set %cid %lu", 'g', (long)rgid); -} - -const char *get_home_dir(uid_t uid) -{ - struct passwd* pw = getpwuid(uid); - // TODO: handle errno - return pw ? pw->pw_dir : NULL; -} diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index e3dbcffc..b041b060 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -108,7 +108,7 @@ $(DESTDIR)/$(DEBUG_INFO_DIR): abrt_dump_oops_SOURCES = \ abrt-dump-oops.c abrt_dump_oops_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -119,15 +119,17 @@ abrt_dump_oops_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_dump_oops_LDADD = \ - ../lib/libreport.la + $(GLIB_LIBS) \ + $(LIBREPORT_LIBS) abrt_action_analyze_c_SOURCES = \ abrt-action-analyze-c.c abrt_action_analyze_c_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -138,15 +140,16 @@ abrt_action_analyze_c_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_analyze_c_LDADD = \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_analyze_python_SOURCES = \ abrt-action-analyze-python.c abrt_action_analyze_python_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -157,15 +160,17 @@ abrt_action_analyze_python_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_analyze_python_LDADD = \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_analyze_oops_SOURCES = \ abrt-action-analyze-oops.c abrt_action_analyze_oops_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../libreport/src/include/ -I$(srcdir)/../include \ + -I$(srcdir)/../libreport/src/lib \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -176,15 +181,16 @@ abrt_action_analyze_oops_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_analyze_oops_LDADD = \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_trim_files_SOURCES = \ abrt-action-trim-files.c abrt_action_trim_files_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -195,15 +201,17 @@ abrt_action_trim_files_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_trim_files_LDADD = \ - ../lib/libreport.la + $(LIBREPORT_LIBS) \ + ../lib/libabrt.la abrt_action_generate_backtrace_SOURCES = \ abrt-action-generate-backtrace.c abrt_action_generate_backtrace_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -214,15 +222,16 @@ abrt_action_generate_backtrace_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_generate_backtrace_LDADD = \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_analyze_backtrace_SOURCES = \ abrt-action-analyze-backtrace.c abrt_action_analyze_backtrace_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -233,16 +242,17 @@ abrt_action_analyze_backtrace_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_analyze_backtrace_LDADD = \ - ../lib/libreport.la \ + $(LIBREPORT_LIBS) \ ../btparser/libbtparser.la abrt_action_bugzilla_SOURCES = \ abrt-action-bugzilla.c rhbz.c rhbz.h abrt_action_bugzilla_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -253,18 +263,19 @@ abrt_action_bugzilla_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings abrt_action_bugzilla_LDADD = \ $(GLIB_LIBS) \ ../lib/libabrt_web.la \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_rhtsupport_SOURCES = \ abrt_rh_support.h abrt_rh_support.c \ abrt-action-rhtsupport.c abrt_action_rhtsupport_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -275,6 +286,7 @@ abrt_action_rhtsupport_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror @@ -283,12 +295,12 @@ abrt_action_rhtsupport_LDADD = \ $(GLIB_LIBS) \ $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) \ ../lib/libabrt_web.la \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_upload_SOURCES = \ abrt-action-upload.c abrt_action_upload_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -300,18 +312,19 @@ abrt_action_upload_CPPFLAGS = \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ $(CURL_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_upload_LDFLAGS = -ltar abrt_action_upload_LDADD = \ $(GLIB_LIBS) \ $(CURL_LIBS) \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_kerneloops_SOURCES = \ abrt-action-kerneloops.c abrt_action_kerneloops_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -322,16 +335,18 @@ abrt_action_kerneloops_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_kerneloops_LDADD = \ ../lib/libabrt_web.la \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_mailx_SOURCES = \ abrt-action-mailx.c abrt_action_mailx_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../libreport/src/include/ -I$(srcdir)/../include \ + -I$(srcdir)/../libreport/src/lib \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -342,15 +357,16 @@ abrt_action_mailx_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_mailx_LDADD = \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_print_SOURCES = \ abrt-action-print.c abrt_action_print_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -DBIN_DIR=\"$(bindir)\" \ -DVAR_RUN=\"$(VAR_RUN)\" \ @@ -361,32 +377,34 @@ abrt_action_print_CPPFLAGS = \ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ $(GLIB_CFLAGS) \ + $(LIBREPORT_CFLAGS) \ -D_GNU_SOURCE \ -Wall -Wwrite-strings -Werror abrt_action_print_LDADD = \ - ../lib/libreport.la + $(LIBREPORT_LIBS) abrt_action_install_debuginfo_to_abrt_cache_SOURCES = \ abrt-action-install-debuginfo-to-abrt-cache.c abrt_action_install_debuginfo_to_abrt_cache_CPPFLAGS = \ - -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../include \ -I$(srcdir)/../lib \ -D_GNU_SOURCE \ + $(LIBREPORT_CFLAGS) \ -Wall -Wwrite-strings abrt_action_install_debuginfo_to_abrt_cache_LDADD = abrt_retrace_client_SOURCES = \ abrt-retrace-client.c abrt_retrace_client_CFLAGS = \ - -I$(srcdir)/../include/report \ - -I$(srcdir)/../include \ - -I$(srcdir)/../lib \ + -I$(srcdir)/../include \ + -I$(srcdir)/../lib \ $(NSS_CFLAGS) \ $(GLIB_CFLAGS) \ -D_GNU_SOURCE \ + $(LIBREPORT_CFLAGS) \ -Wall -Wwrite-strings -Werror abrt_retrace_client_LDADD = \ - ../lib/libreport.la \ + $(LIBREPORT_LIBS) \ ../btparser/libbtparser.la \ $(NSS_LIBS) |