diff options
author | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-04-11 16:23:35 +0000 |
---|---|---|
committer | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-04-11 16:23:35 +0000 |
commit | 72c0e1ee41ad693a5ff11137579eb7c2a39f4e22 (patch) | |
tree | b292a499341d3c0314283e2822a93241a1c4e1dd | |
parent | b4a1bdf087dcc1938cb93e5292512b7aa71fb569 (diff) | |
download | busybox-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-- | Makefile | 20 | ||||
-rw-r--r-- | ar.c | 36 | ||||
-rw-r--r-- | archival/ar.c | 36 | ||||
-rw-r--r-- | archival/dpkg.c | 34 | ||||
-rw-r--r-- | archival/dpkg_deb.c | 2 | ||||
-rw-r--r-- | cp_mv.c | 2 | ||||
-rw-r--r-- | dpkg.c | 34 | ||||
-rw-r--r-- | dpkg_deb.c | 2 | ||||
-rw-r--r-- | include/libbb.h | 14 | ||||
-rw-r--r-- | libbb/copy_file.c | 133 | ||||
-rw-r--r-- | libbb/copy_file_chunk.c | 35 | ||||
-rw-r--r-- | libbb/deb_extract.c | 113 | ||||
-rw-r--r-- | libbb/get_ar_headers.c | 70 | ||||
-rw-r--r-- | libbb/libbb.h | 14 |
14 files changed, 270 insertions, 275 deletions
@@ -237,16 +237,16 @@ LIBBB = libbb | |||
237 | LIBBB_LIB = libbb.a | 237 | LIBBB_LIB = libbb.a |
238 | LIBBB_CSRC= ask_confirmation.c check_wildcard_match.c chomp.c \ | 238 | LIBBB_CSRC= ask_confirmation.c check_wildcard_match.c chomp.c \ |
239 | concat_path_file.c copy_file.c copy_file_chunk.c create_path.c daemon.c \ | 239 | concat_path_file.c copy_file.c copy_file_chunk.c create_path.c daemon.c \ |
240 | deb_extract.c device_open.c error_msg.c error_msg_and_die.c \ | 240 | deb_extract.c device_open.c error_msg.c error_msg_and_die.c find_mount_point.c \ |
241 | find_mount_point.c find_pid_by_name.c find_root_device.c full_read.c \ | 241 | find_pid_by_name.c find_root_device.c full_read.c full_write.c \ |
242 | full_write.c get_ar_headers.c get_console.c get_last_path_component.c \ | 242 | get_ar_headers.c get_console.c get_last_path_component.c get_line_from_file.c \ |
243 | get_line_from_file.c gz_open.c human_readable.c inode_hash.c \ | 243 | gz_open.c human_readable.c inode_hash.c isdirectory.c kernel_version.c loop.c \ |
244 | isdirectory.c kernel_version.c loop.c mode_string.c module_syscalls.c mtab.c \ | 244 | mode_string.c module_syscalls.c mtab.c mtab_file.c my_getgrnam.c my_getgrgid.c \ |
245 | mtab_file.c my_getgrnam.c my_getgrgid.c my_getpwnam.c my_getpwnamegid.c \ | 245 | my_getpwnam.c my_getpwnamegid.c my_getpwuid.c parse_mode.c parse_number.c \ |
246 | my_getpwuid.c parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c \ | 246 | perror_msg.c perror_msg_and_die.c print_file.c process_escape_sequence.c \ |
247 | print_file.c process_escape_sequence.c recursive_action.c safe_read.c \ | 247 | recursive_action.c safe_read.c safe_strncpy.c seek_ared_file.c syscalls.c \ |
248 | safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c trim.c unzip.c \ | 248 | syslog_msg_with_name.c time_string.c trim.c untar.c unzip.c vdprintf.c \ |
249 | vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c xgetcwd.c xregcomp.c | 249 | verror_msg.c vperror_msg.c wfopen.c xfuncs.c xgetcwd.c xregcomp.c |
250 | 250 | ||
251 | LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC)) | 251 | LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC)) |
252 | LIBBB_CFLAGS = -I$(LIBBB) | 252 | LIBBB_CFLAGS = -I$(LIBBB) |
@@ -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; |
@@ -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 | ||
153 | static int | 153 | static int |
@@ -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); | |||
93 | void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name); | 93 | void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name); |
94 | void reset_ino_dev_hashtable(void); | 94 | void reset_ino_dev_hashtable(void); |
95 | 95 | ||
96 | int copy_file(const char *srcName, const char *destName, | 96 | int 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); |
98 | int copy_file_chunk(int srcFd, int dstFd, off_t remaining); | 98 | int copy_file_chunk(FILE *src_file, FILE *dst_file, off_t chunksize); |
99 | char *buildName(const char *dirName, const char *fileName); | 99 | char *buildName(const char *dirName, const char *fileName); |
100 | int makeString(int argc, const char **argv, char *buf, int bufLen); | 100 | int makeString(int argc, const char **argv, char *buf, int bufLen); |
101 | char *getChunk(int size); | 101 | char *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; |
228 | extern ar_headers_t get_ar_headers(int srcFd); | 228 | extern ar_headers_t *get_ar_headers(FILE *in_file); |
229 | extern int deb_extract(int optflags, const char *dir_name, const char *deb_filename); | 229 | extern int seek_ared_file(FILE *in_file, ar_headers_t *headers, const char *tar_gz_file); |
230 | 230 | extern int deb_extract(const char *package_filename, const int function, char *target_dir); | |
231 | extern int untar(FILE *src_tar_file, int untar_function, char *base_path); | ||
231 | extern int unzip(FILE *l_in_file, FILE *l_out_file); | 232 | extern int unzip(FILE *l_in_file, FILE *l_out_file); |
232 | extern void gz_close(int gunzip_pid); | 233 | extern void gz_close(int gunzip_pid); |
233 | extern int gz_open(FILE *compressed_file, int *pid); | 234 | extern 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 | */ |
43 | int | 43 | int |
44 | copy_file(const char *srcName, const char *destName, | 44 | copy_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, ×) < 0) | 176 | if (utime(dst_name, ×) < 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: | 182 | error_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 | */ |
35 | int copy_file_chunk(int srcfd, int dstfd, off_t chunksize) | 35 | extern 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 | /* |
55 | Local Variables: | 60 | Local 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 */ | 32 | const int dpkg_deb_contents = 1; |
33 | extern int gz_open(FILE *compressed_file, int *pid); | 33 | const int dpkg_deb_control = 2; |
34 | extern void gz_close(int gunzip_pid); | 34 | const int dpkg_deb_info = 4; |
35 | const int dpkg_deb_extract = 8; | ||
36 | const int dpkg_deb_verbose_extract = 16; | ||
37 | const int dpkg_deb_list = 32; | ||
35 | 38 | ||
36 | extern int tar_unzip_init(int tarFd); | 39 | extern int deb_extract(const char *package_filename, const int function, char *target_dir) |
37 | extern int readTarFile(int tarFd, int extractFlag, int listFlag, | ||
38 | int tostdoutFlag, int verboseFlag, char** extractList, char** excludeList); | ||
39 | |||
40 | extern 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 | ||
33 | extern ar_headers_t get_ar_headers(int srcFd) | 33 | extern 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); | |||
93 | void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name); | 93 | void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name); |
94 | void reset_ino_dev_hashtable(void); | 94 | void reset_ino_dev_hashtable(void); |
95 | 95 | ||
96 | int copy_file(const char *srcName, const char *destName, | 96 | int 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); |
98 | int copy_file_chunk(int srcFd, int dstFd, off_t remaining); | 98 | int copy_file_chunk(FILE *src_file, FILE *dst_file, off_t chunksize); |
99 | char *buildName(const char *dirName, const char *fileName); | 99 | char *buildName(const char *dirName, const char *fileName); |
100 | int makeString(int argc, const char **argv, char *buf, int bufLen); | 100 | int makeString(int argc, const char **argv, char *buf, int bufLen); |
101 | char *getChunk(int size); | 101 | char *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; |
228 | extern ar_headers_t get_ar_headers(int srcFd); | 228 | extern ar_headers_t *get_ar_headers(FILE *in_file); |
229 | extern int deb_extract(int optflags, const char *dir_name, const char *deb_filename); | 229 | extern int seek_ared_file(FILE *in_file, ar_headers_t *headers, const char *tar_gz_file); |
230 | 230 | extern int deb_extract(const char *package_filename, const int function, char *target_dir); | |
231 | extern int untar(FILE *src_tar_file, int untar_function, char *base_path); | ||
231 | extern int unzip(FILE *l_in_file, FILE *l_out_file); | 232 | extern int unzip(FILE *l_in_file, FILE *l_out_file); |
232 | extern void gz_close(int gunzip_pid); | 233 | extern void gz_close(int gunzip_pid); |
233 | extern int gz_open(FILE *compressed_file, int *pid); | 234 | extern int gz_open(FILE *compressed_file, int *pid); |
235 | |||
234 | #endif /* __LIBBB_H__ */ | 236 | #endif /* __LIBBB_H__ */ |