diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2001-04-11 16:23:35 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2001-04-11 16:23:35 +0000 |
commit | 4949faf4b2090ca23c2aeb34535fdbe57754913a (patch) | |
tree | b292a499341d3c0314283e2822a93241a1c4e1dd /libbb | |
parent | 5b20d02ea98c41bbd8a49cdbb84f425fa9ef446e (diff) | |
download | busybox-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.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 |
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 | */ |
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__ */ |