Jakub Filak 776543
From 865f7b88b391f2fbd71baa1aa3d6320455d4f519 Mon Sep 17 00:00:00 2001
Jakub Filak 776543
From: Denys Vlasenko <dvlasenk@redhat.com>
Jakub Filak 776543
Date: Fri, 26 Apr 2013 17:33:17 +0200
Jakub Filak 776543
Subject: [ABRT PATCH 2/5] abrt-uefioops: new service
Jakub Filak 776543
Jakub Filak 776543
This service, once per boot, scans /sys/fs/pstore/* and crates
Jakub Filak 776543
oops problem dirs from this data.
Jakub Filak 776543
Jakub Filak 776543
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Jakub Filak 776543
Signed-off-by: Martin Milata <mmilata@redhat.com>
Jakub Filak 776543
---
Jakub Filak 776543
 Makefile.am                        |   6 +-
Jakub Filak 776543
 init-scripts/abrt-uefioops         |  79 ++++++++++++++++++++
Jakub Filak 776543
 init-scripts/abrt-uefioops.service |  12 +++
Jakub Filak 776543
 po/POTFILES.in                     |   4 +-
Jakub Filak 776543
 src/hooks/Makefile.am              |  37 +++++++++-
Jakub Filak 776543
 src/hooks/abrt-harvest-uefioops.in |  24 ++++++
Jakub Filak 776543
 src/hooks/abrt-merge-uefioops.c    | 148 +++++++++++++++++++++++++++++++++++++
Jakub Filak 776543
 7 files changed, 304 insertions(+), 6 deletions(-)
Jakub Filak 776543
 create mode 100644 init-scripts/abrt-uefioops
Jakub Filak 776543
 create mode 100644 init-scripts/abrt-uefioops.service
Jakub Filak 776543
 create mode 100644 src/hooks/abrt-harvest-uefioops.in
Jakub Filak 776543
 create mode 100644 src/hooks/abrt-merge-uefioops.c
Jakub Filak 776543
Jakub Filak 776543
diff --git a/Makefile.am b/Makefile.am
Jakub Filak 776543
index cc820ee..0eecc60 100644
Jakub Filak 776543
--- a/Makefile.am
Jakub Filak 776543
+++ b/Makefile.am
Jakub Filak 776543
@@ -34,14 +34,16 @@ if HAVE_SYSTEMD
Jakub Filak 776543
                                   init-scripts/abrt-ccpp.service \
Jakub Filak 776543
                                   init-scripts/abrt-oops.service \
Jakub Filak 776543
                                   init-scripts/abrt-xorg.service \
Jakub Filak 776543
-                                  init-scripts/abrt-vmcore.service
Jakub Filak 776543
+                                  init-scripts/abrt-vmcore.service \
Jakub Filak 776543
+                                  init-scripts/abrt-uefioops.service
Jakub Filak 776543
 else
Jakub Filak 776543
     sysv_initdir = $(sysconfdir)/rc.d/init.d/
Jakub Filak 776543
     sysv_init_SCRIPTS = init-scripts/abrtd \
Jakub Filak 776543
                         init-scripts/abrt-ccpp \
Jakub Filak 776543
                         init-scripts/abrt-oops \
Jakub Filak 776543
                         init-scripts/abrt-xorg \
Jakub Filak 776543
-                        init-scripts/abrt-vmcore
Jakub Filak 776543
+                        init-scripts/abrt-vmcore \
Jakub Filak 776543
+                        init-scripts/abrt-uefioops
Jakub Filak 776543
 endif
Jakub Filak 776543
 
Jakub Filak 776543
 RPM_DIRS = --define "_sourcedir `pwd`" \
Jakub Filak 776543
diff --git a/init-scripts/abrt-uefioops b/init-scripts/abrt-uefioops
Jakub Filak 776543
new file mode 100644
Jakub Filak 776543
index 0000000..663e24a
Jakub Filak 776543
--- /dev/null
Jakub Filak 776543
+++ b/init-scripts/abrt-uefioops
Jakub Filak 776543
@@ -0,0 +1,79 @@
Jakub Filak 776543
+#!/bin/bash
Jakub Filak 776543
+# Harvest UEFI-saved oopses for ABRT
Jakub Filak 776543
+#
Jakub Filak 776543
+# chkconfig: 35 82 16
Jakub Filak 776543
+# description: Collects UEFI-saved oopses for ABRT
Jakub Filak 776543
+### BEGIN INIT INFO
Jakub Filak 776543
+# Provides: abrt-uefioops
Jakub Filak 776543
+# Required-Start: $abrtd
Jakub Filak 776543
+# Default-Stop: 0 1 2 6
Jakub Filak 776543
+# Default-Start: 3 5
Jakub Filak 776543
+# Short-Description: Collects UEFI-saved oopses for ABRT
Jakub Filak 776543
+# Description: Collects UEFI-saved oopses for ABRT
Jakub Filak 776543
+### END INIT INFO
Jakub Filak 776543
+
Jakub Filak 776543
+# Source function library.
Jakub Filak 776543
+. /etc/rc.d/init.d/functions
Jakub Filak 776543
+
Jakub Filak 776543
+LOCK="/var/lock/subsys/abrt-uefioops"
Jakub Filak 776543
+HARVEST_CMD="/usr/sbin/abrt-harvest-uefioops"
Jakub Filak 776543
+
Jakub Filak 776543
+RETVAL=0
Jakub Filak 776543
+
Jakub Filak 776543
+check() {
Jakub Filak 776543
+	# Check that we're a privileged user
Jakub Filak 776543
+	[ "`id -u`" = 0 ] || exit 4
Jakub Filak 776543
+}
Jakub Filak 776543
+
Jakub Filak 776543
+start() {
Jakub Filak 776543
+	check
Jakub Filak 776543
+	"$HARVEST_CMD"
Jakub Filak 776543
+	RETVAL=$?
Jakub Filak 776543
+	[ $RETVAL -eq 0 ] && touch -- "$LOCK"
Jakub Filak 776543
+	return $RETVAL
Jakub Filak 776543
+}
Jakub Filak 776543
+
Jakub Filak 776543
+stop() {
Jakub Filak 776543
+	check
Jakub Filak 776543
+	rm -f -- "$LOCK"
Jakub Filak 776543
+	return 0
Jakub Filak 776543
+}
Jakub Filak 776543
+
Jakub Filak 776543
+restart() {
Jakub Filak 776543
+	stop
Jakub Filak 776543
+	start
Jakub Filak 776543
+}
Jakub Filak 776543
+
Jakub Filak 776543
+reload() {
Jakub Filak 776543
+	restart
Jakub Filak 776543
+}
Jakub Filak 776543
+
Jakub Filak 776543
+case "$1" in
Jakub Filak 776543
+start)
Jakub Filak 776543
+	start
Jakub Filak 776543
+	;;
Jakub Filak 776543
+stop)
Jakub Filak 776543
+	stop
Jakub Filak 776543
+	;;
Jakub Filak 776543
+reload)
Jakub Filak 776543
+	reload
Jakub Filak 776543
+	;;
Jakub Filak 776543
+force-reload)
Jakub Filak 776543
+	echo "$0: Unimplemented feature."
Jakub Filak 776543
+	RETVAL=3
Jakub Filak 776543
+	;;
Jakub Filak 776543
+restart)
Jakub Filak 776543
+	restart
Jakub Filak 776543
+	;;
Jakub Filak 776543
+condrestart)
Jakub Filak 776543
+	test -f "$LOCK" && restart
Jakub Filak 776543
+	;;
Jakub Filak 776543
+status)
Jakub Filak 776543
+	test -f "$LOCK" && RETVAL=0 || RETVAL=3
Jakub Filak 776543
+	;;
Jakub Filak 776543
+*)
Jakub Filak 776543
+	echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|force-reload}"
Jakub Filak 776543
+	RETVAL=2
Jakub Filak 776543
+esac
Jakub Filak 776543
+
Jakub Filak 776543
+exit $RETVAL
Jakub Filak 776543
diff --git a/init-scripts/abrt-uefioops.service b/init-scripts/abrt-uefioops.service
Jakub Filak 776543
new file mode 100644
Jakub Filak 776543
index 0000000..cee4296
Jakub Filak 776543
--- /dev/null
Jakub Filak 776543
+++ b/init-scripts/abrt-uefioops.service
Jakub Filak 776543
@@ -0,0 +1,12 @@
Jakub Filak 776543
+[Unit]
Jakub Filak 776543
+Description=Collect UEFI-saved oopses for ABRT
Jakub Filak 776543
+After=abrtd.service
Jakub Filak 776543
+Requisite=abrtd.service
Jakub Filak 776543
+
Jakub Filak 776543
+[Service]
Jakub Filak 776543
+Type=oneshot
Jakub Filak 776543
+ExecStart=/usr/sbin/abrt-harvest-uefioops
Jakub Filak 776543
+RemainAfterExit=yes
Jakub Filak 776543
+
Jakub Filak 776543
+[Install]
Jakub Filak 776543
+WantedBy=multi-user.target
Jakub Filak 776543
diff --git a/po/POTFILES.in b/po/POTFILES.in
Jakub Filak 776543
index b057a3d..26b595e 100644
Jakub Filak 776543
--- a/po/POTFILES.in
Jakub Filak 776543
+++ b/po/POTFILES.in
Jakub Filak 776543
@@ -35,13 +35,15 @@ src/plugins/collect_xsession_errors.xml.in
Jakub Filak 776543
 src/plugins/https-utils.c
Jakub Filak 776543
 src/plugins/bodhi.c
Jakub Filak 776543
 
Jakub Filak 776543
+src/hooks/abrt-merge-uefioops.c
Jakub Filak 776543
+
Jakub Filak 776543
 src/cli/abrt-cli.c
Jakub Filak 776543
 src/cli/list.c
Jakub Filak 776543
 src/cli/status.c
Jakub Filak 776543
+
Jakub Filak 776543
 src/plugins/analyze_CCpp.xml.in
Jakub Filak 776543
 src/plugins/analyze_VMcore.xml.in
Jakub Filak 776543
 src/plugins/collect_GConf.xml.in
Jakub Filak 776543
 src/plugins/collect_vimrc_system.xml.in
Jakub Filak 776543
 src/plugins/collect_vimrc_user.xml.in
Jakub Filak 776543
 src/plugins/post_report.xml.in
Jakub Filak 776543
-
Jakub Filak 776543
diff --git a/src/hooks/Makefile.am b/src/hooks/Makefile.am
Jakub Filak 776543
index 9f65d62..de97a88 100644
Jakub Filak 776543
--- a/src/hooks/Makefile.am
Jakub Filak 776543
+++ b/src/hooks/Makefile.am
Jakub Filak 776543
@@ -12,7 +12,11 @@ dist_pluginsconf_DATA = \
Jakub Filak 776543
 
Jakub Filak 776543
 sbin_SCRIPTS = \
Jakub Filak 776543
     abrt-install-ccpp-hook \
Jakub Filak 776543
-    abrt-harvest-vmcore
Jakub Filak 776543
+    abrt-harvest-vmcore \
Jakub Filak 776543
+    abrt-harvest-uefioops
Jakub Filak 776543
+
Jakub Filak 776543
+bin_PROGRAMS = \
Jakub Filak 776543
+    abrt-merge-uefioops
Jakub Filak 776543
 
Jakub Filak 776543
 libexec_PROGRAMS = abrt-hook-ccpp
Jakub Filak 776543
 
Jakub Filak 776543
@@ -32,10 +36,32 @@ abrt_hook_ccpp_LDADD = \
Jakub Filak 776543
     ../lib/libabrt.la \
Jakub Filak 776543
     $(LIBREPORT_LIBS)
Jakub Filak 776543
 
Jakub Filak 776543
-pyhook_PYTHON = abrt_exception_handler.py abrt.pth
Jakub Filak 776543
+# abrt-merge-uefioops
Jakub Filak 776543
+abrt_merge_uefioops_SOURCES = \
Jakub Filak 776543
+    abrt-merge-uefioops.c
Jakub Filak 776543
+abrt_merge_uefioops_CPPFLAGS = \
Jakub Filak 776543
+    -I$(srcdir)/../include \
Jakub Filak 776543
+    -I$(srcdir)/../lib \
Jakub Filak 776543
+    -DVAR_RUN=\"$(VAR_RUN)\" \
Jakub Filak 776543
+    -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
Jakub Filak 776543
+    -DDEFAULT_DUMP_DIR_MODE=$(DEFAULT_DUMP_DIR_MODE) \
Jakub Filak 776543
+    $(GLIB_CFLAGS) \
Jakub Filak 776543
+    $(LIBREPORT_CFLAGS) \
Jakub Filak 776543
+    -D_GNU_SOURCE
Jakub Filak 776543
+abrt_merge_uefioops_LDADD = \
Jakub Filak 776543
+    ../lib/libabrt.la \
Jakub Filak 776543
+    $(LIBREPORT_LIBS)
Jakub Filak 776543
+
Jakub Filak 776543
+DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
Jakub Filak 776543
+
Jakub Filak 776543
+pyhook_PYTHON = \
Jakub Filak 776543
+	abrt_exception_handler.py \
Jakub Filak 776543
+	abrt.pth
Jakub Filak 776543
+
Jakub Filak 776543
 EXTRA_DIST = abrt_exception_handler.py.in \
Jakub Filak 776543
 	abrt-install-ccpp-hook.in \
Jakub Filak 776543
-	abrt-harvest-vmcore.in
Jakub Filak 776543
+	abrt-harvest-vmcore.in \
Jakub Filak 776543
+	abrt-harvest-uefioops.in
Jakub Filak 776543
 
Jakub Filak 776543
 CLEANFILES := $(notdir $(wildcard *~)) $(notdir $(wildcard *\#)) $(notdir $(wildcard \.\#*)) $(notdir $(wildcard *.pyc)) $(man1_MANS)
Jakub Filak 776543
 
Jakub Filak 776543
@@ -63,3 +89,8 @@ abrt-harvest-vmcore: abrt-harvest-vmcore.in
Jakub Filak 776543
 	sed -e s,\@CONF_DIR\@,\$(CONF_DIR)\,g \
Jakub Filak 776543
 	    -e s,\@DEFAULT_DUMP_LOCATION\@,$(DEFAULT_DUMP_LOCATION),g \
Jakub Filak 776543
 		$< >$@
Jakub Filak 776543
+
Jakub Filak 776543
+abrt-harvest-uefioops: abrt-harvest-uefioops.in
Jakub Filak 776543
+	sed -e s,\@CONF_DIR\@,\$(CONF_DIR)\,g \
Jakub Filak 776543
+	    -e s,\@DEFAULT_DUMP_LOCATION\@,$(DEFAULT_DUMP_LOCATION),g \
Jakub Filak 776543
+		$< >$@
Jakub Filak 776543
diff --git a/src/hooks/abrt-harvest-uefioops.in b/src/hooks/abrt-harvest-uefioops.in
Jakub Filak 776543
new file mode 100644
Jakub Filak 776543
index 0000000..9f63256
Jakub Filak 776543
--- /dev/null
Jakub Filak 776543
+++ b/src/hooks/abrt-harvest-uefioops.in
Jakub Filak 776543
@@ -0,0 +1,24 @@
Jakub Filak 776543
+#!/bin/sh
Jakub Filak 776543
+#
Jakub Filak 776543
+# This script is meant to be run once at system startup after abrtd is up
Jakub Filak 776543
+# and running. It scans /sys/fs/pstore/*, reconstructs oops text(s)
Jakub Filak 776543
+# from these files, creates ABRT problem directories from them,
Jakub Filak 776543
+# then removes the files (UEFI storage is a limited resource).
Jakub Filak 776543
+#
Jakub Filak 776543
+
Jakub Filak 776543
+# Wait for abrtd to start. Give it at least 1 second to initialize.
Jakub Filak 776543
+i=10
Jakub Filak 776543
+while ! pidof abrtd >/dev/null; do
Jakub Filak 776543
+	if test $((i--)) = 0; then
Jakub Filak 776543
+		exit 1
Jakub Filak 776543
+	fi
Jakub Filak 776543
+	sleep 1
Jakub Filak 776543
+done
Jakub Filak 776543
+sleep 1
Jakub Filak 776543
+
Jakub Filak 776543
+cd /sys/fs/pstore 2>/dev/null || exit 0
Jakub Filak 776543
+
Jakub Filak 776543
+abrt-merge-uefioops -o * | abrt-dump-oops -D
Jakub Filak 776543
+if test $? = 0; then
Jakub Filak 776543
+	abrt-merge-uefioops -d *
Jakub Filak 776543
+fi
Jakub Filak 776543
diff --git a/src/hooks/abrt-merge-uefioops.c b/src/hooks/abrt-merge-uefioops.c
Jakub Filak 776543
new file mode 100644
Jakub Filak 776543
index 0000000..6fc3109
Jakub Filak 776543
--- /dev/null
Jakub Filak 776543
+++ b/src/hooks/abrt-merge-uefioops.c
Jakub Filak 776543
@@ -0,0 +1,148 @@
Jakub Filak 776543
+/*
Jakub Filak 776543
+    Copyright (C) 2013  Red Hat, Inc.
Jakub Filak 776543
+
Jakub Filak 776543
+    This program is free software; you can redistribute it and/or modify
Jakub Filak 776543
+    it under the terms of the GNU General Public License as published by
Jakub Filak 776543
+    the Free Software Foundation; either version 2 of the License, or
Jakub Filak 776543
+    (at your option) any later version.
Jakub Filak 776543
+
Jakub Filak 776543
+    This program is distributed in the hope that it will be useful,
Jakub Filak 776543
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
Jakub Filak 776543
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jakub Filak 776543
+    GNU General Public License for more details.
Jakub Filak 776543
+
Jakub Filak 776543
+    You should have received a copy of the GNU General Public License along
Jakub Filak 776543
+    with this program; if not, write to the Free Software Foundation, Inc.,
Jakub Filak 776543
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Jakub Filak 776543
+*/
Jakub Filak 776543
+#include "libabrt.h"
Jakub Filak 776543
+
Jakub Filak 776543
+struct oops_text {
Jakub Filak 776543
+    unsigned panic_no;
Jakub Filak 776543
+    unsigned part_no;
Jakub Filak 776543
+    const char *filename;
Jakub Filak 776543
+    char *text;
Jakub Filak 776543
+};
Jakub Filak 776543
+
Jakub Filak 776543
+static
Jakub Filak 776543
+struct oops_text *parse_file(const char *filename)
Jakub Filak 776543
+{
Jakub Filak 776543
+    FILE *fp = fopen(filename, "r");
Jakub Filak 776543
+    if (!fp)
Jakub Filak 776543
+        return NULL;
Jakub Filak 776543
+
Jakub Filak 776543
+    char buffer[16 * 1024];
Jakub Filak 776543
+
Jakub Filak 776543
+    struct oops_text *ot = NULL;
Jakub Filak 776543
+
Jakub Filak 776543
+    if (!fgets(buffer, sizeof(buffer), fp))
Jakub Filak 776543
+        goto ret;
Jakub Filak 776543
+    unsigned n1, n2;
Jakub Filak 776543
+    int n = sscanf(buffer, "Panic#%u Part%u\n", &n1, &n2;;
Jakub Filak 776543
+    if (n != 2)
Jakub Filak 776543
+        goto ret;
Jakub Filak 776543
+
Jakub Filak 776543
+    ot = xzalloc(sizeof(*ot));
Jakub Filak 776543
+    ot->filename = filename;
Jakub Filak 776543
+    ot->panic_no = n1;
Jakub Filak 776543
+    ot->part_no = n2;
Jakub Filak 776543
+
Jakub Filak 776543
+    size_t sz = fread(buffer, 1, sizeof(buffer), fp);
Jakub Filak 776543
+    ot->text = strndup(buffer, sz);
Jakub Filak 776543
+
Jakub Filak 776543
+ ret:
Jakub Filak 776543
+    fclose(fp);
Jakub Filak 776543
+    return ot;
Jakub Filak 776543
+}
Jakub Filak 776543
+
Jakub Filak 776543
+static
Jakub Filak 776543
+int compare_oops_texts(const void *a, const void *b)
Jakub Filak 776543
+{
Jakub Filak 776543
+    struct oops_text *aa = *(struct oops_text **)a;
Jakub Filak 776543
+    struct oops_text *bb = *(struct oops_text **)b;
Jakub Filak 776543
+    if (aa->panic_no < bb->panic_no)
Jakub Filak 776543
+        return -1;
Jakub Filak 776543
+    if (aa->panic_no > bb->panic_no)
Jakub Filak 776543
+        return 1;
Jakub Filak 776543
+    if (aa->part_no < bb->part_no)
Jakub Filak 776543
+        return -1;
Jakub Filak 776543
+    return (aa->part_no > bb->part_no);
Jakub Filak 776543
+}
Jakub Filak 776543
+
Jakub Filak 776543
+int main(int argc, char **argv)
Jakub Filak 776543
+{
Jakub Filak 776543
+    /* I18n */
Jakub Filak 776543
+    setlocale(LC_ALL, "");
Jakub Filak 776543
+#if ENABLE_NLS
Jakub Filak 776543
+    bindtextdomain(PACKAGE, LOCALEDIR);
Jakub Filak 776543
+    textdomain(PACKAGE);
Jakub Filak 776543
+#endif
Jakub Filak 776543
+
Jakub Filak 776543
+    abrt_init(argv);
Jakub Filak 776543
+
Jakub Filak 776543
+    /* Can't keep these strings/structs static: _() doesn't support that */
Jakub Filak 776543
+    const char *program_usage_string = _(
Jakub Filak 776543
+        "& [-v] [-od] FILE...\n"
Jakub Filak 776543
+        "\n"
Jakub Filak 776543
+        "Scans files for split oops message. Can print and/or delete them."
Jakub Filak 776543
+    );
Jakub Filak 776543
+    enum {
Jakub Filak 776543
+        OPT_v = 1 << 0,
Jakub Filak 776543
+        OPT_o = 1 << 1,
Jakub Filak 776543
+        OPT_d = 1 << 2,
Jakub Filak 776543
+    };
Jakub Filak 776543
+    /* Keep enum above and order of options below in sync! */
Jakub Filak 776543
+    struct options program_options[] = {
Jakub Filak 776543
+        OPT__VERBOSE(&g_verbose),
Jakub Filak 776543
+        OPT_BOOL('o', NULL, NULL, _("Print found oopses")),
Jakub Filak 776543
+        OPT_BOOL('d', NULL, NULL, _("Delete files with found oopses")),
Jakub Filak 776543
+        OPT_END()
Jakub Filak 776543
+    };
Jakub Filak 776543
+    unsigned opts = parse_opts(argc, argv, program_options, program_usage_string);
Jakub Filak 776543
+
Jakub Filak 776543
+    export_abrt_envvars(0);
Jakub Filak 776543
+
Jakub Filak 776543
+    struct oops_text **v = xzalloc(sizeof(v[0]));
Jakub Filak 776543
+    int i = 0;
Jakub Filak 776543
+
Jakub Filak 776543
+    while (*argv)
Jakub Filak 776543
+    {
Jakub Filak 776543
+        v[i] = parse_file(*argv);
Jakub Filak 776543
+        if (v[i])
Jakub Filak 776543
+        {
Jakub Filak 776543
+            v = xrealloc(v, (++i + 1) * sizeof(v[0]));
Jakub Filak 776543
+            v[i] = NULL;
Jakub Filak 776543
+        }
Jakub Filak 776543
+        argv++;
Jakub Filak 776543
+    }
Jakub Filak 776543
+
Jakub Filak 776543
+    if (i == 0) /* nothing was found */
Jakub Filak 776543
+        return 0;
Jakub Filak 776543
+
Jakub Filak 776543
+    qsort(v, i, sizeof(v[0]), compare_oops_texts);
Jakub Filak 776543
+
Jakub Filak 776543
+    if (opts & OPT_o)
Jakub Filak 776543
+    {
Jakub Filak 776543
+        struct oops_text **vv = v;
Jakub Filak 776543
+        while (*vv)
Jakub Filak 776543
+        {
Jakub Filak 776543
+            struct oops_text *cur_oops = *vv;
Jakub Filak 776543
+            fputs(cur_oops->text, stdout);
Jakub Filak 776543
+            vv++;
Jakub Filak 776543
+        }
Jakub Filak 776543
+    }
Jakub Filak 776543
+
Jakub Filak 776543
+    if (opts & OPT_d)
Jakub Filak 776543
+    {
Jakub Filak 776543
+        struct oops_text **vv = v;
Jakub Filak 776543
+        while (*vv)
Jakub Filak 776543
+        {
Jakub Filak 776543
+            struct oops_text *cur_oops = *vv;
Jakub Filak 776543
+            if (unlink(cur_oops->filename) != 0)
Jakub Filak 776543
+                perror_msg("Can't unlink '%s'", cur_oops->filename);
Jakub Filak 776543
+            vv++;
Jakub Filak 776543
+        }
Jakub Filak 776543
+    }
Jakub Filak 776543
+
Jakub Filak 776543
+    return 0;
Jakub Filak 776543
+}
Jakub Filak 776543
-- 
Jakub Filak 776543
1.8.1.4
Jakub Filak 776543