19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 29e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Additional tools for Minizip 39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Code: Xavier Roche '2004 49e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project License: Same as ZLIB (www.gzip.org) 59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project*/ 69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Code */ 89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdio.h> 99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdlib.h> 109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <string.h> 119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zlib.h" 129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "unzip.h" 139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define READ_8(adr) ((unsigned char)*(adr)) 159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) 169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) 179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define WRITE_8(buff, n) do { \ 199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ 209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} while(0) 219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define WRITE_16(buff, n) do { \ 229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_8((unsigned char*)(buff), n); \ 239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ 249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} while(0) 259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define WRITE_32(buff, n) do { \ 269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ 279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ 289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} while(0) 299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectextern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) 319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectconst char* file; 329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectconst char* fileOut; 339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectconst char* fileOutTmp; 349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source ProjectuLong* nRecovered; 359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source ProjectuLong* bytesRecovered; 369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int err = Z_OK; 389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project FILE* fpZip = fopen(file, "rb"); 399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project FILE* fpOut = fopen(fileOut, "wb"); 409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project FILE* fpOutCD = fopen(fileOutTmp, "wb"); 419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fpZip != NULL && fpOut != NULL) { 429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int entries = 0; 439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project uLong totalBytes = 0; 449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char header[30]; 45ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes char filename[1024]; 469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char extra[1024]; 479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int offset = 0; 489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int offsetCD = 0; 499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while ( fread(header, 1, 30, fpZip) == 30 ) { 509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int currentOffset = offset; 519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* File entry */ 539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (READ_32(header) == 0x04034b50) { 549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int version = READ_16(header + 4); 559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int gpflag = READ_16(header + 6); 569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int method = READ_16(header + 8); 579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int filetime = READ_16(header + 10); 589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int filedate = READ_16(header + 12); 599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int crc = READ_32(header + 14); /* crc */ 609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int cpsize = READ_32(header + 18); /* compressed size */ 619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ 629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int fnsize = READ_16(header + 26); /* file name length */ 639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned int extsize = READ_16(header + 28); /* extra field length */ 649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project filename[0] = extra[0] = '\0'; 65381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Header */ 679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fwrite(header, 1, 30, fpOut) == 30) { 689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project offset += 30; 699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 73381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Filename */ 759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fnsize > 0) { 76ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (fnsize < sizeof(filename)) { 77ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (fread(filename, 1, fnsize, fpZip) == fnsize) { 78ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { 79ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes offset += fnsize; 80ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } else { 81ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes err = Z_ERRNO; 82ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes break; 83ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_STREAM_ERROR; 949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Extra field */ 989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (extsize > 0) { 99ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (extsize < sizeof(extra)) { 100ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (fread(extra, 1, extsize, fpZip) == extsize) { 101ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (fwrite(extra, 1, extsize, fpOut) == extsize) { 102ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes offset += extsize; 103ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } else { 104ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes err = Z_ERRNO; 105ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes break; 106ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 116381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Data */ 1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project { 1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int dataSize = cpsize; 1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (dataSize == 0) { 1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project dataSize = uncpsize; 1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (dataSize > 0) { 1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char* data = malloc(dataSize); 1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (data != NULL) { 1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { 1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { 1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project offset += dataSize; 1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project totalBytes += dataSize; 1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project free(data); 1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (err != Z_OK) { 1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_MEM_ERROR; 1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 146381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Central directory entry */ 1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project { 1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char header[46]; 1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char* comment = ""; 1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int comsize = (int) strlen(comment); 1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_32(header, 0x02014b50); 1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 4, version); 1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 6, version); 1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 8, gpflag); 1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 10, method); 1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 12, filetime); 1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 14, filedate); 1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_32(header + 16, crc); 1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_32(header + 20, cpsize); 1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_32(header + 24, uncpsize); 1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 28, fnsize); 1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 30, extsize); 1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 32, comsize); 1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 34, 0); /* disk # */ 1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 36, 0); /* int attrb */ 1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_32(header + 38, 0); /* ext attrb */ 1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_32(header + 42, currentOffset); 1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Header */ 1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fwrite(header, 1, 46, fpOutCD) == 46) { 1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project offsetCD += 46; 172381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Filename */ 1749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fnsize > 0) { 1759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { 1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project offsetCD += fnsize; 1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_STREAM_ERROR; 1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 185381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Extra field */ 1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (extsize > 0) { 1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { 1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project offsetCD += extsize; 1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 195381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Comment field */ 1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (comsize > 0) { 1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { 1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project offsetCD += comsize; 2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 2039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 205381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 206381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 2079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Success */ 2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project entries++; 2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 2189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Final central directory */ 2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project { 2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int entriesZip = entries; 2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char header[22]; 2259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; 2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int comsize = (int) strlen(comment); 2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (entriesZip > 0xffff) { 2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project entriesZip = 0xffff; 2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_32(header, 0x06054b50); 2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 4, 0); /* disk # */ 2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 6, 0); /* disk # */ 2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 8, entriesZip); /* hack */ 2349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 10, entriesZip); /* hack */ 2359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_32(header + 12, offsetCD); /* size of CD */ 2369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_32(header + 16, offset); /* offset to CD */ 2379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project WRITE_16(header + 20, comsize); /* comment */ 238381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 2399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Header */ 2409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fwrite(header, 1, 22, fpOutCD) == 22) { 241381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 2429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Comment field */ 2439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (comsize > 0) { 2449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { 2459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 2469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 248381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 2499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 2509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Final merge (file + central directory) */ 2559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fclose(fpOutCD); 2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (err == Z_OK) { 2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fpOutCD = fopen(fileOutTmp, "rb"); 2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fpOutCD != NULL) { 2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int nRead; 2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project char buffer[8192]; 2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { 2629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { 2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_ERRNO; 2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fclose(fpOutCD); 2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 270381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Close */ 2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fclose(fpZip); 2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fclose(fpOut); 274381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Wipe temporary file */ 2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (void)remove(fileOutTmp); 277381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Number of recovered entries */ 2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (err == Z_OK) { 2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (nRecovered != NULL) { 2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *nRecovered = entries; 2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (bytesRecovered != NULL) { 2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *bytesRecovered = totalBytes; 2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } else { 2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project err = Z_STREAM_ERROR; 2899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return err; 2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 292