diff options
| author | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-22 18:05:08 +0200 |
|---|---|---|
| committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-22 18:05:08 +0200 |
| commit | b5f18dbe443f8b0295d34f23d00e66d324dff28b (patch) | |
| tree | a98b68436cc5e69c71782243963b37fd74593367 /src | |
| parent | 3550d52943a2f8214d82e5cc6e6f00beb5d8d1ed (diff) | |
This patch splits off abrtd's package/component/description
generation into a separate tool:
abrt-action-save-package-data: invalid option -- 'z'
Usage: abrt-action-save-package-data -d DIR [-vs]
Query package database and save package name, component,
and description
Options:
-d DIR Crash dump directory
-v Verbose
-s Log to syslog
This also allows for debugging and regression testing of
abrt-action-save-package-data - it can be simply run
from command-line.
Also it provides a better fault isolation - crash in
abrt-action-save-package-data does not take down abrtd.
Same goes for isolation of memory leaks - old code actually
had leaks on a rarely used error path. New code doesn't,
but if it would have, it wouldn't matter, since the process
is short-lived.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/daemon/Daemon.cpp | 3 | ||||
| -rw-r--r-- | src/daemon/Makefile.am | 29 | ||||
| -rw-r--r-- | src/daemon/MiddleWare.cpp | 274 | ||||
| -rw-r--r-- | src/daemon/MiddleWare.h | 8 | ||||
| -rw-r--r-- | src/daemon/abrt-action-save-package-data.cpp | 332 |
5 files changed, 383 insertions, 263 deletions
diff --git a/src/daemon/Daemon.cpp b/src/daemon/Daemon.cpp index b7024296..2564a82a 100644 --- a/src/daemon/Daemon.cpp +++ b/src/daemon/Daemon.cpp @@ -719,11 +719,8 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin case MW_IN_DB: log("Huh, this crash is already in db?! Nothing to do"); break; - case MW_BLACKLISTED: case MW_CORRUPTED: - case MW_PACKAGE_ERROR: case MW_GPG_ERROR: - case MW_FILE_ERROR: default: log("Corrupted or bad crash %s (res:%d), deleting", fullname, (int)res); delete_debug_dump_dir(fullname); diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index 3390dc04..4a8f179c 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -1,6 +1,9 @@ bin_SCRIPTS = abrt-debuginfo-install abrt-handle-upload -sbin_PROGRAMS = abrtd abrt-server abrt-action-generate-backtrace +sbin_PROGRAMS = abrtd \ + abrt-server \ + abrt-action-generate-backtrace \ + abrt-action-save-package-data abrtd_SOURCES = \ PluginManager.h PluginManager.cpp \ @@ -70,6 +73,30 @@ abrt_action_generate_backtrace_CPPFLAGS = \ abrt_action_generate_backtrace_LDADD = \ ../../lib/utils/libABRTUtils.la +abrt_action_save_package_data_SOURCES = \ + rpm.h rpm.c \ + Settings.h Settings.cpp \ + abrt-action-save-package-data.cpp +abrt_action_save_package_data_CPPFLAGS = \ + -I$(srcdir)/../../inc \ + -I$(srcdir)/../../lib/utils \ + -DBIN_DIR=\"$(bindir)\" \ + -DVAR_RUN=\"$(VAR_RUN)\" \ + -DCONF_DIR=\"$(CONF_DIR)\" \ + -DLOCALSTATEDIR='"$(localstatedir)"' \ + -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ + -DDEBUG_INFO_DIR=\"$(DEBUG_INFO_DIR)\" \ + -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ + -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ + $(GLIB_CFLAGS) \ + -D_GNU_SOURCE \ + -Wall -Werror +# polkit_check_authorization is in libABRTdUtils +abrt_action_save_package_data_LDADD = \ + $(RPM_LIBS) \ + ../../lib/utils/libABRTdUtils.la \ + ../../lib/utils/libABRTUtils.la + dbusabrtconfdir = ${sysconfdir}/dbus-1/system.d/ dist_dbusabrtconf_DATA = dbus-abrt.conf diff --git a/src/daemon/MiddleWare.cpp b/src/daemon/MiddleWare.cpp index b3f7ca8a..4ff83570 100644 --- a/src/daemon/MiddleWare.cpp +++ b/src/daemon/MiddleWare.cpp @@ -18,7 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include <fnmatch.h> #include <algorithm> /* for std::find */ #include "abrtlib.h" #include "Daemon.h" @@ -635,250 +634,38 @@ static bool is_debug_dump_saved(long uid, const char *debug_dump_dir) } /** - * Returns the first full path argument in the command line or NULL. - * Skips options are in form "-XXX". - * Caller must delete the returned string using free(). - */ -static char *get_argv1_if_full_path(const char* cmdline) -{ - const char *argv1 = strpbrk(cmdline, " \t"); - while (argv1 != NULL) - { - /* we found space in cmdline, so it might contain - * path to some script like: - * /usr/bin/python [-XXX] /usr/bin/system-control-network - */ - argv1++; /* skip the space */ - if (*argv1 == '-') /* skip arguments */ - { - /* looks like -XXX in "perl -XXX /usr/bin/script.pl", skip */ - argv1 = strpbrk(argv1, " \t"); - continue; - } - else if (*argv1 == ' ' || *argv1 == '\t') /* skip multiple spaces */ - continue; - else if (*argv1 != '/') - { - /* if the string following the space doesn't start - * with '/' it's probably not a full path to script - * and we can't use it to determine the package name - */ - break; - } - - /* cut the rest of cmdline arguments */ - int len = strchrnul(argv1, ' ') - argv1; - return xstrndup(argv1, len); - } - return NULL; -} - -static bool is_path_blacklisted(const char *path) -{ - set_string_t::iterator it = g_settings_setBlackListedPaths.begin(); - while (it != g_settings_setBlackListedPaths.end()) - { - if (fnmatch(it->c_str(), path, /*flags:*/ 0) == 0) - { - return true; - } - it++; - } - return false; -} - - -/** * Get a package name from executable name and save * package description to particular debugdump directory of a crash. * @param pExecutable A name of crashed application. * @param pDebugDumpDir A debugdump dir containing all necessary data. * @return It return results of operation. See mw_result_t. */ -static mw_result_t SavePackageDescriptionToDebugDump( - const char *pExecutable, - const char *cmdline, - bool remote, - const char *pDebugDumpDir) +static mw_result_t SavePackageDescriptionToDebugDump(const char *pDebugDumpDir) { - char* rpm_pkg = NULL; - char* packageName = NULL; - char* component = NULL; - std::string scriptName; /* only if "interpreter /path/to/script" */ - - if (strcmp(pExecutable, "kernel") == 0) + pid_t pid = fork(); + if (pid < 0) { - component = xstrdup("kernel"); - rpm_pkg = xstrdup("kernel"); - packageName = xstrdup("kernel"); - } - else - { - if (is_path_blacklisted(pExecutable)) - { - log("Blacklisted executable '%s'", pExecutable); - return MW_BLACKLISTED; - } - - rpm_pkg = rpm_get_package_nvr(pExecutable); - if (rpm_pkg == NULL) - { - if (g_settings_bProcessUnpackaged || remote) - { - VERB2 log("Crash in unpackaged executable '%s', proceeding without packaging information", pExecutable); - - struct dump_dir *dd = dd_init(); - if (!dd_opendir(dd, pDebugDumpDir, DD_CLOSE_ON_OPEN_ERR)) - return MW_ERROR; - - dd_save_text(dd, FILENAME_PACKAGE, ""); - dd_save_text(dd, FILENAME_COMPONENT, ""); - dd_save_text(dd, FILENAME_DESCRIPTION, "Crashed executable does not belong to any installed package"); - - dd_close(dd); - return MW_OK; - } - else - { - log("Executable '%s' doesn't belong to any package", pExecutable); - return MW_PACKAGE_ERROR; - } - } - - /* Check well-known interpreter names */ - - const char *basename = strrchr(pExecutable, '/'); - if (basename) basename++; else basename = pExecutable; - - /* Add more interpreters as needed */ - if (strcmp(basename, "python") == 0 - || strcmp(basename, "perl") == 0 - ) { -// TODO: we don't verify that python executable is not modified -// or that python package is properly signed -// (see CheckFingerprint/CheckHash below) - - /* Try to find package for the script by looking at argv[1]. - * This will work only if the cmdline contains the whole path. - * Example: python /usr/bin/system-control-network - */ - bool knownOrigin = false; - char *script_name = get_argv1_if_full_path(cmdline); - if (script_name) - { - char *script_pkg = rpm_get_package_nvr(script_name); - if (script_pkg) - { - /* There is a well-formed script name in argv[1], - * and it does belong to some package. - * Replace interpreter's rpm_pkg and pExecutable - * with data pertaining to the script. - */ - free(rpm_pkg); - rpm_pkg = script_pkg; - scriptName = script_name; - pExecutable = scriptName.c_str(); - knownOrigin = true; - /* pExecutable has changed, check it again */ - if (is_path_blacklisted(pExecutable)) - { - log("Blacklisted executable '%s'", pExecutable); - return MW_BLACKLISTED; - } - } - free(script_name); - } - - if (!knownOrigin && !g_settings_bProcessUnpackaged && !remote) - { - log("Interpreter crashed, but no packaged script detected: '%s'", cmdline); - return MW_PACKAGE_ERROR; - } - } - - packageName = get_package_name_from_NVR_or_NULL(rpm_pkg); - VERB2 log("Package:'%s' short:'%s'", rpm_pkg, packageName); - - if (g_settings_setBlackListedPkgs.find(packageName) != g_settings_setBlackListedPkgs.end()) - { - log("Blacklisted package '%s'", packageName); - free(packageName); - return MW_BLACKLISTED; - } - if (g_settings_bOpenGPGCheck && !remote) - { - if (rpm_chk_fingerprint(packageName)) - { - log("Package '%s' isn't signed with proper key", packageName); - free(packageName); - return MW_GPG_ERROR; - } - /* - Checking the MD5 sum requires to run prelink to "un-prelink" the - binaries - this is considered potential security risk so we don't - use it, until we find some non-intrusive way - - Delete? - */ - /* - if (!CheckHash(packageName.c_str(), pExecutable)) - { - error_msg("Executable '%s' seems to be modified, " - "doesn't match one from package '%s'", - pExecutable, packageName.c_str()); - return MW_GPG_ERROR; - } - */ - } - component = rpm_get_component(pExecutable); - } - - char *dsc = rpm_get_description(packageName); - free(packageName); - - char host[HOST_NAME_MAX + 1]; - if (!remote) - { - // HOST_NAME_MAX is defined in limits.h - int ret = gethostname(host, HOST_NAME_MAX); - host[HOST_NAME_MAX] = '\0'; - if (ret < 0) - { - perror_msg("gethostname"); - host[0] = '\0'; - } + perror_msg("fork"); + return MW_ERROR; } - - struct dump_dir *dd = dd_init(); - if (dd_opendir(dd, pDebugDumpDir, 0)) + if (pid == 0) /* child */ { - if (rpm_pkg) - { - dd_save_text(dd, FILENAME_PACKAGE, rpm_pkg); - free(rpm_pkg); - } - - if (dsc) - { - dd_save_text(dd, FILENAME_DESCRIPTION, dsc); - free(dsc); - } - - if (component) - { - dd_save_text(dd, FILENAME_COMPONENT, component); - free(component); - } - - if (!remote) - dd_save_text(dd, FILENAME_HOSTNAME, host); + char *argv[5]; /* abrt-action-save-package-data [-s] -d DIR NULL */ + char **pp = argv; + *pp++ = (char*)"abrt-action-save-package-data"; + if (logmode & LOGMODE_SYSLOG) + *pp++ = (char*)"-s"; + *pp++ = (char*)"-d"; + *pp++ = (char*)pDebugDumpDir; + *pp = NULL; - dd_close(dd); - return MW_OK; + execvp(argv[0], argv); + perror_msg_and_die("Can't execute '%s'", argv[0]); } - dd_close(dd); - - return MW_ERROR; + /* parent */ + int status; + waitpid(pid, &status, 0); + return (WIFEXITED(status) && WEXITSTATUS(status) == 0) ? MW_OK : MW_ERROR; } bool analyzer_has_InformAllUsers(const char *analyzer_name) @@ -1038,7 +825,6 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir, map_crash_data_t& pCrashData) { mw_result_t res; - int remote = 0; struct dump_dir *dd = dd_init(); if (!dd_opendir(dd, pDebugDumpDir, DD_CLOSE_ON_OPEN_ERR)) @@ -1047,14 +833,6 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir, char *time = dd_load_text(dd, FILENAME_TIME); char *uid = dd_load_text(dd, CD_UID); char *analyzer = dd_load_text(dd, FILENAME_ANALYZER); - char *executable = dd_load_text(dd, FILENAME_EXECUTABLE); - char *cmdline = dd_load_text(dd, FILENAME_CMDLINE); - - char *remote_str; - if (dd_exist(dd, FILENAME_REMOTE)) - remote_str = dd_load_text(dd, FILENAME_REMOTE); - else - remote_str = xstrdup(""); dd_close(dd); @@ -1077,14 +855,7 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir, goto error; } - if (remote_str[0]) - remote = remote_str[0] != '1'; - - res = SavePackageDescriptionToDebugDump(executable, - cmdline, - remote, - pDebugDumpDir - ); + res = SavePackageDescriptionToDebugDump(pDebugDumpDir); if (res != MW_OK) goto error; @@ -1107,10 +878,7 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir, } error: - free(remote_str); free(time); - free(executable); - free(cmdline); free(uid); free(analyzer); diff --git a/src/daemon/MiddleWare.h b/src/daemon/MiddleWare.h index 70bfd999..b132fb95 100644 --- a/src/daemon/MiddleWare.h +++ b/src/daemon/MiddleWare.h @@ -30,18 +30,14 @@ */ typedef enum { MW_OK, /**< No error.*/ + MW_OCCURRED, /**< A not-yet-reported dup.*/ + MW_REPORTED, /**< A reported dup.*/ MW_ERROR, /**< Common error.*/ - MW_BLACKLISTED, /**< Package is blacklisted.*/ MW_CORRUPTED, /**< Debugdump directory is corrupted.*/ - MW_PACKAGE_ERROR, /**< Cannot determine package name.*/ MW_GPG_ERROR, /**< Package is not signed properly.*/ - MW_REPORTED, /**< Crash is already reported.*/ - MW_OCCURRED, /**< Crash occurred in the past, but it is not reported yet.*/ MW_IN_DB, /**< Debugdump directory is already saved in a database.*/ MW_IN_DB_ERROR, /**< Error while working with a database.*/ MW_PLUGIN_ERROR, /**< plugin wasn't found or error within plugin*/ - MW_FILE_ERROR /**< Error when trying open debugdump directory or - when trying open file in debug dump directory..*/ } mw_result_t; typedef enum { diff --git a/src/daemon/abrt-action-save-package-data.cpp b/src/daemon/abrt-action-save-package-data.cpp new file mode 100644 index 00000000..bd18bc86 --- /dev/null +++ b/src/daemon/abrt-action-save-package-data.cpp @@ -0,0 +1,332 @@ +/* + 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 <fnmatch.h> +#include "abrtlib.h" +#include "abrt_packages.h" +#include "Settings.h" +#include "rpm.h" + + +/** + * Returns the first full path argument in the command line or NULL. + * Skips options are in form "-XXX". + * Caller must delete the returned string using free(). + */ +static char *get_argv1_if_full_path(const char* cmdline) +{ + const char *argv1 = strpbrk(cmdline, " \t"); + while (argv1 != NULL) + { + /* we found space in cmdline, so it might contain + * path to some script like: + * /usr/bin/python [-XXX] /usr/bin/system-control-network + */ + argv1++; /* skip the space */ + if (*argv1 == '-') + { + /* looks like -XXX in "perl -XXX /usr/bin/script.pl", skip */ + argv1 = strpbrk(argv1, " \t"); + continue; + } + if (*argv1 == ' ' || *argv1 == '\t') /* skip multiple spaces */ + continue; + if (*argv1 != '/') + { + /* if the string following the space doesn't start + * with '/' it's probably not a full path to script + * and we can't use it to determine the package name + */ + break; + } + + /* cut the rest of cmdline arguments */ + int len = strchrnul(argv1, ' ') - argv1; + return xstrndup(argv1, len); + } + return NULL; +} + +static bool is_path_blacklisted(const char *path) +{ + set_string_t::iterator it = g_settings_setBlackListedPaths.begin(); + while (it != g_settings_setBlackListedPaths.end()) + { + if (fnmatch(it->c_str(), path, /*flags:*/ 0) == 0) + { + return true; + } + it++; + } + return false; +} + +static int SavePackageDescriptionToDebugDump(const char *dump_dir_name) +{ + struct dump_dir *dd = dd_init(); + if (!dd_opendir(dd, dump_dir_name, DD_CLOSE_ON_OPEN_ERR)) + return 1; + + char *remote_str = dd_load_text(dd, FILENAME_REMOTE); + bool remote = (remote_str[0] == '1'); + free(remote_str); + + int error = 1; + char *executable = dd_load_text(dd, FILENAME_EXECUTABLE); + char *cmdline = dd_load_text(dd, FILENAME_CMDLINE); + char *package_full_name = NULL; + char *package_short_name = NULL; + char *component = NULL; + char *script_name = NULL; /* only if "interpreter /path/to/script" */ + char *dsc = NULL; + /* note: "goto ret" statements below free all the above variables, + * but they don't dd_close(dd) */ + + if (strcmp(executable, "kernel") == 0) + { + component = xstrdup("kernel"); + package_full_name = xstrdup("kernel"); + package_short_name = xstrdup("kernel"); + dsc = rpm_get_description(package_short_name); + } + else + { + /* Close dd while we query package database. It can take some time, + * don't want to keep dd locked longer than necessary */ + dd_close(dd); + + if (is_path_blacklisted(executable)) + { + log("Blacklisted executable '%s'", executable); + goto ret; /* return 1 (failure) */ + } + + package_full_name = rpm_get_package_nvr(executable); + if (!package_full_name) + { + if (g_settings_bProcessUnpackaged || remote) + { + VERB2 log("Crash in unpackaged executable '%s', proceeding without packaging information", executable); + dd = dd_init(); + if (!dd_opendir(dd, dump_dir_name, DD_CLOSE_ON_OPEN_ERR)) + goto ret; /* return 1 (failure) */ + dd_save_text(dd, FILENAME_PACKAGE, ""); + dd_save_text(dd, FILENAME_DESCRIPTION, "Crashed executable does not belong to any installed package"); + dd_save_text(dd, FILENAME_COMPONENT, ""); +//TODO: move hostname saving to a more logical place + if (!remote) + { + char host[HOST_NAME_MAX + 1]; + int ret = gethostname(host, HOST_NAME_MAX); + if (ret < 0) + { + perror_msg("gethostname"); + host[0] = '\0'; + } + host[HOST_NAME_MAX] = '\0'; + dd_save_text(dd, FILENAME_HOSTNAME, host); + } + goto ret0; /* no error */ + } + log("Executable '%s' doesn't belong to any package", executable); + goto ret; /* return 1 (failure) */ + } + + /* Check well-known interpreter names */ + { + const char *basename = strrchr(executable, '/'); + if (basename) basename++; else basename = executable; + + /* Add more interpreters as needed */ + if (strcmp(basename, "python") == 0 + || strcmp(basename, "perl") == 0 + ) { +// TODO: we don't verify that python executable is not modified +// or that python package is properly signed +// (see CheckFingerprint/CheckHash below) + /* Try to find package for the script by looking at argv[1]. + * This will work only if the cmdline contains the whole path. + * Example: python /usr/bin/system-control-network + */ + char *script_pkg = NULL; + char *script_name = get_argv1_if_full_path(cmdline); + if (script_name) + { + script_pkg = rpm_get_package_nvr(script_name); + if (script_pkg) + { + /* There is a well-formed script name in argv[1], + * and it does belong to some package. + * Replace interpreter's package_full_name and executable + * with data pertaining to the script. + */ + free(package_full_name); + package_full_name = script_pkg; + executable = script_name; + /* executable has changed, check it again */ + if (is_path_blacklisted(executable)) + { + log("Blacklisted executable '%s'", executable); + goto ret; /* return 1 (failure) */ + } + } + } + if (!script_pkg && !g_settings_bProcessUnpackaged && !remote) + { + log("Interpreter crashed, but no packaged script detected: '%s'", cmdline); + goto ret; /* return 1 (failure) */ + } + } + } + + package_short_name = get_package_name_from_NVR_or_NULL(package_full_name); + VERB2 log("Package:'%s' short:'%s'", package_full_name, package_short_name); + + if (g_settings_setBlackListedPkgs.find(package_short_name) != g_settings_setBlackListedPkgs.end()) + { + log("Blacklisted package '%s'", package_short_name); + goto ret; /* return 1 (failure) */ + } + if (g_settings_bOpenGPGCheck && !remote) + { + if (rpm_chk_fingerprint(package_short_name)) + { + log("Package '%s' isn't signed with proper key", package_short_name); + goto ret; /* return 1 (failure) */ + } + /* We used to also check the integrity of the executable here: + * if (!CheckHash(package_short_name.c_str(), executable)) BOOM(); + * Checking the MD5 sum requires to run prelink to "un-prelink" the + * binaries - this is considered potential security risk so we don't + * do it now, until we find some non-intrusive way. + */ + } + + component = rpm_get_component(executable); + dsc = rpm_get_description(package_short_name); + + dd = dd_init(); + if (!dd_opendir(dd, dump_dir_name, DD_CLOSE_ON_OPEN_ERR)) + goto ret; /* return 1 (failure) */ + } + + if (package_full_name) + { + dd_save_text(dd, FILENAME_PACKAGE, package_full_name); + } + if (dsc) + { + dd_save_text(dd, FILENAME_DESCRIPTION, dsc); + } + if (component) + { + dd_save_text(dd, FILENAME_COMPONENT, component); + } +//TODO: move hostname saving to a more logical place + if (!remote) + { + char host[HOST_NAME_MAX + 1]; + int ret = gethostname(host, HOST_NAME_MAX); + if (ret < 0) + { + perror_msg("gethostname"); + host[0] = '\0'; + } + host[HOST_NAME_MAX] = '\0'; + dd_save_text(dd, FILENAME_HOSTNAME, host); + } + + dd_close(dd); + + ret0: + error = 0; + ret: + free(package_full_name); + free(package_short_name); + free(component); + free(script_name); + free(dsc); + + return error; +} + +int main(int argc, char **argv) +{ + char *env_verbose = getenv("ABRT_VERBOSE"); + if (env_verbose) + g_verbose = atoi(env_verbose); + + const char *dump_dir_name = "."; + enum { + OPT_s = (1 << 0), + }; + int optflags = 0; + int opt; + while ((opt = getopt(argc, argv, "d:i:t:vs")) != -1) + { + switch (opt) + { + case 'd': + dump_dir_name = optarg; + break; + case 'v': + g_verbose++; + break; + case 's': + optflags |= OPT_s; + break; + default: + /* Careful: the string below contains tabs, dont replace with spaces */ + error_msg_and_die( + "Usage: abrt-action-save-package-data -d DIR [-vs]" + "\n" + "\nQuery package database and save package name, component, and description" + "\n" + "\nOptions:" + "\n -d DIR Crash dump directory" + "\n -v Verbose" + "\n -s Log to syslog" + ); + } + } + + putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose)); + msg_prefix = xasprintf("abrt-action-save-package-data[%u]", getpid()); + if (optflags & OPT_s) + { + openlog(msg_prefix, 0, LOG_DAEMON); + logmode = LOGMODE_SYSLOG; + } + + VERB1 log("Loading settings"); + if (LoadSettings() != 0) + return 1; /* syntax error (looged already by LoadSettings) */ + + VERB1 log("Initializing rpm library"); + rpm_init(); + + set_string_t::iterator it_k = g_settings_setOpenGPGPublicKeys.begin(); + for (; it_k != g_settings_setOpenGPGPublicKeys.end(); it_k++) + { + VERB1 log("Loading GPG key '%s'", it_k->c_str()); + rpm_load_gpgkey(it_k->c_str()); + } + + return SavePackageDescriptionToDebugDump(dump_dir_name); + /* can call rpm_destroy but do we really need to bother? we are exiting! */ +} |
