int load_abrt_conf() { free_abrt_conf_data(); map_string_t *settings = new_map_string(); if (!load_abrt_conf_file(ABRT_CONF, settings)) perror_msg("Can't load '%s'", ABRT_CONF); ParseCommon(settings, ABRT_CONF); free_map_string(settings); return 0; }
int cmd_report(int argc, const char **argv) { const char *program_usage_string = _( "& report [options] DIR..." ); enum { OPT_v = 1 << 0, OPT_d = 1 << 1, OPT_u = 1 << 2, }; struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_BOOL('d', "delete", NULL, _("Remove PROBLEM_DIR after reporting")), OPT_BOOL('u', "unsafe", NULL, _("Ignore security checks to be able to " "report all problems")), OPT_END() }; unsigned opts = parse_opts(argc, (char **)argv, program_options, program_usage_string); argv += optind; if (!argv[0]) show_usage_and_die(program_usage_string, program_options); export_abrt_envvars(/*prog_prefix:*/ 0); load_abrt_conf(); free_abrt_conf_data(); int report_flags = 0; if (opts & OPT_d) report_flags |= CMD_REPORT_REMOVE; if (opts & OPT_u) report_flags |= CMD_REPORT_UNSAFE; return _cmd_report(argv, report_flags); }
int main(int argc, char **argv) { /* I18n */ setlocale(LC_ALL, ""); #if ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif abrt_init(argv); /* Can't keep these strings/structs static: _() doesn't support that */ const char *program_usage_string = _( "& [options]" ); enum { OPT_v = 1 << 0, OPT_u = 1 << 1, OPT_s = 1 << 2, OPT_p = 1 << 3, }; /* Keep enum above and order of options below in sync! */ struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_INTEGER('u', NULL, &client_uid, _("Use NUM as client uid")), OPT_BOOL( 's', NULL, NULL , _("Log to syslog")), OPT_BOOL( 'p', NULL, NULL , _("Add program names to log")), OPT_END() }; unsigned opts = parse_opts(argc, argv, program_options, program_usage_string); export_abrt_envvars(opts & OPT_p); msg_prefix = xasprintf("%s[%u]", g_progname, getpid()); if (opts & OPT_s) { logmode = LOGMODE_JOURNAL; } /* Set up timeout handling */ /* Part 1 - need this to make SIGALRM interrupt syscalls * (as opposed to restarting them): I want read syscall to be interrupted */ struct sigaction sa; /* sa.sa_flags.SA_RESTART bit is clear: make signal interrupt syscalls */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = dummy_handler; /* pity, SIG_DFL won't do */ sigaction(SIGALRM, &sa, NULL); /* Part 2 - set the timeout per se */ alarm(TIMEOUT); if (client_uid == (uid_t)-1L) { /* Get uid of the connected client */ struct ucred cr; socklen_t crlen = sizeof(cr); if (0 != getsockopt(STDIN_FILENO, SOL_SOCKET, SO_PEERCRED, &cr, &crlen)) perror_msg_and_die("getsockopt(SO_PEERCRED)"); if (crlen != sizeof(cr)) error_msg_and_die("%s: bad crlen %d", "getsockopt(SO_PEERCRED)", (int)crlen); client_uid = cr.uid; } load_abrt_conf(); int r = perform_http_xact(); if (r == 0) r = 200; free_abrt_conf_data(); printf("HTTP/1.1 %u \r\n\r\n", r); return (r >= 400); /* Error if 400+ */ }
int main(int argc, char **argv) { /* I18n */ setlocale(LC_ALL, ""); #if ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif abrt_init(argv); /* Can't keep these strings/structs static: _() doesn't support that */ const char *program_usage_string = _( "& [-vsoxm] [-d DIR]/[-D] [FILE]\n" "\n" "Extract Xorg crash from FILE (or standard input)" ); /* Keep OPT_z enums and order of options below in sync! */ struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_BOOL( 's', NULL, NULL, _("Log to syslog")), OPT_BOOL( 'o', NULL, NULL, _("Print found crash data on standard output")), OPT_STRING('d', NULL, &debug_dumps_dir, "DIR", _("Create problem directory in DIR for every crash found")), OPT_BOOL( 'D', NULL, NULL, _("Same as -d DumpLocation, DumpLocation is specified in abrt.conf")), OPT_BOOL( 'x', NULL, NULL, _("Make the problem directory world readable")), OPT_BOOL( 'm', NULL, NULL, _("Print search string(s) to stdout and exit")), OPT_END() }; unsigned opts = g_opts = parse_opts(argc, argv, program_options, program_usage_string); export_abrt_envvars(0); msg_prefix = g_progname; if ((opts & OPT_s) || getenv("ABRT_SYSLOG")) { logmode = LOGMODE_JOURNAL; } if (opts & OPT_m) { puts("Backtrace"); return 0; } if (opts & OPT_D) { if (opts & OPT_d) show_usage_and_die(program_usage_string, program_options); load_abrt_conf(); debug_dumps_dir = g_settings_dump_location; g_settings_dump_location = NULL; free_abrt_conf_data(); } argv += optind; if (argv[0]) xmove_fd(xopen(argv[0], O_RDONLY), STDIN_FILENO); char *line; while ((line = xmalloc_fgetline(stdin)) != NULL) { char *p = skip_pfx(line); if (strcmp(p, "Backtrace:") == 0) { free(line); g_bt_count++; process_xorg_bt(); continue; } free(line); } /* If we are run by a log watcher, this delays log rescan * (because log watcher waits to us to terminate) * and possibly prevents dreaded "abrt storm". */ if (opts & (OPT_d|OPT_D)) { if (g_bt_count > MAX_DUMPED_DD_COUNT) sleep(g_bt_count - MAX_DUMPED_DD_COUNT); } return 0; }
int main(int argc, char **argv) { /* I18n */ setlocale(LC_ALL, ""); #if ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif abrt_init(argv); /* Can't keep these strings/structs static: _() doesn't support that */ const char *program_usage_string = _( "& [-vusoxm] [-d DIR]/[-D] [FILE]\n" "\n" "Extract oops from FILE (or standard input)" ); enum { OPT_v = 1 << 0, OPT_s = 1 << 1, OPT_o = 1 << 2, OPT_d = 1 << 3, OPT_D = 1 << 4, OPT_u = 1 << 5, OPT_x = 1 << 6, OPT_t = 1 << 7, OPT_m = 1 << 8, }; char *problem_dir = NULL; char *dump_location = NULL; /* Keep enum above and order of options below in sync! */ struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_BOOL( 's', NULL, NULL, _("Log to syslog")), OPT_BOOL( 'o', NULL, NULL, _("Print found oopses on standard output")), /* oopses don't contain any sensitive info, and even * the old koops app was showing the oopses to all users */ OPT_STRING('d', NULL, &dump_location, "DIR", _("Create new problem directory in DIR for every oops found")), OPT_BOOL( 'D', NULL, NULL, _("Same as -d DumpLocation, DumpLocation is specified in abrt.conf")), OPT_STRING('u', NULL, &problem_dir, "PROBLEM", _("Save the extracted information in PROBLEM")), OPT_BOOL( 'x', NULL, NULL, _("Make the problem directory world readable")), OPT_BOOL( 't', NULL, NULL, _("Throttle problem directory creation to 1 per second")), OPT_BOOL( 'm', NULL, NULL, _("Print search string(s) to stdout and exit")), OPT_END() }; unsigned opts = parse_opts(argc, argv, program_options, program_usage_string); export_abrt_envvars(0); msg_prefix = g_progname; if ((opts & OPT_s) || getenv("ABRT_SYSLOG")) { logmode = LOGMODE_JOURNAL; } if (opts & OPT_m) { char *oops_string_filter_regex = abrt_oops_string_filter_regex(); if (oops_string_filter_regex) { regex_t filter_re; if (regcomp(&filter_re, oops_string_filter_regex, REG_NOSUB) != 0) perror_msg_and_die(_("Failed to compile regex")); const regex_t *filter[] = { &filter_re, NULL }; koops_print_suspicious_strings_filtered(filter); regfree(&filter_re); free(oops_string_filter_regex); } else koops_print_suspicious_strings(); return 1; } if (opts & OPT_D) { if (opts & OPT_d) show_usage_and_die(program_usage_string, program_options); load_abrt_conf(); dump_location = g_settings_dump_location; g_settings_dump_location = NULL; free_abrt_conf_data(); } int oops_utils_flags = 0; if ((opts & OPT_x)) oops_utils_flags |= ABRT_OOPS_WORLD_READABLE; if ((opts & OPT_t)) oops_utils_flags |= ABRT_OOPS_THROTTLE_CREATION; if ((opts & OPT_o)) oops_utils_flags |= ABRT_OOPS_PRINT_STDOUT; argv += optind; if (argv[0]) xmove_fd(xopen(argv[0], O_RDONLY), STDIN_FILENO); GList *oops_list = NULL; scan_syslog_file(&oops_list, STDIN_FILENO); unsigned errors = 0; if (opts & OPT_u) { log_warning("Updating problem directory"); switch (g_list_length(oops_list)) { case 0: { error_msg(_("Can't update the problem: no oops found")); errors = 1; break; } default: { log_notice(_("More oopses found: process only the first one")); } /* falls trought */ case 1: { struct dump_dir *dd = dd_opendir(problem_dir, /*open for writing*/0); if (dd) { abrt_oops_save_data_in_dump_dir(dd, (char *)oops_list->data, /*no proc modules*/NULL); dd_close(dd); } } } } else errors = abrt_oops_process_list(oops_list, dump_location, ABRT_DUMP_OOPS_ANALYZER, oops_utils_flags); list_free_with_free(oops_list); //oops_list = NULL; return errors; }
int main(int argc, char** argv) { /* I18n */ setlocale(LC_ALL, ""); #if ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif abrt_init(argv); int parent_pid = getpid(); const char *program_usage_string = _( "& [options]" ); enum { OPT_v = 1 << 0, OPT_d = 1 << 1, OPT_s = 1 << 2, // TODO: get rid of -t NUM, it is no longer useful since dbus is moved to a separate tool OPT_t = 1 << 3, OPT_p = 1 << 4, }; /* Keep enum above and order of options below in sync! */ struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_BOOL( 'd', NULL, NULL , _("Do not daemonize")), OPT_BOOL( 's', NULL, NULL , _("Log to syslog even with -d")), OPT_INTEGER('t', NULL, &s_timeout, _("Exit after NUM seconds of inactivity")), OPT_BOOL( 'p', NULL, NULL , _("Add program names to log")), OPT_END() }; unsigned opts = parse_opts(argc, argv, program_options, program_usage_string); export_abrt_envvars(opts & OPT_p); #if 0 /* We no longer use dbus */ /* When dbus daemon starts us, it doesn't set PATH * (I saw it set only DBUS_STARTER_ADDRESS and DBUS_STARTER_BUS_TYPE). * In this case, set something sane: */ const char *env_path = getenv("PATH"); if (!env_path || !env_path[0]) putenv((char*)"PATH=/usr/sbin:/usr/bin:/sbin:/bin"); #endif unsetenv("ABRT_SYSLOG"); msg_prefix = g_progname; /* for log_warning(), error_msg() and such */ if (getuid() != 0) error_msg_and_die("Must be run as root"); if (opts & OPT_s) start_logging(); xpipe(s_signal_pipe); close_on_exec_on(s_signal_pipe[0]); close_on_exec_on(s_signal_pipe[1]); ndelay_on(s_signal_pipe[0]); /* I/O should not block - */ ndelay_on(s_signal_pipe[1]); /* especially writes! they happen in signal handler! */ signal(SIGTERM, handle_signal); signal(SIGINT, handle_signal); signal(SIGCHLD, handle_signal); GIOChannel* channel_signal = NULL; guint channel_id_signal_event = 0; bool pidfile_created = false; struct abrt_inotify_watch *aiw = NULL; int ret = 1; /* Initialization */ log_notice("Loading settings"); if (load_abrt_conf() != 0) goto init_error; /* Moved before daemonization because parent waits for signal from daemon * only for short period and time consumed by * mark_unprocessed_dump_dirs_not_reportable() is slightly unpredictable. */ sanitize_dump_dir_rights(); mark_unprocessed_dump_dirs_not_reportable(g_settings_dump_location); /* Daemonize unless -d */ if (!(opts & OPT_d)) { /* forking to background */ fflush(NULL); /* paranoia */ pid_t pid = fork(); if (pid < 0) { perror_msg_and_die("fork"); } if (pid > 0) { /* Parent */ /* Wait for child to notify us via SIGTERM that it feels ok */ int i = 20; /* 2 sec */ while (s_sig_caught == 0 && --i) { usleep(100 * 1000); } if (s_sig_caught == SIGTERM) { exit(0); } if (s_sig_caught) { error_msg_and_die("Failed to start: got sig %d", s_sig_caught); } error_msg_and_die("Failed to start: timeout waiting for child"); } /* Child (daemon) continues */ if (setsid() < 0) perror_msg_and_die("setsid"); if (g_verbose == 0 && logmode != LOGMODE_JOURNAL) start_logging(); } log_notice("Creating glib main loop"); s_main_loop = g_main_loop_new(NULL, FALSE); /* Watching 'g_settings_dump_location' for delete self * because hooks expects that the dump location exists if abrtd is running */ aiw = abrt_inotify_watch_init(g_settings_dump_location, IN_DUMP_LOCATION_FLAGS, handle_inotify_cb, /*user data*/NULL); /* Add an event source which waits for INT/TERM signal */ log_notice("Adding signal pipe watch to glib main loop"); channel_signal = abrt_gio_channel_unix_new(s_signal_pipe[0]); channel_id_signal_event = add_watch_or_die(channel_signal, G_IO_IN | G_IO_PRI | G_IO_HUP, handle_signal_cb); guint name_id = 0; /* Mark the territory */ log_notice("Creating pid file"); if (create_pidfile() != 0) goto init_error; pidfile_created = true; /* Open socket to receive new problem data (from python etc). */ dumpsocket_init(); /* Inform parent that we initialized ok */ if (!(opts & OPT_d)) { log_notice("Signalling parent"); kill(parent_pid, SIGTERM); if (logmode != LOGMODE_JOURNAL) start_logging(); } /* Only now we want signal pipe to work */ s_signal_pipe_write = s_signal_pipe[1]; /* Own a name on D-Bus */ name_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, ABRTD_DBUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL); start_idle_timeout(); /* Enter the event loop */ log_debug("Init complete, entering main loop"); g_main_loop_run(s_main_loop); ret = 0; /* Jump to exit */ goto cleanup; init_error: /* Initialization error */ error_msg("Error while initializing daemon"); /* Inform parent that initialization failed */ if (!(opts & OPT_d)) kill(parent_pid, SIGINT); cleanup: if (name_id > 0) g_bus_unown_name (name_id); /* Error or INT/TERM. Clean up, in reverse order. * Take care to not undo things we did not do. */ dumpsocket_shutdown(); if (pidfile_created) unlink(VAR_RUN_PIDFILE); if (channel_id_signal_event > 0) g_source_remove(channel_id_signal_event); if (channel_signal) g_io_channel_unref(channel_signal); abrt_inotify_watch_destroy(aiw); if (s_main_loop) g_main_loop_unref(s_main_loop); free_abrt_conf_data(); if (s_sig_caught && s_sig_caught != SIGCHLD) { /* We use TERM to stop abrtd, so not printing out error message. */ if (s_sig_caught != SIGTERM) { error_msg("Got signal %d, exiting", s_sig_caught); signal(s_sig_caught, SIG_DFL); raise(s_sig_caught); } } /* Exiting */ log_notice("Exiting"); return ret; }
int main(int argc, char **argv) { /* I18n */ setlocale(LC_ALL, ""); #if ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif abrt_init(argv); char *i_opt = NULL; /* Can't keep these strings/structs static: _() doesn't support that */ const char *program_usage_string = _( "& [options] -d DIR\n" "\n" "Analyzes coredump in problem directory DIR, generates and saves backtrace" ); enum { OPT_v = 1 << 0, OPT_d = 1 << 1, OPT_i = 1 << 2, OPT_t = 1 << 3, }; /* Keep enum above and order of options below in sync! */ struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_STRING( 'd', NULL, &dump_dir_name , "DIR" , _("Problem directory")), OPT_STRING( 'i', NULL, &i_opt , "DIR1[:DIR2]...", _("Additional debuginfo directories")), OPT_INTEGER('t', NULL, &exec_timeout_sec, _("Kill gdb if it runs for more than NUM seconds")), OPT_END() }; /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string); export_abrt_envvars(0); map_string_t *settings = new_map_string(); if (!load_abrt_plugin_conf_file(CCPP_CONF, settings)) error_msg("Can't load '%s'", CCPP_CONF); const char *value = get_map_string_item_or_NULL(settings, "DebuginfoLocation"); char *debuginfo_location; if (value) debuginfo_location = xstrdup(value); else debuginfo_location = xstrdup(LOCALSTATEDIR"/cache/abrt-di"); free_map_string(settings); char *debuginfo_dirs = NULL; if (i_opt) debuginfo_dirs = xasprintf("%s:%s", debuginfo_location, i_opt); /* Create gdb backtrace */ char *backtrace = get_backtrace(dump_dir_name, exec_timeout_sec, (debuginfo_dirs) ? debuginfo_dirs : debuginfo_location); free(debuginfo_location); if (!backtrace) { backtrace = xstrdup(""); log_warning("get_backtrace() returns NULL, broken core/gdb?"); } free(debuginfo_dirs); free_abrt_conf_data(); /* Store gdb backtrace */ struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); if (!dd) return 1; dd_save_text(dd, FILENAME_BACKTRACE, backtrace); dd_close(dd); /* Don't be completely silent. gdb run takes a few seconds, * it is useful to let user know it (maybe) worked. */ log_warning(_("Backtrace is generated and saved, %u bytes"), (int)strlen(backtrace)); free(backtrace); return 0; }
int main(int argc, char *argv[]) { /* I18n */ setlocale(LC_ALL, ""); #if ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif abrt_init(argv); /* Can't keep these strings/structs static: _() doesn't support that */ const char *program_usage_string_template = _( "& [-vsoxtf] [-e]/[-c CURSOR] [-d DIR]/[-D]\n" "\n" "Extract Xorg crash from systemd-journal\n" "\n" "-c and -e options conflicts because both specifies the first read message.\n" "\n" "-e is useful only for -f because the following of journal starts by reading \n" "the entire journal if the last seen possition is not available.\n" "\n" "The last seen position is saved in %s\n" "\n" "Journal filter is required parameter and must be specified either by parameter\n" "-j or in %s conf file.\n" ); char program_usage_string[strlen(program_usage_string_template) + strlen(ABRT_JOURNAL_XORG_WATCH_STATE_FILE) + strlen(XORG_CONF_PATH)]; sprintf(program_usage_string, program_usage_string_template, ABRT_JOURNAL_XORG_WATCH_STATE_FILE, XORG_CONF_PATH); enum { OPT_v = 1 << 0, OPT_s = 1 << 1, OPT_o = 1 << 2, OPT_d = 1 << 3, OPT_D = 1 << 4, OPT_x = 1 << 5, OPT_t = 1 << 6, OPT_c = 1 << 7, OPT_e = 1 << 8, OPT_f = 1 << 9, OPT_a = 1 << 10, OPT_J = 1 << 11, OPT_j = 1 << 12, }; char *cursor = NULL; char *dump_location = NULL; char *journal_dir = NULL; GList *journal_filters = NULL; /* Keep enum above and order of options below in sync! */ struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_BOOL( 's', NULL, NULL, _("Log to syslog")), OPT_BOOL( 'o', NULL, NULL, _("Print found crashes on standard output")), OPT_STRING('d', NULL, &dump_location, "DIR", _("Create new problem directory in DIR for every crash found")), OPT_BOOL( 'D', NULL, NULL, _("Same as -d DumpLocation, DumpLocation is specified in abrt.conf")), OPT_BOOL( 'x', NULL, NULL, _("Make the problem directory world readable")), OPT_BOOL( 't', NULL, NULL, _("Throttle problem directory creation to 1 per second")), OPT_STRING('c', NULL, &cursor, "CURSOR", _("Start reading systemd-journal from the CURSOR position")), OPT_BOOL( 'e', NULL, NULL, _("Start reading systemd-journal from the end")), OPT_BOOL( 'f', NULL, NULL, _("Follow systemd-journal from the last seen position (if available)")), OPT_BOOL( 'a', NULL, NULL, _("Read journal files from all machines")), OPT_STRING('J', NULL, &journal_dir, "PATH", _("Read all journal files from directory at PATH")), OPT_LIST( 'j', NULL, &journal_filters, "FILTER", _("Journal filter e.g. '_COMM=gdm-x-session' (may be given many times)")), OPT_END() }; unsigned opts = parse_opts(argc, argv, program_options, program_usage_string); export_abrt_envvars(0); msg_prefix = g_progname; if ((opts & OPT_s) || getenv("ABRT_SYSLOG")) { logmode = LOGMODE_JOURNAL; } if ((opts & OPT_c) && (opts & OPT_e)) error_msg_and_die(_("You need to specify either -c CURSOR or -e")); if (opts & OPT_D) { if (opts & OPT_d) show_usage_and_die(program_usage_string, program_options); load_abrt_conf(); dump_location = g_settings_dump_location; g_settings_dump_location = NULL; free_abrt_conf_data(); } int xorg_utils_flags = 0; if ((opts & OPT_x)) xorg_utils_flags |= ABRT_XORG_WORLD_READABLE; if ((opts & OPT_t)) xorg_utils_flags |= ABRT_XORG_THROTTLE_CREATION; if ((opts & OPT_o)) xorg_utils_flags |= ABRT_XORG_PRINT_STDOUT; /* get journal filters */ const char *const env_journal_filter = getenv("ABRT_DUMP_JOURNAL_XORG_DEBUG_FILTER"); bool free_filter_list_data = false; GList *xorg_journal_filter = NULL; if (env_journal_filter != NULL) { xorg_journal_filter = g_list_append(xorg_journal_filter, (gpointer)env_journal_filter); log_debug("Using journal filter from environment variable"); } else if (journal_filters != NULL) { xorg_journal_filter = journal_filters; log_debug("Using journal filter passed by parameter -j"); } else { map_string_t *settings = new_map_string(); log_notice("Loading settings from '%s'", XORG_CONF); load_abrt_plugin_conf_file(XORG_CONF, settings); log_debug("Loaded '%s'", XORG_CONF); const char *conf_journal_filters = get_map_string_item_or_NULL(settings, "JournalFilters"); xorg_journal_filter = parse_list(conf_journal_filters); /* list data will be free by g_list_free_full */ free_filter_list_data = true; free_map_string(settings); if (xorg_journal_filter) log_debug("Using journal filter from conf file %s", XORG_CONF); } if (xorg_journal_filter == NULL) error_msg_and_die(_("Journal filter must be specified either by parameter -j or stored in /etc/abrt/plugins/xorg.conf file")); abrt_journal_t *journal = NULL; if ((opts & OPT_J)) { log_debug("Using journal files from directory '%s'", journal_dir); if (abrt_journal_open_directory(&journal, journal_dir)) error_msg_and_die(_("Cannot initialize systemd-journal in directory '%s'"), journal_dir); } else { if (((opts & OPT_a) ? abrt_journal_new_merged : abrt_journal_new)(&journal)) error_msg_and_die(_("Cannot open systemd-journal")); } if (abrt_journal_set_journal_filter(journal, xorg_journal_filter) < 0) error_msg_and_die(_("Cannot filter systemd-journal to Xorg data only")); /* free filter list */ if (free_filter_list_data) g_list_free_full(xorg_journal_filter, free); else g_list_free(xorg_journal_filter); if ((opts & OPT_e) && abrt_journal_seek_tail(journal) < 0) error_msg_and_die(_("Cannot seek to the end of journal")); if ((opts & OPT_f)) { if (!cursor) abrt_journal_restore_position(journal, ABRT_JOURNAL_XORG_WATCH_STATE_FILE); else if(abrt_journal_set_cursor(journal, cursor)) error_msg_and_die(_("Failed to start watch from cursor '%s'"), cursor); watch_journald(journal, dump_location, xorg_utils_flags); abrt_journal_save_current_position(journal, ABRT_JOURNAL_XORG_WATCH_STATE_FILE); } else { if (cursor && abrt_journal_set_cursor(journal, cursor)) error_msg_and_die(_("Failed to set systemd-journal cursor '%s'"), cursor); /* Compatibility hack, a watch's callback gets the journal already moved * to a next message.*/ abrt_journal_next(journal); GList *crashes = abrt_journal_extract_xorg_crashes(journal); abrt_xorg_process_list_of_crashes(crashes, dump_location, xorg_utils_flags); g_list_free_full(crashes, (GDestroyNotify)xorg_crash_info_free); } abrt_journal_free(journal); return EXIT_SUCCESS; }