aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277>2001-04-11 16:23:35 +0000
committerbug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277>2001-04-11 16:23:35 +0000
commit72c0e1ee41ad693a5ff11137579eb7c2a39f4e22 (patch)
treeb292a499341d3c0314283e2822a93241a1c4e1dd
parentb4a1bdf087dcc1938cb93e5292512b7aa71fb569 (diff)
downloadbusybox-w32-72c0e1ee41ad693a5ff11137579eb7c2a39f4e22.tar.gz
busybox-w32-72c0e1ee41ad693a5ff11137579eb7c2a39f4e22.tar.bz2
busybox-w32-72c0e1ee41ad693a5ff11137579eb7c2a39f4e22.zip
copy_file_chunk uses streams now.
git-svn-id: svn://busybox.net/trunk/busybox@2315 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--Makefile20
-rw-r--r--ar.c36
-rw-r--r--archival/ar.c36
-rw-r--r--archival/dpkg.c34
-rw-r--r--archival/dpkg_deb.c2
-rw-r--r--cp_mv.c2
-rw-r--r--dpkg.c34
-rw-r--r--dpkg_deb.c2
-rw-r--r--include/libbb.h14
-rw-r--r--libbb/copy_file.c133
-rw-r--r--libbb/copy_file_chunk.c35
-rw-r--r--libbb/deb_extract.c113
-rw-r--r--libbb/get_ar_headers.c70
-rw-r--r--libbb/libbb.h14
14 files changed, 270 insertions, 275 deletions
diff --git a/Makefile b/Makefile
index d2a07fa8d..ed59deb0d 100644
--- a/Makefile
+++ b/Makefile
@@ -237,16 +237,16 @@ LIBBB = libbb
237LIBBB_LIB = libbb.a 237LIBBB_LIB = libbb.a
238LIBBB_CSRC= ask_confirmation.c check_wildcard_match.c chomp.c \ 238LIBBB_CSRC= ask_confirmation.c check_wildcard_match.c chomp.c \
239concat_path_file.c copy_file.c copy_file_chunk.c create_path.c daemon.c \ 239concat_path_file.c copy_file.c copy_file_chunk.c create_path.c daemon.c \
240deb_extract.c device_open.c error_msg.c error_msg_and_die.c \ 240deb_extract.c device_open.c error_msg.c error_msg_and_die.c find_mount_point.c \
241find_mount_point.c find_pid_by_name.c find_root_device.c full_read.c \ 241find_pid_by_name.c find_root_device.c full_read.c full_write.c \
242full_write.c get_ar_headers.c get_console.c get_last_path_component.c \ 242get_ar_headers.c get_console.c get_last_path_component.c get_line_from_file.c \
243get_line_from_file.c gz_open.c human_readable.c inode_hash.c \ 243gz_open.c human_readable.c inode_hash.c isdirectory.c kernel_version.c loop.c \
244isdirectory.c kernel_version.c loop.c mode_string.c module_syscalls.c mtab.c \ 244mode_string.c module_syscalls.c mtab.c mtab_file.c my_getgrnam.c my_getgrgid.c \
245mtab_file.c my_getgrnam.c my_getgrgid.c my_getpwnam.c my_getpwnamegid.c \ 245my_getpwnam.c my_getpwnamegid.c my_getpwuid.c parse_mode.c parse_number.c \
246my_getpwuid.c parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c \ 246perror_msg.c perror_msg_and_die.c print_file.c process_escape_sequence.c \
247print_file.c process_escape_sequence.c recursive_action.c safe_read.c \ 247recursive_action.c safe_read.c safe_strncpy.c seek_ared_file.c syscalls.c \
248safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c trim.c unzip.c \ 248syslog_msg_with_name.c time_string.c trim.c untar.c unzip.c vdprintf.c \
249vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c xgetcwd.c xregcomp.c 249verror_msg.c vperror_msg.c wfopen.c xfuncs.c xgetcwd.c xregcomp.c
250 250
251LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC)) 251LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC))
252LIBBB_CFLAGS = -I$(LIBBB) 252LIBBB_CFLAGS = -I$(LIBBB)
diff --git a/ar.c b/ar.c
index fbbc7aa64..8ab386821 100644
--- a/ar.c
+++ b/ar.c
@@ -36,12 +36,13 @@ extern int ar_main(int argc, char **argv)
36 const int extract_to_file = 8; /* extract contents of archive */ 36 const int extract_to_file = 8; /* extract contents of archive */
37 const int extract_to_stdout = 16; /* extract to stdout */ 37 const int extract_to_stdout = 16; /* extract to stdout */
38 38
39 FILE *src_file = NULL, *dst_file = NULL;
39 int funct = 0, opt=0; 40 int funct = 0, opt=0;
40 int srcFd=0, dstFd=0;
41 41
42 ar_headers_t head, *extract_list=NULL; 42 ar_headers_t *head, *extract_list=NULL;
43 43
44 extract_list = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); 44 extract_list = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
45 head = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
45 46
46 while ((opt = getopt(argc, argv, "ovtpx")) != -1) { 47 while ((opt = getopt(argc, argv, "ovtpx")) != -1) {
47 switch (opt) { 48 switch (opt) {
@@ -66,21 +67,22 @@ extern int ar_main(int argc, char **argv)
66 } 67 }
67 68
68 /* check the src filename was specified */ 69 /* check the src filename was specified */
69 if (optind == argc) 70 if (optind == argc) {
70 show_usage(); 71 show_usage();
71 72 }
72 if ( (srcFd = open(argv[optind], O_RDONLY)) < 0) 73
74 if ( (src_file = wfopen(argv[optind], "r")) < 0) {
73 error_msg_and_die("Cannot read %s", argv[optind]); 75 error_msg_and_die("Cannot read %s", argv[optind]);
76 }
74 77
75 optind++; 78 optind++;
76 head = get_ar_headers(srcFd); 79 head = get_ar_headers(src_file);
77
78 /* find files to extract or display */ 80 /* find files to extract or display */
79 /* search through argv and build extract list */ 81 /* search through argv and build extract list */
80 for (;optind<argc; optind++) { 82 for (;optind < argc; optind++) {
81 ar_headers_t *ar_entry; 83 ar_headers_t *ar_entry;
82 ar_entry = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); 84 ar_entry = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
83 ar_entry = &head; 85 ar_entry = head;
84 while (ar_entry->next != NULL) { 86 while (ar_entry->next != NULL) {
85 if (strcmp(argv[optind], ar_entry->name) == 0) { 87 if (strcmp(argv[optind], ar_entry->name) == 0) {
86 ar_headers_t *tmp; 88 ar_headers_t *tmp;
@@ -96,20 +98,20 @@ extern int ar_main(int argc, char **argv)
96 98
97 /* if individual files not found extract all files */ 99 /* if individual files not found extract all files */
98 if (extract_list->next==NULL) { 100 if (extract_list->next==NULL) {
99 extract_list = &head; 101 extract_list = head;
100 } 102 }
101 103
102 /* find files to extract or display */ 104 /* find files to extract or display */
103 while (extract_list->next != NULL) { 105 while (extract_list->next != NULL) {
104 if (funct & extract_to_file) { 106 if (funct & extract_to_file) {
105 dstFd = open(extract_list->name, O_WRONLY | O_CREAT, extract_list->mode); 107 dst_file = wfopen(extract_list->name, "w");
106 } 108 }
107 else if (funct & extract_to_stdout) { 109 else if (funct & extract_to_stdout) {
108 dstFd = fileno(stdout); 110 dst_file = stdout;
109 } 111 }
110 if ((funct & extract_to_file) || (funct & extract_to_stdout)) { 112 if ((funct & extract_to_file) || (funct & extract_to_stdout)) {
111 lseek(srcFd, extract_list->offset, SEEK_SET); 113 fseek(src_file, extract_list->offset, SEEK_SET);
112 copy_file_chunk(srcFd, dstFd, (off_t) extract_list->size); 114 copy_file_chunk(src_file, dst_file, (off_t) extract_list->size);
113 } 115 }
114 if (funct & verbose) { 116 if (funct & verbose) {
115 printf("%s %d/%d %8d %s ", mode_string(extract_list->mode), 117 printf("%s %d/%d %8d %s ", mode_string(extract_list->mode),
diff --git a/archival/ar.c b/archival/ar.c
index fbbc7aa64..8ab386821 100644
--- a/archival/ar.c
+++ b/archival/ar.c
@@ -36,12 +36,13 @@ extern int ar_main(int argc, char **argv)
36 const int extract_to_file = 8; /* extract contents of archive */ 36 const int extract_to_file = 8; /* extract contents of archive */
37 const int extract_to_stdout = 16; /* extract to stdout */ 37 const int extract_to_stdout = 16; /* extract to stdout */
38 38
39 FILE *src_file = NULL, *dst_file = NULL;
39 int funct = 0, opt=0; 40 int funct = 0, opt=0;
40 int srcFd=0, dstFd=0;
41 41
42 ar_headers_t head, *extract_list=NULL; 42 ar_headers_t *head, *extract_list=NULL;
43 43
44 extract_list = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); 44 extract_list = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
45 head = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
45 46
46 while ((opt = getopt(argc, argv, "ovtpx")) != -1) { 47 while ((opt = getopt(argc, argv, "ovtpx")) != -1) {
47 switch (opt) { 48 switch (opt) {
@@ -66,21 +67,22 @@ extern int ar_main(int argc, char **argv)
66 } 67 }
67 68
68 /* check the src filename was specified */ 69 /* check the src filename was specified */
69 if (optind == argc) 70 if (optind == argc) {
70 show_usage(); 71 show_usage();
71 72 }
72 if ( (srcFd = open(argv[optind], O_RDONLY)) < 0) 73
74 if ( (src_file = wfopen(argv[optind], "r")) < 0) {
73 error_msg_and_die("Cannot read %s", argv[optind]); 75 error_msg_and_die("Cannot read %s", argv[optind]);
76 }
74 77
75 optind++; 78 optind++;
76 head = get_ar_headers(srcFd); 79 head = get_ar_headers(src_file);
77
78 /* find files to extract or display */ 80 /* find files to extract or display */
79 /* search through argv and build extract list */ 81 /* search through argv and build extract list */
80 for (;optind<argc; optind++) { 82 for (;optind < argc; optind++) {
81 ar_headers_t *ar_entry; 83 ar_headers_t *ar_entry;
82 ar_entry = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); 84 ar_entry = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
83 ar_entry = &head; 85 ar_entry = head;
84 while (ar_entry->next != NULL) { 86 while (ar_entry->next != NULL) {
85 if (strcmp(argv[optind], ar_entry->name) == 0) { 87 if (strcmp(argv[optind], ar_entry->name) == 0) {
86 ar_headers_t *tmp; 88 ar_headers_t *tmp;
@@ -96,20 +98,20 @@ extern int ar_main(int argc, char **argv)
96 98
97 /* if individual files not found extract all files */ 99 /* if individual files not found extract all files */
98 if (extract_list->next==NULL) { 100 if (extract_list->next==NULL) {
99 extract_list = &head; 101 extract_list = head;
100 } 102 }
101 103
102 /* find files to extract or display */ 104 /* find files to extract or display */
103 while (extract_list->next != NULL) { 105 while (extract_list->next != NULL) {
104 if (funct & extract_to_file) { 106 if (funct & extract_to_file) {
105 dstFd = open(extract_list->name, O_WRONLY | O_CREAT, extract_list->mode); 107 dst_file = wfopen(extract_list->name, "w");
106 } 108 }
107 else if (funct & extract_to_stdout) { 109 else if (funct & extract_to_stdout) {
108 dstFd = fileno(stdout); 110 dst_file = stdout;
109 } 111 }
110 if ((funct & extract_to_file) || (funct & extract_to_stdout)) { 112 if ((funct & extract_to_file) || (funct & extract_to_stdout)) {
111 lseek(srcFd, extract_list->offset, SEEK_SET); 113 fseek(src_file, extract_list->offset, SEEK_SET);
112 copy_file_chunk(srcFd, dstFd, (off_t) extract_list->size); 114 copy_file_chunk(src_file, dst_file, (off_t) extract_list->size);
113 } 115 }
114 if (funct & verbose) { 116 if (funct & verbose) {
115 printf("%s %d/%d %8d %s ", mode_string(extract_list->mode), 117 printf("%s %d/%d %8d %s ", mode_string(extract_list->mode),
diff --git a/archival/dpkg.c b/archival/dpkg.c
index 55d97adda..d0728d995 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -565,8 +565,8 @@ static int dpkg_dounpack(package_t *pkg)
565 int r = 0, i; 565 int r = 0, i;
566 int status = TRUE; 566 int status = TRUE;
567 char *cwd = xgetcwd(0); 567 char *cwd = xgetcwd(0);
568 char *src_file = NULL; 568 char *src_filename = NULL;
569 char *dst_file = NULL; 569 char *dst_filename = NULL;
570// char *lst_file = NULL; 570// char *lst_file = NULL;
571 char *adminscripts[] = { "prerm", "postrm", "preinst", "postinst", 571 char *adminscripts[] = { "prerm", "postrm", "preinst", "postinst",
572 "conffiles", "md5sums", "shlibs", "templates" }; 572 "conffiles", "md5sums", "shlibs", "templates" };
@@ -576,37 +576,37 @@ static int dpkg_dounpack(package_t *pkg)
576 if(cwd==NULL) 576 if(cwd==NULL)
577 exit(EXIT_FAILURE); 577 exit(EXIT_FAILURE);
578 chdir("/"); 578 chdir("/");
579 deb_extract(dpkg_deb_extract, "/", pkg->file); 579 deb_extract(pkg->file, dpkg_deb_extract, "/");
580 580
581 /* Installs the package scripts into the info directory */ 581 /* Installs the package scripts into the info directory */
582 for (i = 0; i < sizeof(adminscripts) / sizeof(adminscripts[0]); i++) { 582 for (i = 0; i < sizeof(adminscripts) / sizeof(adminscripts[0]); i++) {
583 struct stat src_stat_buf; 583 struct stat src_stat_buf;
584 int src_fd = 0, dst_fd = 0; 584 FILE *src_file = NULL, *dst_file = NULL;
585 585
586 /* The full path of the current location of the admin file */ 586 /* The full path of the current location of the admin file */
587 src_file = xrealloc(src_file, strlen(dpkgcidir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1); 587 src_filename = xrealloc(src_filename, strlen(dpkgcidir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1);
588 sprintf(src_file, "%s%s/%s", dpkgcidir, pkg->package, adminscripts[i]); 588 sprintf(src_filename, "%s%s/%s", dpkgcidir, pkg->package, adminscripts[i]);
589 589
590 /* the full path of where we want the file to be copied to */ 590 /* the full path of where we want the file to be copied to */
591 dst_file = xrealloc(dst_file, strlen(infodir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1); 591 dst_filename = xrealloc(dst_filename, strlen(infodir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1);
592 sprintf(dst_file, "%s%s.%s", infodir, pkg->package, adminscripts[i]); 592 sprintf(dst_filename, "%s%s.%s", infodir, pkg->package, adminscripts[i]);
593 593
594 /* 594 /*
595 * copy admin file to permanent home 595 * copy admin file to permanent home
596 * NOTE: Maybe merge this behaviour into libb/copy_file.c 596 * NOTE: Maybe merge this behaviour into libb/copy_file.c
597 */ 597 */
598 if (lstat(src_file, &src_stat_buf) == 0) { 598 if (lstat(src_filename, &src_stat_buf) == 0) {
599 if ((src_fd = open(src_file, O_RDONLY)) != -1) { 599 if ((src_file = wfopen(src_filename, "r")) != NULL) {
600 if ((dst_fd = open(dst_file, O_WRONLY | O_CREAT, 0644)) == -1) { 600 if ((dst_file = wfopen(dst_filename, "w")) == NULL) {
601 status = FALSE; 601 status = FALSE;
602 perror_msg("Opening %s", dst_file); 602 perror_msg("Opening %s", dst_filename);
603 } 603 }
604 copy_file_chunk(src_fd, dst_fd, src_stat_buf.st_size); 604 copy_file_chunk(src_file, dst_file, src_stat_buf.st_size);
605 close(src_fd); 605 fclose(src_file);
606 close(dst_fd); 606 fclose(dst_file);
607 } else { 607 } else {
608 status = FALSE; 608 status = FALSE;
609 error_msg("couldnt open [%s]\n", src_file); 609 error_msg("couldnt open [%s]\n", src_filename);
610 } 610 }
611 } 611 }
612 } 612 }
@@ -671,7 +671,7 @@ static int dpkg_unpackcontrol(package_t *pkg)
671 strcat(tmp_name, pkg->package); 671 strcat(tmp_name, pkg->package);
672 672
673 /* extract control.tar.gz to the full extraction path */ 673 /* extract control.tar.gz to the full extraction path */
674 deb_extract(dpkg_deb_control, tmp_name, pkg->file); 674 deb_extract(pkg->file, dpkg_deb_control, tmp_name);
675 675
676 /* parse the extracted control file */ 676 /* parse the extracted control file */
677 strcat(tmp_name, "/control"); 677 strcat(tmp_name, "/control");
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c
index 450b04b8e..3cdd4ffae 100644
--- a/archival/dpkg_deb.c
+++ b/archival/dpkg_deb.c
@@ -68,7 +68,7 @@ extern int dpkg_deb_main(int argc, char **argv)
68 strcpy(target_dir, argv[optind + 1]); 68 strcpy(target_dir, argv[optind + 1]);
69 } 69 }
70 } 70 }
71 deb_extract(optflag, target_dir, argv[optind]); 71 deb_extract(argv[optind], optflag, target_dir);
72/* else if (optflag & dpkg_deb_info) { 72/* else if (optflag & dpkg_deb_info) {
73 extract_flag = TRUE; 73 extract_flag = TRUE;
74 extract_to_stdout = TRUE; 74 extract_to_stdout = TRUE;
diff --git a/cp_mv.c b/cp_mv.c
index f4b5cd0d6..3c19f1a04 100644
--- a/cp_mv.c
+++ b/cp_mv.c
@@ -147,7 +147,7 @@ cp_mv_Action(const char *fileName, struct stat *statbuf, void* junk)
147 add_to_ino_dev_hashtable(statbuf, destName); 147 add_to_ino_dev_hashtable(statbuf, destName);
148 } 148 }
149 } 149 }
150 return copy_file(fileName, destName, preserveFlag, followLinks, forceFlag); 150 return copy_file(fileName, destName, preserveFlag, followLinks, forceFlag, FALSE);
151} 151}
152 152
153static int 153static int
diff --git a/dpkg.c b/dpkg.c
index 55d97adda..d0728d995 100644
--- a/dpkg.c
+++ b/dpkg.c
@@ -565,8 +565,8 @@ static int dpkg_dounpack(package_t *pkg)
565 int r = 0, i; 565 int r = 0, i;
566 int status = TRUE; 566 int status = TRUE;
567 char *cwd = xgetcwd(0); 567 char *cwd = xgetcwd(0);
568 char *src_file = NULL; 568 char *src_filename = NULL;
569 char *dst_file = NULL; 569 char *dst_filename = NULL;
570// char *lst_file = NULL; 570// char *lst_file = NULL;
571 char *adminscripts[] = { "prerm", "postrm", "preinst", "postinst", 571 char *adminscripts[] = { "prerm", "postrm", "preinst", "postinst",
572 "conffiles", "md5sums", "shlibs", "templates" }; 572 "conffiles", "md5sums", "shlibs", "templates" };
@@ -576,37 +576,37 @@ static int dpkg_dounpack(package_t *pkg)
576 if(cwd==NULL) 576 if(cwd==NULL)
577 exit(EXIT_FAILURE); 577 exit(EXIT_FAILURE);
578 chdir("/"); 578 chdir("/");
579 deb_extract(dpkg_deb_extract, "/", pkg->file); 579 deb_extract(pkg->file, dpkg_deb_extract, "/");
580 580
581 /* Installs the package scripts into the info directory */ 581 /* Installs the package scripts into the info directory */
582 for (i = 0; i < sizeof(adminscripts) / sizeof(adminscripts[0]); i++) { 582 for (i = 0; i < sizeof(adminscripts) / sizeof(adminscripts[0]); i++) {
583 struct stat src_stat_buf; 583 struct stat src_stat_buf;
584 int src_fd = 0, dst_fd = 0; 584 FILE *src_file = NULL, *dst_file = NULL;
585 585
586 /* The full path of the current location of the admin file */ 586 /* The full path of the current location of the admin file */
587 src_file = xrealloc(src_file, strlen(dpkgcidir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1); 587 src_filename = xrealloc(src_filename, strlen(dpkgcidir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1);
588 sprintf(src_file, "%s%s/%s", dpkgcidir, pkg->package, adminscripts[i]); 588 sprintf(src_filename, "%s%s/%s", dpkgcidir, pkg->package, adminscripts[i]);
589 589
590 /* the full path of where we want the file to be copied to */ 590 /* the full path of where we want the file to be copied to */
591 dst_file = xrealloc(dst_file, strlen(infodir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1); 591 dst_filename = xrealloc(dst_filename, strlen(infodir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1);
592 sprintf(dst_file, "%s%s.%s", infodir, pkg->package, adminscripts[i]); 592 sprintf(dst_filename, "%s%s.%s", infodir, pkg->package, adminscripts[i]);
593 593
594 /* 594 /*
595 * copy admin file to permanent home 595 * copy admin file to permanent home
596 * NOTE: Maybe merge this behaviour into libb/copy_file.c 596 * NOTE: Maybe merge this behaviour into libb/copy_file.c
597 */ 597 */
598 if (lstat(src_file, &src_stat_buf) == 0) { 598 if (lstat(src_filename, &src_stat_buf) == 0) {
599 if ((src_fd = open(src_file, O_RDONLY)) != -1) { 599 if ((src_file = wfopen(src_filename, "r")) != NULL) {
600 if ((dst_fd = open(dst_file, O_WRONLY | O_CREAT, 0644)) == -1) { 600 if ((dst_file = wfopen(dst_filename, "w")) == NULL) {
601 status = FALSE; 601 status = FALSE;
602 perror_msg("Opening %s", dst_file); 602 perror_msg("Opening %s", dst_filename);
603 } 603 }
604 copy_file_chunk(src_fd, dst_fd, src_stat_buf.st_size); 604 copy_file_chunk(src_file, dst_file, src_stat_buf.st_size);
605 close(src_fd); 605 fclose(src_file);
606 close(dst_fd); 606 fclose(dst_file);
607 } else { 607 } else {
608 status = FALSE; 608 status = FALSE;
609 error_msg("couldnt open [%s]\n", src_file); 609 error_msg("couldnt open [%s]\n", src_filename);
610 } 610 }
611 } 611 }
612 } 612 }
@@ -671,7 +671,7 @@ static int dpkg_unpackcontrol(package_t *pkg)
671 strcat(tmp_name, pkg->package); 671 strcat(tmp_name, pkg->package);
672 672
673 /* extract control.tar.gz to the full extraction path */ 673 /* extract control.tar.gz to the full extraction path */
674 deb_extract(dpkg_deb_control, tmp_name, pkg->file); 674 deb_extract(pkg->file, dpkg_deb_control, tmp_name);
675 675
676 /* parse the extracted control file */ 676 /* parse the extracted control file */
677 strcat(tmp_name, "/control"); 677 strcat(tmp_name, "/control");
diff --git a/dpkg_deb.c b/dpkg_deb.c
index 450b04b8e..3cdd4ffae 100644
--- a/dpkg_deb.c
+++ b/dpkg_deb.c
@@ -68,7 +68,7 @@ extern int dpkg_deb_main(int argc, char **argv)
68 strcpy(target_dir, argv[optind + 1]); 68 strcpy(target_dir, argv[optind + 1]);
69 } 69 }
70 } 70 }
71 deb_extract(optflag, target_dir, argv[optind]); 71 deb_extract(argv[optind], optflag, target_dir);
72/* else if (optflag & dpkg_deb_info) { 72/* else if (optflag & dpkg_deb_info) {
73 extract_flag = TRUE; 73 extract_flag = TRUE;
74 extract_to_stdout = TRUE; 74 extract_to_stdout = TRUE;
diff --git a/include/libbb.h b/include/libbb.h
index 279b4e78b..54e852512 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -93,9 +93,9 @@ int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name);
93void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name); 93void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name);
94void reset_ino_dev_hashtable(void); 94void reset_ino_dev_hashtable(void);
95 95
96int copy_file(const char *srcName, const char *destName, 96int copy_file(const char *src_name, const char *dst_name,
97 int setModes, int followLinks, int forceFlag); 97 int set_modes, int follow_links, int force_flag, int quiet_flag);
98int copy_file_chunk(int srcFd, int dstFd, off_t remaining); 98int copy_file_chunk(FILE *src_file, FILE *dst_file, off_t chunksize);
99char *buildName(const char *dirName, const char *fileName); 99char *buildName(const char *dirName, const char *fileName);
100int makeString(int argc, const char **argv, char *buf, int bufLen); 100int makeString(int argc, const char **argv, char *buf, int bufLen);
101char *getChunk(int size); 101char *getChunk(int size);
@@ -225,10 +225,12 @@ typedef struct ar_headers_s {
225 off_t offset; 225 off_t offset;
226 struct ar_headers_s *next; 226 struct ar_headers_s *next;
227} ar_headers_t; 227} ar_headers_t;
228extern ar_headers_t get_ar_headers(int srcFd); 228extern ar_headers_t *get_ar_headers(FILE *in_file);
229extern int deb_extract(int optflags, const char *dir_name, const char *deb_filename); 229extern int seek_ared_file(FILE *in_file, ar_headers_t *headers, const char *tar_gz_file);
230 230extern int deb_extract(const char *package_filename, const int function, char *target_dir);
231extern int untar(FILE *src_tar_file, int untar_function, char *base_path);
231extern int unzip(FILE *l_in_file, FILE *l_out_file); 232extern int unzip(FILE *l_in_file, FILE *l_out_file);
232extern void gz_close(int gunzip_pid); 233extern void gz_close(int gunzip_pid);
233extern int gz_open(FILE *compressed_file, int *pid); 234extern int gz_open(FILE *compressed_file, int *pid);
235
234#endif /* __LIBBB_H__ */ 236#endif /* __LIBBB_H__ */
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index 64b65b9fa..eb9cb1a16 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -41,49 +41,54 @@
41 * -Erik Andersen 41 * -Erik Andersen
42 */ 42 */
43int 43int
44copy_file(const char *srcName, const char *destName, 44copy_file(const char *src_name, const char *dst_name,
45 int setModes, int followLinks, int forceFlag) 45 int set_modes, int follow_links, int force_flag, int quiet_flag)
46{ 46{
47 int rfd; 47 FILE *src_file = NULL;
48 int wfd; 48 FILE *dst_file = NULL;
49 int status;
50 struct stat srcStatBuf; 49 struct stat srcStatBuf;
51 struct stat dstStatBuf; 50 struct stat dstStatBuf;
52 struct utimbuf times; 51 struct utimbuf times;
52 int src_status;
53 int dst_status;
54
55 if (follow_links == TRUE) {
56 src_status = stat(src_name, &srcStatBuf);
57 dst_status = stat(dst_name, &dstStatBuf);
58 } else {
59 src_status = lstat(src_name, &srcStatBuf);
60 dst_status = lstat(dst_name, &dstStatBuf);
61 }
53 62
54 if (followLinks == TRUE) 63 if (src_status < 0) {
55 status = stat(srcName, &srcStatBuf); 64 if (!quiet_flag) {
56 else 65 perror_msg("%s", src_name);
57 status = lstat(srcName, &srcStatBuf); 66 }
58
59 if (status < 0) {
60 perror_msg("%s", srcName);
61 return FALSE; 67 return FALSE;
62 } 68 }
63 69
64 if (followLinks == TRUE) 70 if ((dst_status < 0) || force_flag) {
65 status = stat(destName, &dstStatBuf); 71 unlink(dst_name);
66 else
67 status = lstat(destName, &dstStatBuf);
68
69 if (status < 0 || forceFlag==TRUE) {
70 unlink(destName);
71 dstStatBuf.st_ino = -1; 72 dstStatBuf.st_ino = -1;
72 dstStatBuf.st_dev = -1; 73 dstStatBuf.st_dev = -1;
73 } 74 }
74 75
75 if ((srcStatBuf.st_dev == dstStatBuf.st_dev) && 76 if ((srcStatBuf.st_dev == dstStatBuf.st_dev) &&
76 (srcStatBuf.st_ino == dstStatBuf.st_ino)) { 77 (srcStatBuf.st_ino == dstStatBuf.st_ino)) {
77 error_msg("Copying file \"%s\" to itself", srcName); 78 if (!quiet_flag) {
79 error_msg("Copying file \"%s\" to itself", src_name);
80 }
78 return FALSE; 81 return FALSE;
79 } 82 }
80 83
81 if (S_ISDIR(srcStatBuf.st_mode)) { 84 if (S_ISDIR(srcStatBuf.st_mode)) {
82 //fprintf(stderr, "copying directory %s to %s\n", srcName, destName); 85 //fprintf(stderr, "copying directory %s to %s\n", srcName, destName);
83 /* Make sure the directory is writable */ 86 /* Make sure the directory is writable */
84 status = mkdir(destName, 0777777 ^ umask(0)); 87 dst_status = create_path(dst_name, 0777777 ^ umask(0));
85 if (status < 0 && errno != EEXIST) { 88 if ((dst_status < 0) && (errno != EEXIST)) {
86 perror_msg("%s", destName); 89 if (!quiet_flag) {
90 perror_msg("%s", dst_name);
91 }
87 return FALSE; 92 return FALSE;
88 } 93 }
89 } else if (S_ISLNK(srcStatBuf.st_mode)) { 94 } else if (S_ISLNK(srcStatBuf.st_mode)) {
@@ -92,80 +97,92 @@ copy_file(const char *srcName, const char *destName,
92 97
93 //fprintf(stderr, "copying link %s to %s\n", srcName, destName); 98 //fprintf(stderr, "copying link %s to %s\n", srcName, destName);
94 /* Warning: This could possibly truncate silently, to BUFSIZ chars */ 99 /* Warning: This could possibly truncate silently, to BUFSIZ chars */
95 link_size = readlink(srcName, &link_val[0], BUFSIZ); 100 link_size = readlink(src_name, &link_val[0], BUFSIZ);
96 if (link_size < 0) { 101 if (link_size < 0) {
97 perror_msg("%s", srcName); 102 if (quiet_flag) {
103 perror_msg("%s", src_name);
104 }
98 return FALSE; 105 return FALSE;
99 } 106 }
100 link_val[link_size] = '\0'; 107 link_val[link_size] = '\0';
101 status = symlink(link_val, destName); 108 src_status = symlink(link_val, dst_name);
102 if (status < 0) { 109 if (src_status < 0) {
103 perror_msg("%s", destName); 110 if (!quiet_flag) {
111 perror_msg("%s", dst_name);
112 }
104 return FALSE; 113 return FALSE;
105 } 114 }
106#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) 115#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
107 if (setModes == TRUE) { 116 if (set_modes == TRUE) {
108 /* Try to set owner, but fail silently like GNU cp */ 117 /* Try to set owner, but fail silently like GNU cp */
109 lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); 118 lchown(dst_name, srcStatBuf.st_uid, srcStatBuf.st_gid);
110 } 119 }
111#endif 120#endif
112 return TRUE; 121 return TRUE;
113 } else if (S_ISFIFO(srcStatBuf.st_mode)) { 122 } else if (S_ISFIFO(srcStatBuf.st_mode)) {
114 //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName); 123 //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName);
115 if (mkfifo(destName, 0644) < 0) { 124 if (mkfifo(dst_name, 0644) < 0) {
116 perror_msg("%s", destName); 125 if (!quiet_flag) {
126 perror_msg("%s", dst_name);
127 }
117 return FALSE; 128 return FALSE;
118 } 129 }
119 } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) 130 } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode)
120 || S_ISSOCK(srcStatBuf.st_mode)) { 131 || S_ISSOCK(srcStatBuf.st_mode)) {
121 //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName); 132 //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName);
122 if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) { 133 if (mknod(dst_name, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) {
123 perror_msg("%s", destName); 134 if (!quiet_flag) {
135 perror_msg("%s", dst_name);
136 }
124 return FALSE; 137 return FALSE;
125 } 138 }
126 } else if (S_ISREG(srcStatBuf.st_mode)) { 139 } else if (S_ISREG(srcStatBuf.st_mode)) {
127 //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName); 140 //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName);
128 rfd = open(srcName, O_RDONLY); 141 src_file = fopen(src_name, "r");
129 if (rfd < 0) { 142 if (src_file == NULL) {
130 perror_msg("%s", srcName); 143 if (!quiet_flag) {
144 perror_msg("%s", src_name);
145 }
131 return FALSE; 146 return FALSE;
132 } 147 }
133 148
134 wfd = open(destName, O_WRONLY | O_CREAT | O_TRUNC, 149 dst_file = fopen(dst_name, "w");
135 srcStatBuf.st_mode); 150 if (dst_file == NULL) {
136 if (wfd < 0) { 151 if (!quiet_flag) {
137 perror_msg("%s", destName); 152 perror_msg("%s", dst_name);
138 close(rfd); 153 }
154 fclose(src_file);
139 return FALSE; 155 return FALSE;
140 } 156 }
141 157
142 if (copy_file_chunk(rfd, wfd, srcStatBuf.st_size)==FALSE) 158 if (copy_file_chunk(src_file, dst_file, srcStatBuf.st_size)==FALSE) {
143 goto error_exit; 159 goto error_exit;
144 160 }
145 close(rfd); 161
146 if (close(wfd) < 0) { 162 fclose(src_file);
163 if (fclose(dst_file) < 0) {
147 return FALSE; 164 return FALSE;
148 } 165 }
149 } 166 }
150 167
151 if (setModes == TRUE) { 168 if (set_modes == TRUE) {
152 /* This is fine, since symlinks never get here */ 169 /* This is fine, since symlinks never get here */
153 if (chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) 170 if (chown(dst_name, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0)
154 perror_msg_and_die("%s", destName); 171 perror_msg("%s", dst_name);
155 if (chmod(destName, srcStatBuf.st_mode) < 0) 172 if (chmod(dst_name, srcStatBuf.st_mode) < 0)
156 perror_msg_and_die("%s", destName); 173 perror_msg("%s", dst_name);
157 times.actime = srcStatBuf.st_atime; 174 times.actime = srcStatBuf.st_atime;
158 times.modtime = srcStatBuf.st_mtime; 175 times.modtime = srcStatBuf.st_mtime;
159 if (utime(destName, &times) < 0) 176 if (utime(dst_name, &times) < 0)
160 perror_msg_and_die("%s", destName); 177 perror_msg("%s", dst_name);
161 } 178 }
162 179
163 return TRUE; 180 return TRUE;
164 181
165 error_exit: 182error_exit:
166 perror_msg("%s", destName); 183 perror_msg("%s", dst_name);
167 close(rfd); 184 fclose(src_file);
168 close(wfd); 185 fclose(dst_file);
169 186
170 return FALSE; 187 return FALSE;
171} 188}
diff --git a/libbb/copy_file_chunk.c b/libbb/copy_file_chunk.c
index bf0b06e1a..e887cbe9f 100644
--- a/libbb/copy_file_chunk.c
+++ b/libbb/copy_file_chunk.c
@@ -32,24 +32,29 @@
32/* 32/*
33 * Copy chunksize bytes between two file descriptors 33 * Copy chunksize bytes between two file descriptors
34 */ 34 */
35int copy_file_chunk(int srcfd, int dstfd, off_t chunksize) 35extern int copy_file_chunk(FILE *src_file, FILE *dst_file, off_t chunksize)
36{ 36{
37 off_t size; 37 off_t size, amount_written;
38 char buffer[BUFSIZ]; /* BUFSIZ is declared in stdio.h */ 38 char buffer[BUFSIZ]; /* BUFSIZ is declared in stdio.h */
39 39
40 while (chunksize > 0) { 40 clearerr(src_file);
41 if (chunksize > BUFSIZ) 41 clearerr(dst_file);
42 size = BUFSIZ; 42 while (chunksize > 0) {
43 else 43 if (chunksize > BUFSIZ) {
44 size = chunksize; 44 size = BUFSIZ;
45 if (full_write(dstfd, buffer, full_read(srcfd, buffer, size)) < size) 45 } else {
46 return(FALSE); 46 size = chunksize;
47 chunksize -= size; 47 }
48 } 48 amount_written = fwrite(buffer, 1, fread(buffer, 1, size, src_file), dst_file);
49 return (TRUE); 49 if (amount_written != size) {
50 error_msg("Couldnt write correct amount");
51 return(FALSE);
52 }
53 chunksize -= amount_written;
54 }
55 return (TRUE);
50} 56}
51 57
52
53/* END CODE */ 58/* END CODE */
54/* 59/*
55Local Variables: 60Local Variables:
diff --git a/libbb/deb_extract.c b/libbb/deb_extract.c
index 358c4d0a8..35ff99671 100644
--- a/libbb/deb_extract.c
+++ b/libbb/deb_extract.c
@@ -29,94 +29,53 @@
29#include <signal.h> 29#include <signal.h>
30#include "libbb.h" 30#include "libbb.h"
31 31
32/* From gunzip.c */ 32const int dpkg_deb_contents = 1;
33extern int gz_open(FILE *compressed_file, int *pid); 33const int dpkg_deb_control = 2;
34extern void gz_close(int gunzip_pid); 34const int dpkg_deb_info = 4;
35const int dpkg_deb_extract = 8;
36const int dpkg_deb_verbose_extract = 16;
37const int dpkg_deb_list = 32;
35 38
36extern int tar_unzip_init(int tarFd); 39extern int deb_extract(const char *package_filename, const int function, char *target_dir)
37extern int readTarFile(int tarFd, int extractFlag, int listFlag,
38 int tostdoutFlag, int verboseFlag, char** extractList, char** excludeList);
39
40extern int deb_extract(int optflags, const char *dir_name, const char *deb_filename)
41{ 40{
42 const int dpkg_deb_contents = 1;
43 const int dpkg_deb_control = 2;
44// const int dpkg_deb_info = 4;
45 const int dpkg_deb_extract = 8;
46 const int dpkg_deb_verbose_extract = 16;
47 const int dpkg_deb_list = 32;
48 41
49 char **extract_list = NULL; 42 FILE *deb_file, *uncompressed_file;
50 ar_headers_t *ar_headers = NULL; 43 ar_headers_t *headers = NULL;
51 char ar_filename[15]; 44 char *ared_file;
52 int extract_flag = FALSE; 45 int gunzip_pid;
53 int list_flag = FALSE;
54 int verbose_flag = FALSE;
55 int extract_to_stdout = FALSE;
56 int srcFd = 0;
57 int status;
58 pid_t pid;
59 FILE *comp_file = NULL;
60 46
61 if (dpkg_deb_contents == (dpkg_deb_contents & optflags)) { 47 if ((function == dpkg_deb_info) || (function == dpkg_deb_control)) {
62 strcpy(ar_filename, "data.tar.gz"); 48 ared_file = xstrdup("control.tar.gz");
63 verbose_flag = TRUE; 49 } else {
64 list_flag = TRUE; 50 ared_file = xstrdup("data.tar.gz");
65 }
66 if (dpkg_deb_list == (dpkg_deb_list & optflags)) {
67 strcpy(ar_filename, "data.tar.gz");
68 list_flag = TRUE;
69 }
70 if (dpkg_deb_control == (dpkg_deb_control & optflags)) {
71 strcpy(ar_filename, "control.tar.gz");
72 extract_flag = TRUE;
73 }
74 if (dpkg_deb_extract == (dpkg_deb_extract & optflags)) {
75 strcpy(ar_filename, "data.tar.gz");
76 extract_flag = TRUE;
77 }
78 if (dpkg_deb_verbose_extract == (dpkg_deb_verbose_extract & optflags)) {
79 strcpy(ar_filename, "data.tar.gz");
80 extract_flag = TRUE;
81 list_flag = TRUE;
82 } 51 }
83 52
84 ar_headers = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); 53 /* open the debian package to be worked on */
85 srcFd = open(deb_filename, O_RDONLY); 54 deb_file = wfopen(package_filename, "r");
55
56 headers = (ar_headers_t *) xmalloc(sizeof(ar_headers_t));
86 57
87 *ar_headers = get_ar_headers(srcFd); 58 /* get a linked list of all ar entries */
88 if (ar_headers->next == NULL) { 59 if ((headers = get_ar_headers(deb_file)) == NULL) {
89 error_msg_and_die("Couldnt find %s in %s", ar_filename, deb_filename); 60 error_msg("Couldnt get ar headers\n");
61 return(EXIT_FAILURE);
90 } 62 }
91 63
92 while (ar_headers->next != NULL) { 64 /* seek to the start of the .tar.gz file within the ar file*/
93 if (strcmp(ar_headers->name, ar_filename) == 0) { 65 if (seek_ared_file(deb_file, headers, ared_file) == EXIT_FAILURE) {
94 break; 66 error_msg("Couldnt seek to ar file");
95 }
96 ar_headers = ar_headers->next;
97 } 67 }
98 lseek(srcFd, ar_headers->offset, SEEK_SET); 68
99 /* Uncompress the file */ 69 /* open a stream of decompressed data */
100 comp_file = fdopen(srcFd, "r"); 70 uncompressed_file = fdopen(gz_open(deb_file, &gunzip_pid), "r");
101 if ((srcFd = gz_open(comp_file, &pid)) == EXIT_FAILURE) { 71
102 error_msg_and_die("Couldnt unzip file"); 72 /* get a list of all tar headers inside the .gz file */
103 } 73 untar(uncompressed_file, dpkg_deb_extract, target_dir);
104 if ( dir_name != NULL) {
105 if (is_directory(dir_name, TRUE, NULL)==FALSE) {
106 mkdir(dir_name, 0755);
107 }
108 if (chdir(dir_name)==-1) {
109 error_msg_and_die("Cannot change to dir %s", dir_name);
110 }
111 }
112 status = readTarFile(srcFd, extract_flag, list_flag,
113 extract_to_stdout, verbose_flag, NULL, extract_list);
114 74
115 /* we are deliberately terminating the child so we can safely ignore this */ 75 /* we are deliberately terminating the child so we can safely ignore this */
116 signal(SIGTERM, SIG_IGN); 76 signal(SIGTERM, SIG_IGN);
117 gz_close(pid); 77 gz_close(gunzip_pid);
118 close(srcFd); 78 fclose(deb_file);
119 fclose(comp_file); 79 fclose(uncompressed_file);
120 80 return(EXIT_SUCCESS);
121 return status;
122} \ No newline at end of file 81} \ No newline at end of file
diff --git a/libbb/get_ar_headers.c b/libbb/get_ar_headers.c
index cf7de5c2a..151caafe1 100644
--- a/libbb/get_ar_headers.c
+++ b/libbb/get_ar_headers.c
@@ -30,7 +30,7 @@
30#include <unistd.h> 30#include <unistd.h>
31#include "libbb.h" 31#include "libbb.h"
32 32
33extern ar_headers_t get_ar_headers(int srcFd) 33extern ar_headers_t *get_ar_headers(FILE *in_file)
34{ 34{
35 typedef struct raw_ar_header_s { /* Byte Offset */ 35 typedef struct raw_ar_header_s { /* Byte Offset */
36 char name[16]; /* 0-15 */ 36 char name[16]; /* 0-15 */
@@ -44,31 +44,33 @@ extern ar_headers_t get_ar_headers(int srcFd)
44 44
45 raw_ar_header_t raw_ar_header; 45 raw_ar_header_t raw_ar_header;
46 46
47 ar_headers_t *head, *entry; 47 ar_headers_t *ar_list, *ar_tmp, *ar_entry;
48 char ar_magic[8]; 48 char ar_magic[8];
49 char *long_name=NULL; 49 char *long_name=NULL;
50 50
51 head = (ar_headers_t *) xmalloc(sizeof(ar_headers_t));
52 entry = (ar_headers_t *) xmalloc(sizeof(ar_headers_t));
53
54 /* check ar magic */ 51 /* check ar magic */
55 if (full_read(srcFd, ar_magic, 8) != 8) { 52 if (fread(ar_magic, 1, 8, in_file) != 8) {
56 error_msg_and_die("cannot read magic"); 53 error_msg("cannot read magic");
54 return(NULL);
57 } 55 }
58 56
59 if (strncmp(ar_magic,"!<arch>",7) != 0) { 57 if (strncmp(ar_magic,"!<arch>",7) != 0) {
60 error_msg_and_die("invalid magic"); 58 error_msg("invalid magic");
59 return(NULL);
61 } 60 }
61
62 ar_list = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
62 63
63 while (full_read(srcFd, (char *) &raw_ar_header, 60)==60) { 64 while (fread((char *) &raw_ar_header, 1, 60, in_file) == 60) {
65 ar_entry = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
64 /* check the end of header markers are valid */ 66 /* check the end of header markers are valid */
65 if ((raw_ar_header.fmag[0]!='`') || (raw_ar_header.fmag[1]!='\n')) { 67 if ((raw_ar_header.fmag[0] != '`') || (raw_ar_header.fmag[1] != '\n')) {
66 char newline; 68 char newline;
67 if (raw_ar_header.fmag[1]!='`') { 69 if (raw_ar_header.fmag[1] != '`') {
68 break; 70 break;
69 } 71 }
70 /* some version of ar, have an extra '\n' after each entry */ 72 /* some version of ar, have an extra '\n' after each entry */
71 read(srcFd, &newline, 1); 73 fread(&newline, 1, 1, in_file);
72 if (newline!='\n') { 74 if (newline!='\n') {
73 break; 75 break;
74 } 76 }
@@ -77,42 +79,46 @@ extern ar_headers_t get_ar_headers(int srcFd)
77 /* dont worry about adding the last '\n', we dont need it now */ 79 /* dont worry about adding the last '\n', we dont need it now */
78 } 80 }
79 81
80 entry->size = (off_t) atoi(raw_ar_header.size); 82 ar_entry->size = (size_t) atoi(raw_ar_header.size);
81 /* long filenames have '/' as the first character */ 83 /* long filenames have '/' as the first character */
82 if (raw_ar_header.name[0] == '/') { 84 if (raw_ar_header.name[0] == '/') {
83 if (raw_ar_header.name[1] == '/') { 85 if (raw_ar_header.name[1] == '/') {
84 /* multiple long filenames are stored as data in one entry */ 86 /* multiple long filenames are stored as data in one entry */
85 long_name = (char *) xrealloc(long_name, entry->size); 87 long_name = (char *) xrealloc(long_name, ar_entry->size);
86 full_read(srcFd, long_name, entry->size); 88 fread(long_name, 1, ar_entry->size, in_file);
87 continue; 89 continue;
88 } 90 }
89 else { 91 else {
90 /* The number after the '/' indicates the offset in the ar data section 92 /* The number after the '/' indicates the offset in the ar data section
91 (saved in variable long_name) that conatains the real filename */ 93 (saved in variable long_name) that conatains the real filename */
92 const int long_name_offset = (int) atoi((char *) &raw_ar_header.name[1]); 94 const int long_name_offset = (int) atoi((char *) &raw_ar_header.name[1]);
93 entry->name = xmalloc(strlen(&long_name[long_name_offset])); 95 ar_entry->name = xmalloc(strlen(&long_name[long_name_offset]));
94 strcpy(entry->name, &long_name[long_name_offset]); 96 strcpy(ar_entry->name, &long_name[long_name_offset]);
95 } 97 }
96 } 98 }
97 else { 99 else {
98 /* short filenames */ 100 /* short filenames */
99 entry->name = xmalloc(16); 101 ar_entry->name = xmalloc(16);
100 strncpy(entry->name, raw_ar_header.name, 16); 102 ar_entry->name = strncpy(ar_entry->name, raw_ar_header.name, 16);
101 } 103 }
102 entry->name[strcspn(entry->name, " /")]='\0'; 104 ar_entry->name[strcspn(ar_entry->name, " /")]='\0';
103 105
104 /* convert the rest of the now valid char header to its typed struct */ 106 /* convert the rest of the now valid char header to its typed struct */
105 parse_mode(raw_ar_header.mode, &entry->mode); 107 parse_mode(raw_ar_header.mode, &ar_entry->mode);
106 entry->mtime = atoi(raw_ar_header.date); 108 ar_entry->mtime = atoi(raw_ar_header.date);
107 entry->uid = atoi(raw_ar_header.uid); 109 ar_entry->uid = atoi(raw_ar_header.uid);
108 entry->gid = atoi(raw_ar_header.gid); 110 ar_entry->gid = atoi(raw_ar_header.gid);
109 entry->offset = lseek(srcFd, 0, SEEK_CUR); 111 ar_entry->offset = ftell(in_file);
112 ar_entry->next = NULL;
110 113
111 /* add this entries header to our combined list */ 114 fseek(in_file, (off_t) ar_entry->size, SEEK_CUR);
112 entry->next = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); 115
113 *entry->next = *head; 116 ar_tmp = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
114 *head = *entry; 117 *ar_tmp = *ar_list;
115 lseek(srcFd, (off_t) entry->size, SEEK_CUR); 118 *ar_list = *ar_entry;
119 free(ar_entry);
120 ar_list->next = ar_tmp;
116 } 121 }
117 return(*head); 122
118} \ No newline at end of file 123 return(ar_list);
124}
diff --git a/libbb/libbb.h b/libbb/libbb.h
index 279b4e78b..54e852512 100644
--- a/libbb/libbb.h
+++ b/libbb/libbb.h
@@ -93,9 +93,9 @@ int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name);
93void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name); 93void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name);
94void reset_ino_dev_hashtable(void); 94void reset_ino_dev_hashtable(void);
95 95
96int copy_file(const char *srcName, const char *destName, 96int copy_file(const char *src_name, const char *dst_name,
97 int setModes, int followLinks, int forceFlag); 97 int set_modes, int follow_links, int force_flag, int quiet_flag);
98int copy_file_chunk(int srcFd, int dstFd, off_t remaining); 98int copy_file_chunk(FILE *src_file, FILE *dst_file, off_t chunksize);
99char *buildName(const char *dirName, const char *fileName); 99char *buildName(const char *dirName, const char *fileName);
100int makeString(int argc, const char **argv, char *buf, int bufLen); 100int makeString(int argc, const char **argv, char *buf, int bufLen);
101char *getChunk(int size); 101char *getChunk(int size);
@@ -225,10 +225,12 @@ typedef struct ar_headers_s {
225 off_t offset; 225 off_t offset;
226 struct ar_headers_s *next; 226 struct ar_headers_s *next;
227} ar_headers_t; 227} ar_headers_t;
228extern ar_headers_t get_ar_headers(int srcFd); 228extern ar_headers_t *get_ar_headers(FILE *in_file);
229extern int deb_extract(int optflags, const char *dir_name, const char *deb_filename); 229extern int seek_ared_file(FILE *in_file, ar_headers_t *headers, const char *tar_gz_file);
230 230extern int deb_extract(const char *package_filename, const int function, char *target_dir);
231extern int untar(FILE *src_tar_file, int untar_function, char *base_path);
231extern int unzip(FILE *l_in_file, FILE *l_out_file); 232extern int unzip(FILE *l_in_file, FILE *l_out_file);
232extern void gz_close(int gunzip_pid); 233extern void gz_close(int gunzip_pid);
233extern int gz_open(FILE *compressed_file, int *pid); 234extern int gz_open(FILE *compressed_file, int *pid);
235
234#endif /* __LIBBB_H__ */ 236#endif /* __LIBBB_H__ */