From 33431ebb9ace3fba76138198596f8155c2e14354 Mon Sep 17 00:00:00 2001
From: Glenn L McGrath <bug1@ihug.co.nz>
Date: Mon, 16 Apr 2001 04:52:19 +0000
Subject: dpkg improvements, use full package struct, avoid extracting to tmp
 dir, rename variable. deb_extract, untar and dpkg_deb modified to make the
 above possible

---
 libbb/deb_extract.c | 33 +++++++++++++++------------------
 libbb/libbb.h       |  9 ++++++---
 libbb/untar.c       | 42 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 59 insertions(+), 25 deletions(-)

(limited to 'libbb')

diff --git a/libbb/deb_extract.c b/libbb/deb_extract.c
index b95dfa4d4..36cebfa51 100644
--- a/libbb/deb_extract.c
+++ b/libbb/deb_extract.c
@@ -34,12 +34,13 @@
  * The contents of argument depend on the value of function.
  * It is either a dir name or a control file or field name(see dpkg_deb.c)
  */
-extern int deb_extract(const char *package_filename, int function, char *argument)
+extern char *deb_extract(const char *package_filename, const int function, const char *argument, const char *argument2)
 {
 
 	FILE *deb_file, *uncompressed_file;
 	ar_headers_t *headers = NULL;
 	char *ared_file = NULL;
+	char *output_buffer = NULL;
 	int gunzip_pid;
 
 	switch (function) {
@@ -61,7 +62,7 @@ extern int deb_extract(const char *package_filename, int function, char *argumen
 	/* get a linked list of all ar entries */
 	if ((headers = get_ar_headers(deb_file)) == NULL) {
 		error_msg("Couldnt get ar headers\n");
-		return(EXIT_FAILURE);
+		return(NULL);
 	}
 
 	/* seek to the start of the .tar.gz file within the ar file*/
@@ -75,27 +76,23 @@ extern int deb_extract(const char *package_filename, int function, char *argumen
 	if (function & extract_fsys_tarfile) {
 		copy_file_chunk(uncompressed_file, stdout, -1);
 	} else {
-		char *output_buffer = NULL;
-		output_buffer = untar(uncompressed_file, stdout, function, argument);
-		if (function & extract_field) {
-			char *field = NULL;
-			int field_length = 0;
-			int field_start = 0;
-			while ((field = read_package_field(&output_buffer[field_start])) != NULL) {
-				field_length = strlen(field);
-				field_start += (field_length + 1);
-				if (strstr(field, argument) == field) {
-					printf("%s\n", field + strlen(argument) + 2);
-				}
-				free(field);
-			}
+		FILE *output;
+
+		if (function & extract_contents_to_file) {
+			output = wfopen(argument, "w");
+		} else {
+			output = stdout;
 		}
-	}
 
+		output_buffer = untar(uncompressed_file, output, function, argument, argument2);
+		if (output != stdout) {
+			fclose(output);
+		}
+	}
 	gz_close(gunzip_pid);
 	fclose(deb_file);
 	fclose(uncompressed_file);
 	free(ared_file);
 
-	return(EXIT_SUCCESS);
+	return(output_buffer);
 }
\ No newline at end of file
diff --git a/libbb/libbb.h b/libbb/libbb.h
index 569ed9397..4b06ad12c 100644
--- a/libbb/libbb.h
+++ b/libbb/libbb.h
@@ -236,10 +236,13 @@ typedef enum extract_function_e {
 	extract_verbose_extract = 16,
 	extract_list = 32,
 	extract_fsys_tarfile = 64,
-	extract_field = 128
+	extract_field = 128,
+	extract_contents_to_file = 256
 } extract_function_t;
-extern int deb_extract(const char *package_filename, int function, char *target_dir);
-extern char *untar(FILE *src_tar_file, FILE *output, const int untar_function, const char *argument);
+extern char *deb_extract(const char *package_filename, const int function,
+	const char *argument, const char *argument2);
+extern char *untar(FILE *src_tar_file, FILE *output, const int untar_function,
+	const char *argument, const char *file_prefix);
 extern char *read_text_file_to_buffer(FILE *src_file);
 extern char *read_package_field(const char *package_buffer);
 
diff --git a/libbb/untar.c b/libbb/untar.c
index e70032c60..a77d94f61 100644
--- a/libbb/untar.c
+++ b/libbb/untar.c
@@ -22,7 +22,8 @@
 #include <unistd.h>
 #include "libbb.h"
 
-extern char *untar(FILE *src_tar_file, FILE *output, const int untar_function, const char *argument)
+extern char *untar(FILE *src_tar_file, FILE *output, const int untar_function,
+	const char *argument, const char *file_prefix)
 {
 	typedef struct raw_tar_header {
         char name[100];               /*   0-99 */
@@ -102,7 +103,21 @@ extern char *untar(FILE *src_tar_file, FILE *output, const int untar_function, c
 			next_header_offset += (512 - size % 512);
 		}
 
-		if (untar_function & (extract_contents | extract_verbose_extract)) {
+		/* If an exclude list is specified check current file against list 
+		if (*exclude_list != NULL) {
+			i = 0;
+			while (exclude_list[i] != 0) {
+				if (strncmp(exclude_list[i], raw_tar_header.name, strlen(raw_tar_header.name)) == 0) {
+					break;
+				}
+				i++;
+			}
+		if (exclude_list[i] != 0) {
+				continue;
+			}
+		} */
+
+		if (untar_function & (extract_contents | extract_verbose_extract | extract_contents_to_file)) {
 			fprintf(output, "%s\n", raw_tar_header.name);
 		}
 
@@ -123,10 +138,29 @@ extern char *untar(FILE *src_tar_file, FILE *output, const int untar_function, c
 						case (extract_extract):
 						case (extract_verbose_extract):
 						case (extract_control): {
-								FILE *dst_file = wfopen(dir, "w");
+								FILE *dst_file = NULL;
+								char *full_name;
+
+								if (file_prefix != NULL) {
+									char *file_name = NULL, *file_extension = NULL;
+
+									file_extension = xmalloc(strlen(raw_tar_header.name) + 1);
+									file_extension = strrchr(raw_tar_header.name, '/');
+									file_extension++;
+									file_name = xmalloc(strlen(file_prefix) + strlen(file_extension) + 2);
+									strcpy(file_name, file_prefix);
+									strcat(file_name, ".");
+									strcat(file_name, file_extension);
+
+									full_name = concat_path_file(strndup(dir, strlen(dir) - strlen(strrchr(dir, '/'))), file_name);
+								} else {
+									full_name = xstrdup(dir);
+								}
+								dst_file = wfopen(full_name, "w");
 								copy_file_chunk(src_tar_file, dst_file, (unsigned long long) size);
 								uncompressed_count += size;
 								fclose(dst_file);
+								chmod(full_name, mode);
 							}
 							break;
 						case (extract_info):
@@ -136,7 +170,7 @@ extern char *untar(FILE *src_tar_file, FILE *output, const int untar_function, c
 							}
 							break;
 						case (extract_field):
-							if (strstr(raw_tar_header.name, "control") != NULL) {
+							if (strstr(raw_tar_header.name, "./control") != NULL) {
 								return(read_text_file_to_buffer(src_tar_file));
 							}
 							break;
-- 
cgit v1.2.3-55-g6feb