File crash-compressed-booted-kernel of Package crash

---
 defs.h    |    2 ++
 filesys.c |   45 +++++++++++++++++++++++++++++++++++----------
 symbols.c |   27 +++++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 10 deletions(-)

--- a/filesys.c
+++ b/filesys.c
@@ -523,6 +512,8 @@ static int
 find_booted_kernel(void)
 {
 	char kernel[BUFSIZE];
+	char kernel_unpacked[PATH_MAX];
+	char *realkernel;
 	char buffer[BUFSIZE];
 	char **searchdirs;
 	int i, preferred, wrapped;
@@ -552,7 +543,8 @@ find_booted_kernel(void)
 
         searchdirs = build_searchdirs(CREATE, &preferred);
 
-	for (i = preferred, wrapped = found = FALSE; !found; i++) { 
+	kernel_unpacked[0] = '\0';
+	for (i = preferred, wrapped = found = FALSE; !found; i++) {
 		if (!searchdirs[i]) {
 			if (preferred && !wrapped) {
 				wrapped = TRUE;
@@ -572,18 +564,37 @@ find_booted_kernel(void)
 			sprintf(kernel, "%s%s", searchdirs[i], dp->d_name);
 
 			if (mount_point(kernel) ||
-			    !file_readable(kernel) || 
-                            !is_elf_file(kernel))
+			    !file_readable(kernel))
 				continue;
 
+			kernel_unpacked[0] = '\0';
+			if (is_gzipped_elf_file(kernel)) {
+				realkernel = kernel_unpacked;
+				if (!uncompress_file(kernel, realkernel)) {
+					error(INFO,
+					      "Uncompression failed for %s\n",
+					      kernel);
+				}
+			} else
+				realkernel = kernel;
+
+			if (!is_elf_file(realkernel)) {
+				if (kernel_unpacked[0])
+					remove(kernel_unpacked);
+				continue;
+			}
+
 			if (CRASHDEBUG(1)) 
 				fprintf(fp, "find_booted_kernel: check: %s\n", 
 					kernel);
 
-			found = match_file_string(kernel, kt->proc_version, buffer);
+			found = match_file_string(realkernel, kt->proc_version, buffer);
 	
 			if (found)
 				break;
+
+			if (kernel_unpacked[0])
+				remove(kernel_unpacked);
 	        }
 		closedir(dirp);
 	}
@@ -592,20 +603,23 @@ find_booted_kernel(void)
 	build_searchdirs(DESTROY, NULL);
 
 	if (found) {
-                if ((pc->namelist = (char *)malloc
-		    (strlen(kernel)+1)) == NULL) 
+                if ((pc->orig_namelist = strdup(kernel)) == NULL)
+			error(FATAL, "booted kernel real name malloc: %s\n",
+				strerror(errno));
+                else if ((pc->namelist = strdup(realkernel)) == NULL) {
 			error(FATAL, "booted kernel name malloc: %s\n",
 				strerror(errno));
-                else {
-                        strcpy(pc->namelist, kernel);
+		} else {
 			if (CRASHDEBUG(1))
 				fprintf(fp, "find_booted_kernel: found: %s\n", 
-					pc->namelist);
-			pc->orig_namelist = pc->namelist;
+					pc->orig_namelist);
                         return TRUE;
                 }
 	}
 
+	if (kernel_unpacked[0])
+		remove(kernel_unpacked);
+
 	error(INFO, 
              "cannot find booted kernel -- please enter namelist argument\n\n");
 	return FALSE;
--- a/defs.h
+++ b/defs.h
@@ -3633,6 +3417,8 @@ void dump_symbol_table(void);
 void dump_struct_table(ulong);
 void dump_offset_table(char *, ulong);
 int is_elf_file(char *);
+int is_gzipped_elf_file(const char *file);
+int uncompress_file(const char *file, char *new_file);
 int is_kernel(char *);
 int is_kernel_uncompress(char *file, char *new_filename);
 int is_shared_object(char *);
--- a/symbols.c
+++ b/symbols.c
@@ -2834,6 +2643,33 @@ int is_gzip_file(const char *file)
 }
 
 /*
+ * Checks if the file is gzip-compressed and the compressed data contains
+ * the ELF magic number.
+ */
+int is_gzipped_elf_file(const char *file)
+{
+	gzFile f;
+	char magic[EI_NIDENT];
+
+	if (!is_gzip_file(file))
+		return FALSE;
+
+	if ((f = gzopen(file, "r")) == Z_NULL) {
+		error(INFO, "Cannot open %s: %s\n", file, strerror(errno));
+		return FALSE;
+	}
+	if (gzread(f, magic, EI_NIDENT) != EI_NIDENT) {
+                /* error(INFO, "%s: %s\n", s, strerror(errno)); */
+		gzclose(f);
+		return FALSE;
+	}
+	gzclose(f);
+
+	magic[EI_CLASS] = NULLCHAR;
+	return(STREQ(magic, ELFMAG));
+}
+
+/*
  * Uncompresses the given file. Saves the name of the new file in new_file.
  * Size of new_file must be large enough for PATH_MAX characters.
  *
openSUSE Build Service is sponsored by