blob: 1e8e5067e365d13e6f35b8732d1f63212eed03cf [file] [log] [blame]
// 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 <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "DFPlatform.h"
#include "unzip.h"
#include "zip.h"
DFextZipHandleP DFextZipOpen(const char *zipFilename, int doUnzip) {
DFextZipHandleP zipHandle = xmalloc(sizeof(DFextZipHandle));
// no more memory
if (!zipHandle)
return NULL;
// Open file
zipHandle->zipFirst = 1;
zipHandle->zipFlag = doUnzip;
if (doUnzip)
zipHandle->handle = unzOpen(zipFilename);
else
zipHandle->handle = zipOpen(zipFilename, APPEND_STATUS_CREATE);
if (zipHandle->handle)
return zipHandle;
free(zipHandle);
return NULL;
}
int DFextZipClose(DFextZipHandleP zipHandle)
{
int rc = 0;
if (zipHandle->handle) {
if (zipHandle->zipFlag)
rc = (unzClose(zipHandle->handle) == UNZ_OK);
else
rc = (zipClose(zipHandle->handle, NULL) == ZIP_OK);
zipHandle->handle = NULL;
}
free(zipHandle);
return rc ? 1 : -1;
}
int DFextZipOpenNextFile(DFextZipHandleP zipHandle, char *entryName, const int maxName)
{
int rc;
if (zipHandle->zipFlag) {
unz_file_info info;
// handling of first file and all others are different
if (zipHandle->zipFirst) {
rc = unzGoToFirstFile(zipHandle->handle);
zipHandle->zipFirst = 0;
}
else
rc = unzGoToNextFile(zipHandle->handle);
// Error or past last file
if (rc != UNZ_OK)
return (rc == UNZ_END_OF_LIST_OF_FILE) ? 0 : -1;
// get file name
if (unzGetCurrentFileInfo(zipHandle->handle, &info, entryName, maxName, NULL, 0, NULL, 0) != UNZ_OK)
return -1;
// check for prefix "/" and if present skip file
if (entryName[strlen(entryName) - 1] == '/')
return DFextZipOpenNextFile(zipHandle, entryName, maxName);
// open Regular file
if (unzOpenCurrentFile(zipHandle->handle) != UNZ_OK)
return -1;
}
else {
return -1; // Zip file is open in write-only mode
}
// ready to read
return 1;
}
int DFextZipAppendNewFile(DFextZipHandleP zipHandle, const char *entryName)
{
zip_fileinfo fileinfo;
memset(&fileinfo, 0, sizeof(fileinfo));
if (zipHandle->zipFlag)
return -1; // Zip file is open in read-only mode
if (zipOpenNewFileInZip(zipHandle->handle,
entryName,
&fileinfo,
NULL, 0,
NULL, 0,
NULL,
Z_DEFLATED,
Z_DEFAULT_COMPRESSION) != ZIP_OK) {
return -1;
}
return 1;
}
int DFextZipCloseFile(DFextZipHandleP zipHandle)
{
if (zipHandle->zipFlag)
return (unzCloseCurrentFile(zipHandle->handle) != UNZ_OK) ? -1 : 1;
else
return (zipCloseFileInZip(zipHandle->handle) != UNZ_OK) ? -1 : 1;
}
int DFextZipReadCurrentFile(DFextZipHandleP zipHandle, void *buf, const int maxLen)
{
return unzReadCurrentFile(zipHandle->handle, buf, maxLen);
}
int DFextZipWriteCurrentFile(DFextZipHandleP zipHandle, const void *buf, const int len)
{
return (zipWriteInFileInZip(zipHandle->handle, buf, len) == ZIP_OK) ? 1 : -1;
}
void *xmalloc(size_t size)
{
void *ptr = malloc(size);
if (ptr == NULL) {
perror("xmalloc: out of memory.\n");
abort();
return NULL;
}
return ptr;
}
void *xcalloc(size_t nmemb, size_t size)
{
void *ptr = calloc(nmemb, size);
if (ptr == NULL) {
perror("xcalloc: out of memory.\n");
abort();
return NULL;
}
return ptr;
}
void *xrealloc(void *in_ptr, size_t size)
{
void *ptr = realloc(in_ptr, size);
if (ptr == NULL) {
perror("xrealloc: out of memory.\n");
abort();
return NULL;
}
return ptr;
}
char *xstrdup(const char *s)
{
size_t l = strlen(s)+1;
return (char*) memcpy (xmalloc (l), s, l);
}