int TRI_ZipFile (const char* filename, const char* dir, TRI_vector_string_t const* files, const char* password) { void* buffer; size_t bufferSize; zipFile zf; #ifdef USEWIN32IOAPI zlib_filefunc64_def ffunc; #endif size_t i, n; int res; if (TRI_ExistsFile(filename)) { return TRI_ERROR_CANNOT_OVERWRITE_FILE; } bufferSize = 16384; buffer = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, bufferSize, false); if (buffer == NULL) { return TRI_ERROR_OUT_OF_MEMORY; } #ifdef USEWIN32IOAPI fill_win32_filefunc64A(&ffunc); zf = zipOpen2_64(filename, 0, NULL, &ffunc); #else zf = zipOpen64(filename, 0); #endif if (zf == NULL) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, buffer); return ZIP_ERRNO; } res = TRI_ERROR_NO_ERROR; n = files->_length; for (i = 0; i < n; ++i) { FILE* fin; char* file; char* fullfile; char* saveName; zip_fileinfo zi; uint32_t crc; int isLarge; file = TRI_AtVectorString(files, i); if (*dir == '\0') { fullfile = TRI_DuplicateString(file); } else { fullfile = TRI_Concatenate2File(dir, file); } memset(&zi, 0, sizeof(zi)); res = TRI_Crc32File(fullfile, &crc); if (res != TRI_ERROR_NO_ERROR) { break; } isLarge = (TRI_SizeFile(file) > 0xFFFFFFFFLL); saveName = file; while (*saveName == '\\' || *saveName == '/') { ++saveName; } if (zipOpenNewFileInZip3_64(zf, saveName, &zi, NULL, 0, NULL, 0, NULL, /* comment*/ Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password, (unsigned long) crc, isLarge) != ZIP_OK) { } fin = fopen(fullfile, "rb"); TRI_FreeString(TRI_CORE_MEM_ZONE, fullfile); if (fin == NULL) { break; } while (true) { int sizeRead; sizeRead = (int) fread(buffer, 1, bufferSize, fin); if (sizeRead < bufferSize) { if (feof(fin) == 0) { res = TRI_set_errno(TRI_ERROR_SYS_ERROR); break; } } if (sizeRead > 0) { res = zipWriteInFileInZip(zf, buffer, sizeRead); if (res != 0) { break; } } else if (sizeRead <= 0) { break; } } fclose(fin); zipCloseFileInZip(zf); if (res != TRI_ERROR_NO_ERROR) { break; } } zipClose(zf, NULL); TRI_Free(TRI_UNKNOWN_MEM_ZONE, buffer); return res; }
int TRI_ZipFile(char const* filename, char const* dir, std::vector<std::string> const& files, char const* password) { void* buffer; #ifdef USEWIN32IOAPI zlib_filefunc64_def ffunc; #endif if (TRI_ExistsFile(filename)) { return TRI_ERROR_CANNOT_OVERWRITE_FILE; } int bufferSize = 16384; buffer = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, (size_t)bufferSize, false); if (buffer == nullptr) { return TRI_ERROR_OUT_OF_MEMORY; } #ifdef USEWIN32IOAPI fill_win32_filefunc64A(&ffunc); zipFile zf = zipOpen2_64(filename, 0, NULL, &ffunc); #else zipFile zf = zipOpen64(filename, 0); #endif if (zf == nullptr) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, buffer); return ZIP_ERRNO; } int res = TRI_ERROR_NO_ERROR; size_t n = files.size(); for (size_t i = 0; i < n; ++i) { std::string fullfile; if (*dir == '\0') { fullfile = files[i]; } else { fullfile = arangodb::basics::FileUtils::buildFilename(dir, files[i]); } zip_fileinfo zi; memset(&zi, 0, sizeof(zi)); uint32_t crc; res = TRI_Crc32File(fullfile.c_str(), &crc); if (res != TRI_ERROR_NO_ERROR) { break; } int isLarge = (TRI_SizeFile(files[i].c_str()) > 0xFFFFFFFFLL); char const* saveName = files[i].c_str(); while (*saveName == '\\' || *saveName == '/') { ++saveName; } if (zipOpenNewFileInZip3_64( zf, saveName, &zi, NULL, 0, NULL, 0, NULL, /* comment*/ Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password, (unsigned long)crc, isLarge) != ZIP_OK) { res = TRI_ERROR_INTERNAL; break; } FILE* fin = fopen(fullfile.c_str(), "rb"); if (fin == nullptr) { break; } while (true) { int sizeRead = (int)fread(buffer, 1, bufferSize, fin); if (sizeRead < bufferSize) { if (feof(fin) == 0) { res = TRI_set_errno(TRI_ERROR_SYS_ERROR); break; } } if (sizeRead > 0) { res = zipWriteInFileInZip(zf, buffer, sizeRead); if (res != 0) { break; } } else /* if (sizeRead <= 0) */ { break; } } fclose(fin); zipCloseFileInZip(zf); if (res != TRI_ERROR_NO_ERROR) { break; } } zipClose(zf, NULL); TRI_Free(TRI_UNKNOWN_MEM_ZONE, buffer); return res; }