aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2001-04-11 16:23:35 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2001-04-11 16:23:35 +0000
commit4949faf4b2090ca23c2aeb34535fdbe57754913a (patch)
treeb292a499341d3c0314283e2822a93241a1c4e1dd /libbb
parent5b20d02ea98c41bbd8a49cdbb84f425fa9ef446e (diff)
downloadbusybox-w32-4949faf4b2090ca23c2aeb34535fdbe57754913a.tar.gz
busybox-w32-4949faf4b2090ca23c2aeb34535fdbe57754913a.tar.bz2
busybox-w32-4949faf4b2090ca23c2aeb34535fdbe57754913a.zip
copy_file_chunk uses streams now.
Diffstat (limited to 'libbb')
-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
5 files changed, 177 insertions, 188 deletions
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__ */