From 0e74f780545b1aa8f6a5277b3cfdc9887c37ed5e Mon Sep 17 00:00:00 2001 From: Jiri Moskovcak Date: Wed, 8 Jun 2011 17:27:42 +0200 Subject: split libreport to a separate package --- src/Makefile.am | 2 +- src/applet/Makefile.am | 8 +- src/btparser/Makefile.am | 4 +- src/cli/Makefile.am | 6 +- src/daemon/Makefile.am | 19 +- src/gui-gtk/Makefile.am | 9 +- src/hooks/Makefile.am | 6 +- src/include/Makefile.am | 10 +- src/include/abrtlib.h | 207 +-------- src/include/report/dump_dir.h | 80 ---- src/include/report/event_config.h | 107 ----- src/include/report/problem_data.h | 99 ----- src/include/report/report.h | 42 -- src/include/report/run_event.h | 82 ---- src/lib/Makefile.am | 79 +--- src/lib/abrt_dbus.c | 623 -------------------------- src/lib/abrt_dbus.h | 360 ---------------- src/lib/abrt_types.c | 37 -- src/lib/append_to_malloced_string.c | 27 -- src/lib/binhex.c | 74 ---- src/lib/concat_path_file.c | 25 -- src/lib/copy_file_recursive.c | 149 ------- src/lib/copyfd.c | 172 -------- src/lib/create_dump_dir.c | 85 ---- src/lib/dirsize.c | 110 ----- src/lib/dump_dir.c | 839 ------------------------------------ src/lib/encbase64.c | 78 ---- src/lib/event_config.c | 366 ---------------- src/lib/event_xml_parser.c | 469 -------------------- src/lib/get_cmdline.c | 150 ------- src/lib/glib_support.c | 27 -- src/lib/hash_sha1.c | 211 --------- src/lib/hash_sha1.h | 47 -- src/lib/hooklib.c | 2 +- src/lib/is_in_string_list.c | 30 -- src/lib/iso_date_string.c | 31 -- src/lib/kernel-tainted.c | 143 ------ src/lib/load_plugin_settings.c | 97 ----- src/lib/logging.c | 148 ------- src/lib/logging.h | 91 ---- src/lib/make_descr.c | 262 ----------- src/lib/overlapping_strcpy.c | 22 - src/lib/parse_options.c | 251 ----------- src/lib/parse_options.h | 80 ---- src/lib/parse_release.c | 81 ---- src/lib/problem_data.c | 424 ------------------ src/lib/read_write.c | 105 ----- src/lib/read_write.h | 55 --- src/lib/report.c | 129 ------ src/lib/run_event.c | 551 ----------------------- src/lib/skip_whitespace.c | 22 - src/lib/spawn.c | 158 ------- src/lib/stdio_helpers.c | 69 --- src/lib/steal_directory.c | 58 --- src/lib/strbuf.c | 170 -------- src/lib/strbuf.h | 112 ----- src/lib/time.c | 65 --- src/lib/xatonum.c | 50 --- src/lib/xconnect.c | 415 ------------------ src/lib/xfuncs.c | 410 ------------------ src/plugins/Makefile.am | 80 ++-- 61 files changed, 95 insertions(+), 8625 deletions(-) delete mode 100644 src/include/report/dump_dir.h delete mode 100644 src/include/report/event_config.h delete mode 100644 src/include/report/problem_data.h delete mode 100644 src/include/report/report.h delete mode 100644 src/include/report/run_event.h delete mode 100644 src/lib/abrt_dbus.c delete mode 100644 src/lib/abrt_dbus.h delete mode 100644 src/lib/abrt_types.c delete mode 100644 src/lib/append_to_malloced_string.c delete mode 100644 src/lib/binhex.c delete mode 100644 src/lib/concat_path_file.c delete mode 100644 src/lib/copy_file_recursive.c delete mode 100644 src/lib/copyfd.c delete mode 100644 src/lib/create_dump_dir.c delete mode 100644 src/lib/dirsize.c delete mode 100644 src/lib/dump_dir.c delete mode 100644 src/lib/encbase64.c delete mode 100644 src/lib/event_config.c delete mode 100644 src/lib/event_xml_parser.c delete mode 100644 src/lib/get_cmdline.c delete mode 100644 src/lib/glib_support.c delete mode 100644 src/lib/hash_sha1.c delete mode 100644 src/lib/hash_sha1.h delete mode 100644 src/lib/is_in_string_list.c delete mode 100644 src/lib/iso_date_string.c delete mode 100644 src/lib/kernel-tainted.c delete mode 100644 src/lib/load_plugin_settings.c delete mode 100644 src/lib/logging.c delete mode 100644 src/lib/logging.h delete mode 100644 src/lib/make_descr.c delete mode 100644 src/lib/overlapping_strcpy.c delete mode 100644 src/lib/parse_options.c delete mode 100644 src/lib/parse_options.h delete mode 100644 src/lib/parse_release.c delete mode 100644 src/lib/problem_data.c delete mode 100644 src/lib/read_write.c delete mode 100644 src/lib/read_write.h delete mode 100644 src/lib/report.c delete mode 100644 src/lib/run_event.c delete mode 100644 src/lib/skip_whitespace.c delete mode 100644 src/lib/spawn.c delete mode 100644 src/lib/stdio_helpers.c delete mode 100644 src/lib/steal_directory.c delete mode 100644 src/lib/strbuf.c delete mode 100644 src/lib/strbuf.h delete mode 100644 src/lib/time.c delete mode 100644 src/lib/xatonum.c delete mode 100644 src/lib/xconnect.c delete mode 100644 src/lib/xfuncs.c (limited to 'src') 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 #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 -#include - -#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 - -#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 - -#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 -#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 -#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 -#include - -/* - * 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 struct abrt_dbus_type {}; -//template <> struct abrt_dbus_type { static const char* csig() { return "b"; } }; -template <> struct abrt_dbus_type { static const char* csig() { return "i"; } static std::string sig(); }; -template <> struct abrt_dbus_type { static const char* csig() { return "u"; } static std::string sig(); }; -template <> struct abrt_dbus_type { static const char* csig() { return "x"; } static std::string sig(); }; -template <> struct abrt_dbus_type { static const char* csig() { return "t"; } static std::string sig(); }; -template <> struct abrt_dbus_type { static const char* csig() { return "s"; } static std::string sig(); }; -#define ABRT_DBUS_SIG(T) (abrt_dbus_type::csig() ? abrt_dbus_type::csig() : abrt_dbus_type::sig().c_str()) -template -struct abrt_dbus_type< std::vector > { - static const char* csig() { return NULL; } - static std::string sig() { return ssprintf("a%s", ABRT_DBUS_SIG(E)); } -}; -template -struct abrt_dbus_type< std::map > { - static const char* csig() { return NULL; } - static std::string sig() { return ssprintf("a{%s%s}", ABRT_DBUS_SIG(K), ABRT_DBUS_SIG(V)); } -}; - -template -static void store_vector(DBusMessageIter* iter, const std::vector& 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::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& val) -{ - if we use such vector, MUST add specialized code here (see in dbus-c++ source) -} -*/ -template -static void store_map(DBusMessageIter* iter, const std::map& 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::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 -static inline void store_val(DBusMessageIter* iter, const std::vector& val) { store_vector(iter, val); } -template -static inline void store_val(DBusMessageIter* iter, const std::map& 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 -static int load_vector(DBusMessageIter* iter, std::vector& 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& val) -{ - if we use such vector, MUST add specialized code here (see in dbus-c++ source) -} -*/ -template -static int load_map(DBusMessageIter* iter, std::map& 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 -static inline int load_val(DBusMessageIter* iter, std::vector& val) { return load_vector(iter, val); } -template -static inline int load_val(DBusMessageIter* iter, std::map& 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 -#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 - * - * 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 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: