Line 162... |
Line 162... |
162 |
}
|
162 |
}
|
163 |
|
163 |
|
164 |
|
164 |
|
165 |
|
165 |
|
166 |
/* unzips a file. zipfd points to the open zip file, curzipnode to the entry to extract, and fulldestfilename is the destination file where to unzip it. returns 0 on success, non-zero otherwise. */
|
166 |
/* unzips a file. zipfd points to the open zip file, curzipnode to the entry to extract, and fulldestfilename is the destination file where to unzip it. returns 0 on success, non-zero otherwise. */
|
167 |
int zip_unzip(FILE *zipfd, struct ziplist *curzipnode, const char *fulldestfilename) {
|
167 |
int zip_unzip(FILE *zipfd, struct ziplist *curzipnode, const char *fulldestfilename, unsigned char *buff15k) {
|
168 |
#define buffsize (12 * 1024) /* bigger buffer is better, but pkg has to work on a 256K PC so let's not get too crazy with RAM */
|
168 |
#define buffsize (15 * 1024) /* bigger buffer is better, but pkg has to work on a 256K PC so let's not get too crazy with RAM */
|
169 |
FILE *filefd;
|
169 |
FILE *filefd;
|
170 |
unsigned long cksum;
|
170 |
unsigned long cksum;
|
171 |
int extract_res;
|
171 |
int extract_res;
|
172 |
unsigned char *buff;
|
- |
|
173 |
struct utimbuf filetimestamp;
|
172 |
struct utimbuf filetimestamp;
|
174 |
|
173 |
|
175 |
/* first of all, check we support the compression method */
|
174 |
/* first of all, check we support the compression method */
|
176 |
switch (curzipnode->compmethod) {
|
175 |
switch (curzipnode->compmethod) {
|
177 |
case ZIP_METH_STORE:
|
176 |
case ZIP_METH_STORE:
|
Line 184... |
Line 183... |
184 |
|
183 |
|
185 |
/* open the dst file */
|
184 |
/* open the dst file */
|
186 |
filefd = fopen(fulldestfilename, "wb");
|
185 |
filefd = fopen(fulldestfilename, "wb");
|
187 |
if (filefd == NULL) return(-2); /* failed to open the dst file */
|
186 |
if (filefd == NULL) return(-2); /* failed to open the dst file */
|
188 |
|
187 |
|
189 |
/* allocate buffers for data I/O */
|
- |
|
190 |
buff = malloc(buffsize);
|
- |
|
191 |
if (buff == NULL) {
|
- |
|
192 |
fclose(filefd);
|
- |
|
193 |
unlink(fulldestfilename); /* remove the failed file once it is closed */
|
- |
|
194 |
return(-6);
|
- |
|
195 |
}
|
- |
|
196 |
|
- |
|
197 |
if (fseek(zipfd, curzipnode->dataoffset, SEEK_SET) != 0) { /* set the reading position inside the zip file */
|
188 |
if (fseek(zipfd, curzipnode->dataoffset, SEEK_SET) != 0) { /* set the reading position inside the zip file */
|
198 |
free(buff);
|
- |
|
199 |
fclose(filefd);
|
189 |
fclose(filefd);
|
200 |
unlink(fulldestfilename); /* remove the failed file once it is closed */
|
190 |
unlink(fulldestfilename); /* remove the failed file once it is closed */
|
201 |
return(-7);
|
191 |
return(-7);
|
202 |
}
|
192 |
}
|
203 |
extract_res = -255;
|
193 |
extract_res = -255;
|
Line 208... |
Line 198... |
208 |
long i, toread;
|
198 |
long i, toread;
|
209 |
extract_res = 0; /* assume we will succeed */
|
199 |
extract_res = 0; /* assume we will succeed */
|
210 |
for (i = 0; i < curzipnode->filelen;) {
|
200 |
for (i = 0; i < curzipnode->filelen;) {
|
211 |
toread = curzipnode->filelen - i;
|
201 |
toread = curzipnode->filelen - i;
|
212 |
if (toread > buffsize) toread = buffsize;
|
202 |
if (toread > buffsize) toread = buffsize;
|
213 |
if (fread(buff, toread, 1, zipfd) != 1) extract_res = -3; /* read a chunk of data */
|
203 |
if (fread(buff15k, toread, 1, zipfd) != 1) extract_res = -3; /* read a chunk of data */
|
214 |
crc32_feed(&cksum, buff, toread); /* update the crc32 checksum */
|
204 |
crc32_feed(&cksum, buff15k, toread); /* update the crc32 checksum */
|
215 |
if (fwrite(buff, toread, 1, filefd) != 1) extract_res = -4; /* write data chunk to dst file */
|
205 |
if (fwrite(buff15k, toread, 1, filefd) != 1) extract_res = -4; /* write data chunk to dst file */
|
216 |
i += toread;
|
206 |
i += toread;
|
217 |
}
|
207 |
}
|
218 |
} else if (curzipnode->compmethod == 8) { /* if the file is deflated, inflate it */
|
208 |
} else if (curzipnode->compmethod == 8) { /* if the file is deflated, inflate it */
|
219 |
/* use 1/3 of my buffer as input and 2/3 as output */
|
209 |
/* use 1/3 of my buffer as input and 2/3 as output */
|
220 |
extract_res = inf(zipfd, filefd, buff, buffsize / 3, buff + (buffsize / 3), buffsize / 3 * 2, &cksum, curzipnode->compressedfilelen);
|
210 |
extract_res = inf(zipfd, filefd, buff15k, buffsize / 3, buff15k + (buffsize / 3), buffsize / 3 * 2, &cksum, curzipnode->compressedfilelen);
|
221 |
}
|
211 |
}
|
222 |
|
212 |
|
223 |
/* clean up memory, close the dst file and terminates crc32 */
|
213 |
/* clean up memory, close the dst file and terminates crc32 */
|
224 |
free(buff);
|
- |
|
225 |
fclose(filefd); /* close the dst file */
|
214 |
fclose(filefd); /* close the dst file */
|
226 |
crc32_finish(&cksum);
|
215 |
crc32_finish(&cksum);
|
227 |
|
216 |
|
228 |
/* printf("extract_res=%d / cksum_expected=%08lX / cksum_obtained=%08lX\n", extract_res, curzipnode->crc32, cksum); */
|
217 |
/* printf("extract_res=%d / cksum_expected=%08lX / cksum_obtained=%08lX\n", extract_res, curzipnode->crc32, cksum); */
|
229 |
if (extract_res != 0) { /* was the extraction process successful? */
|
218 |
if (extract_res != 0) { /* was the extraction process successful? */
|