| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include "DFPlatform.h" |
| #include "DFZipFile.h" |
| #include "DFPlatform.h" |
| #include "DFFilesystem.h" |
| #include "DFString.h" |
| #include "DFCommon.h" |
| #include "DFBuffer.h" |
| #include <stdlib.h> |
| #include <string.h> |
| |
| static int zipError(DFError **error, const char *format, ...) ATTRIBUTE_FORMAT(printf,2,3); |
| |
| static int zipError(DFError **error, const char *format, ...) |
| { |
| va_list ap; |
| va_start(ap,format); |
| DFErrorVFormat(error,format,ap); |
| va_end(ap); |
| return 0; |
| } |
| |
| int DFUnzip(const char *zipFilename, DFStorage *storage, DFError **error) |
| { |
| char entryName[4096]; |
| DFextZipHandleP zipHandle; |
| |
| zipHandle = DFextZipOpen(zipFilename, 1); |
| if (!zipHandle) |
| return zipError(error,"Cannot open file"); |
| |
| int ret; |
| for (; (ret = DFextZipOpenNextFile(zipHandle, entryName, sizeof(entryName))) > 0;) { |
| DFBuffer *content = DFBufferNew(); |
| |
| unsigned char buf[4096]; |
| int r; |
| while (0 < (r = DFextZipReadCurrentFile(zipHandle, buf, sizeof(buf)))) |
| DFBufferAppendData(content,(void *)buf,r); |
| if (0 > r) { |
| DFBufferRelease(content); |
| return zipError(error,"%s: decompression failed",entryName); |
| } |
| |
| if (DFextZipCloseFile(zipHandle) < 0) { |
| DFBufferRelease(content); |
| return zipError(error,"%s: decompression failed",entryName); |
| } |
| |
| if (!DFBufferWriteToStorage(content,storage,entryName,error)) { |
| DFBufferRelease(content); |
| return zipError(error,"%s: %s",entryName,DFErrorMessage(error)); |
| } |
| DFBufferRelease(content); |
| } |
| |
| if (ret < 0) |
| return zipError(error,"Zip directory is corrupt"); |
| |
| DFextZipClose(zipHandle); |
| |
| return 1; |
| } |
| |
| static int zipAddFile(DFextZipHandleP zipHandle, const char *dest, DFBuffer *content, DFError **error) |
| { |
| if (DFextZipAppendNewFile(zipHandle, dest) < 0) |
| return zipError(error,"%s: Cannot create entry in zip file",dest); |
| |
| if (DFextZipWriteCurrentFile(zipHandle, content->data, (unsigned int)content->len) < 0) |
| return zipError(error,"%s: Error writing to entry in zip file",dest); |
| |
| if (DFextZipCloseFile(zipHandle) <0) |
| return zipError(error,"%s: Error closing entry in zip file",dest); |
| return 1; |
| } |
| |
| |
| |
| int DFZip(const char *zipFilename, DFStorage *storage, DFError **error) |
| { |
| const char **allPaths = NULL; |
| DFBuffer *content = NULL; |
| int ok = 0; |
| DFextZipHandleP zipHandle = NULL; |
| |
| allPaths = DFStorageList(storage,error); |
| if (allPaths == NULL || !(zipHandle = DFextZipOpen(zipFilename, 0))) |
| { |
| DFErrorFormat(error,"Cannot create file"); |
| } |
| else |
| { |
| for (int i = 0; allPaths[i]; i++) { |
| const char *path = allPaths[i]; |
| |
| DFBufferRelease(content); |
| content = DFBufferReadFromStorage(storage,path,error); |
| if (content == NULL) { |
| DFErrorFormat(error,"%s: %s",path,DFErrorMessage(error)); |
| goto end; |
| } |
| |
| if (!zipAddFile(zipHandle, path, content, error)) |
| goto end; |
| } |
| |
| ok = 1; |
| } |
| |
| end: |
| DFBufferRelease(content); |
| free(allPaths); |
| if (zipHandle != NULL) |
| DFextZipClose(zipHandle); |
| return ok; |
| } |