1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 11:08:02 -06:00

Windows: Replace XZip/XUnzip library with zlib and libzip and include the sources of these library into VeraCrypt source tree.

This commit is contained in:
Mounir IDRASSI
2016-09-15 10:04:05 +02:00
parent 66891638d5
commit 4dacedd9cc
154 changed files with 29709 additions and 8504 deletions

View File

@@ -29,8 +29,7 @@
#include "Registry.h"
#include "Volumes.h"
#include "Xml.h"
#include "XZip.h"
#include "XUnzip.h"
#include "zip.h"
#ifdef VOLFORMAT
#include "Format/FormatCom.h"
@@ -40,6 +39,22 @@
#include <Strsafe.h>
bool ZipAdd (zip_t *z, const char* name, const unsigned char* pbData, DWORD cbData)
{
zip_error_t zerr;
zip_source_t* zin = zip_source_buffer_create (pbData, cbData, 0, &zerr);
if (!zin)
return false;
if (-1 == zip_file_add (z, name, zin, 0))
{
zip_source_free (zin);
return false;
}
return true;
}
namespace VeraCrypt
{
#if !defined (SETUP)
@@ -2739,25 +2754,32 @@ namespace VeraCrypt
if (!DcsRescueImg)
throw ParameterIncorrect (SRC_POS);
unsigned int maxRescueZipSize = 4 * 1024 * 1024;
ZRESULT res;
HZIP hz = CreateZip (0, maxRescueZipSize, ZIP_MEMORY);
if (!hz)
char szTmpPath[MAX_PATH + 1], szTmpFilePath[MAX_PATH + 1];
if (!GetTempPathA (MAX_PATH, szTmpPath))
throw SystemException (SRC_POS);
if (!GetTempFileNameA (szTmpPath, "_vrd", 0, szTmpFilePath))
throw SystemException (SRC_POS);
finally_do_arg (char*, szTmpFilePath, { DeleteFileA (finally_arg);});
int ierr;
zip_t* z = zip_open (szTmpFilePath, ZIP_CREATE | ZIP_TRUNCATE | ZIP_CHECKCONS, &ierr);
if (!z)
throw ParameterIncorrect (SRC_POS);
finally_do_arg (HZIP, hz, { CloseZip (finally_arg); });
finally_do_arg (zip_t**, &z, { if (*finally_arg) zip_discard (*finally_arg);});
if (ZR_OK != ZipAdd (hz, L"EFI/Boot/bootx64.efi", DcsRescueImg, sizeDcsRescue, ZIP_MEMORY))
if (!ZipAdd (z, "EFI/Boot/bootx64.efi", DcsRescueImg, sizeDcsRescue))
throw ParameterIncorrect (SRC_POS);
if (ZR_OK !=ZipAdd (hz, L"EFI/VeraCrypt/DcsBml.dcs", BootMenuLockerImg, sizeBootMenuLocker, ZIP_MEMORY))
if (!ZipAdd (z, "EFI/VeraCrypt/DcsBml.dcs", BootMenuLockerImg, sizeBootMenuLocker))
throw ParameterIncorrect (SRC_POS);
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsBoot.efi", dcsBootImg, sizeDcsBoot, ZIP_MEMORY))
if (!ZipAdd (z, "EFI/VeraCrypt/DcsBoot.efi", dcsBootImg, sizeDcsBoot))
throw ParameterIncorrect (SRC_POS);
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsCfg.dcs", dcsCfgImg, sizeDcsCfg, ZIP_MEMORY))
if (!ZipAdd (z, "EFI/VeraCrypt/DcsCfg.dcs", dcsCfgImg, sizeDcsCfg))
throw ParameterIncorrect (SRC_POS);
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsInt.dcs", dcsIntImg, sizeDcsInt, ZIP_MEMORY))
if (!ZipAdd (z, "EFI/VeraCrypt/DcsInt.dcs", dcsIntImg, sizeDcsInt))
throw ParameterIncorrect (SRC_POS);
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/LegacySpeaker.dcs", LegacySpeakerImg, sizeLegacySpeaker, ZIP_MEMORY))
if (!ZipAdd (z, "EFI/VeraCrypt/LegacySpeaker.dcs", LegacySpeakerImg, sizeLegacySpeaker))
throw ParameterIncorrect (SRC_POS);
Buffer volHeader(TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
@@ -2778,20 +2800,21 @@ namespace VeraCrypt
bootDevice.Read (volHeader.Ptr (), TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
}
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/svh_bak", volHeader.Ptr (), TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE, ZIP_MEMORY))
if (!ZipAdd (z, "EFI/VeraCrypt/svh_bak", volHeader.Ptr (), TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE))
throw ParameterIncorrect (SRC_POS);
// Original system loader
res = ZR_WRITE;
Buffer fileBuf (0);
bool bLoadAdded = false;
try
{
DWORD fileSize = 0;
File sysBakFile (GetSystemLoaderBackupPath(), true);
sysBakFile.CheckOpened (SRC_POS);
sysBakFile.GetFileSize(fileSize);
Buffer fileBuf ((DWORD) fileSize);
fileBuf.Resize ((DWORD) fileSize);
DWORD sizeLoader = sysBakFile.Read (fileBuf.Ptr (), fileSize);
res = ZipAdd (hz, L"EFI/Boot/original_bootx64.vc_backup", fileBuf.Ptr (), sizeLoader, ZIP_MEMORY);
bLoadAdded = ZipAdd (z, "EFI/Boot/original_bootx64.vc_backup", fileBuf.Ptr (), sizeLoader);
}
catch (Exception &e)
{
@@ -2799,10 +2822,11 @@ namespace VeraCrypt
Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK", ParentWindow);
}
if (res != ZR_OK)
if (!bLoadAdded)
throw ParameterIncorrect (SRC_POS);
EfiBootConf conf;
Buffer propBuf (0);
wstring dcsPropFileName = GetTempPathString() + L"_dcsproprescue";
finally_do_arg (wstring, dcsPropFileName, { DeleteFileW (finally_arg.c_str()); });
if (conf.Save(dcsPropFileName.c_str(), ParentWindow))
@@ -2811,24 +2835,40 @@ namespace VeraCrypt
File propFile (dcsPropFileName, true, false);
propFile.CheckOpened (SRC_POS);
propFile.GetFileSize(fileSize);
Buffer propBuf (fileSize);
propBuf.Resize (fileSize);
DWORD sizeDcsProp = propFile.Read (propBuf.Ptr (), fileSize);
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsProp", propBuf.Ptr (), sizeDcsProp, ZIP_MEMORY))
if (!ZipAdd (z, "EFI/VeraCrypt/DcsProp", propBuf.Ptr (), sizeDcsProp))
throw ParameterIncorrect (SRC_POS);
}
else
throw ParameterIncorrect (SRC_POS);
void* pZipContent = NULL;
unsigned long ulZipSize = 0;
if (ZR_OK != ZipGetMemory (hz, &pZipContent, &ulZipSize))
// flush the zip content to the temporary file
if (zip_close (z) < 0)
throw ParameterIncorrect (SRC_POS);
z = NULL;
// read the zip data from the temporary file
FILE* ftmpFile = fopen (szTmpFilePath, "rb");
if (!ftmpFile)
throw ParameterIncorrect (SRC_POS);
finally_do_arg (FILE*, ftmpFile, { fclose (finally_arg); });
unsigned long ulZipSize = (unsigned long) _filelength (_fileno (ftmpFile));
RescueZipData = new byte[ulZipSize];
if (!RescueZipData)
throw bad_alloc();
memcpy (RescueZipData, pZipContent, ulZipSize);
if (ulZipSize != fread (RescueZipData, 1, ulZipSize, ftmpFile))
{
delete [] RescueZipData;
RescueZipData = NULL;
throw ParameterIncorrect (SRC_POS);
}
RescueZipSize = ulZipSize;
if (!isoImagePath.empty())
@@ -3000,11 +3040,18 @@ namespace VeraCrypt
L"EFI/Boot/original_bootx64.vc_backup"
};
ZRESULT res;
HZIP hz = OpenZip(RescueZipData, RescueZipSize, ZIP_MEMORY);
if (!hz)
zip_error_t zerr;
zip_source_t* zsrc = zip_source_buffer_create (RescueZipData, RescueZipSize, 0, &zerr);
if (!zsrc)
throw ParameterIncorrect (SRC_POS);
finally_do_arg (HZIP, hz, { CloseZip (finally_arg); });
zip_t* z = zip_open_from_source (zsrc, ZIP_CHECKCONS | ZIP_RDONLY, &zerr);
if (!z)
{
zip_source_free (zsrc);
throw ParameterIncorrect (SRC_POS);
}
finally_do_arg (zip_t*, z, { zip_close (finally_arg); });
for (WCHAR drive = L'Z'; drive >= L'C'; --drive)
{
@@ -3019,42 +3066,48 @@ namespace VeraCrypt
if (GetVolumeInformationW (rootPath, NULL, 0, NULL, NULL, NULL, szNameBuffer, ARRAYSIZE(szNameBuffer))
&& !wcsncmp (szNameBuffer, L"FAT", 3))
{
int index, i;
ZIPENTRYW ze;
int i;
for (i = 0; i < ARRAYSIZE(efiFiles); i++)
{
bool bMatch = false;
res = FindZipItemW (hz, efiFiles[i], true, &index, &ze);
if ((res == ZR_OK) && (index >= 0))
zip_int64_t index = zip_name_locate (z, WideToUtf8String (efiFiles[i]).c_str(), ZIP_FL_NOCASE);
if (index >= 0)
{
// check that the file exists on the disk and that it has the same content
StringCbCopyW (szNameBuffer, sizeof (szNameBuffer), rootPath);
StringCbCatW (szNameBuffer, sizeof (szNameBuffer), efiFiles[i]);
try
zip_stat_t stat;
if ((0 == zip_stat_index (z, index, ZIP_FL_NOCASE, &stat)) && (stat.valid & ZIP_STAT_SIZE))
{
DWORD dwSize = 0;
File diskFile (szNameBuffer, true);
diskFile.CheckOpened (SRC_POS);
diskFile.GetFileSize (dwSize);
if (dwSize == (DWORD) ze.unc_size)
// check that the file exists on the disk and that it has the same content
StringCbCopyW (szNameBuffer, sizeof (szNameBuffer), rootPath);
StringCbCatW (szNameBuffer, sizeof (szNameBuffer), efiFiles[i]);
try
{
Buffer fileBuf (dwSize);
if (dwSize == diskFile.Read (fileBuf.Ptr (), dwSize))
DWORD dwSize = 0;
File diskFile (szNameBuffer, true);
diskFile.CheckOpened (SRC_POS);
diskFile.GetFileSize (dwSize);
if (dwSize == (DWORD) stat.size)
{
Buffer efiBuf (dwSize);
res = UnzipItem (hz, ze.index, efiBuf.Ptr (), dwSize, ZIP_MEMORY);
if (res == ZR_OK)
Buffer fileBuf (dwSize);
if (dwSize == diskFile.Read (fileBuf.Ptr (), dwSize))
{
bMatch = (memcmp (efiBuf.Ptr(), fileBuf.Ptr(), dwSize) == 0);
Buffer efiBuf (dwSize);
zip_file_t* zf = zip_fopen_index (z, index, 0);
if (zf)
{
if (0 < zip_fread (zf, efiBuf.Ptr (), stat.size))
{
bMatch = (memcmp (efiBuf.Ptr(), fileBuf.Ptr(), dwSize) == 0);
}
zip_fclose (zf);
}
}
}
}
}
}
catch (...)
{
}
}
catch (...)
{
}
}
else
{
@@ -3129,70 +3182,99 @@ namespace VeraCrypt
if (dwSize == rescueFile.Read (rescueData.Ptr (), dwSize))
{
ZRESULT res;
HZIP hzFile = OpenZip(rescueData.Ptr (), dwSize, ZIP_MEMORY);
if (hzFile)
zip_error_t zerr;
zip_source_t* zsrc = zip_source_buffer_create (rescueData.Ptr (), dwSize, 0, &zerr);
if (!zsrc)
return false;
zip_t* zFile = zip_open_from_source (zsrc, ZIP_CHECKCONS | ZIP_RDONLY, &zerr);
if (!zFile)
{
finally_do_arg (HZIP, hzFile, { CloseZip (finally_arg); });
HZIP hzMem = OpenZip(RescueZipData, RescueZipSize, ZIP_MEMORY);
if (hzMem)
{
finally_do_arg (HZIP, hzMem, { CloseZip (finally_arg); });
const wchar_t* efiFiles[] = {
L"EFI/Boot/bootx64.efi",
L"EFI/VeraCrypt/DcsBml.dcs",
L"EFI/VeraCrypt/DcsBoot.efi",
L"EFI/VeraCrypt/DcsCfg.dcs",
L"EFI/VeraCrypt/DcsInt.dcs",
L"EFI/VeraCrypt/LegacySpeaker.dcs",
L"EFI/VeraCrypt/svh_bak",
L"EFI/Boot/original_bootx64.vc_backup"
};
zip_source_free (zsrc);
throw ParameterIncorrect (SRC_POS);
}
int index, i;
ZIPENTRYW zeFile, zeMem;
for (i = 0; i < ARRAYSIZE(efiFiles); i++)
finally_do_arg (zip_t*, zFile, { zip_close (finally_arg); });
zsrc = zip_source_buffer_create (RescueZipData, RescueZipSize, 0, &zerr);
if (!zsrc)
return false;
zip_t* zMem = zip_open_from_source (zsrc, ZIP_CHECKCONS | ZIP_RDONLY, &zerr);
if (!zMem)
{
zip_source_free (zsrc);
throw ParameterIncorrect (SRC_POS);
}
finally_do_arg (zip_t*, zMem, { zip_close (finally_arg); });
const wchar_t* efiFiles[] = {
L"EFI/Boot/bootx64.efi",
L"EFI/VeraCrypt/DcsBml.dcs",
L"EFI/VeraCrypt/DcsBoot.efi",
L"EFI/VeraCrypt/DcsCfg.dcs",
L"EFI/VeraCrypt/DcsInt.dcs",
L"EFI/VeraCrypt/LegacySpeaker.dcs",
L"EFI/VeraCrypt/svh_bak",
L"EFI/Boot/original_bootx64.vc_backup"
};
int i;
zip_stat_t statMem, statFile;
zip_int64_t indexMem, indexFile;
for (i = 0; i < ARRAYSIZE(efiFiles); i++)
{
bool bMatch = false;
indexMem = zip_name_locate (zMem, WideToUtf8String (efiFiles[i]).c_str(), ZIP_FL_NOCASE);
if (indexMem >= 0)
{
if ((0 == zip_stat_index (zMem, indexMem, ZIP_FL_NOCASE, &statMem)) && (statMem.valid & ZIP_STAT_SIZE))
{
bool bMatch = false;
res = FindZipItemW (hzMem, efiFiles[i], true, &index, &zeMem);
if ((res == ZR_OK) && (index >= 0))
indexFile = zip_name_locate (zFile, WideToUtf8String (efiFiles[i]).c_str(), ZIP_FL_NOCASE);
if (indexFile >= 0)
{
res = FindZipItemW (hzFile, efiFiles[i], true, &index, &zeFile);
if ((res == ZR_OK) && (index >= 0) && (zeMem.unc_size == zeFile.unc_size))
if ((0 == zip_stat_index (zFile, indexFile, ZIP_FL_NOCASE, &statFile)) && (statFile.valid & ZIP_STAT_SIZE))
{
Buffer fileBuf (zeFile.unc_size);
Buffer memBuf (zeFile.unc_size);
res = UnzipItem (hzMem, zeMem.index, memBuf.Ptr (), zeMem.unc_size, ZIP_MEMORY);
if (res == ZR_OK)
if (statMem.size == statFile.size)
{
res = UnzipItem (hzFile, zeFile.index, fileBuf.Ptr (), zeFile.unc_size, ZIP_MEMORY);
if (res == ZR_OK)
Buffer fileBuf (statFile.size);
Buffer memBuf (statMem.size);
zip_file_t* zfMem = zip_fopen_index (zMem, indexMem, 0);
if (zfMem)
{
bMatch = (memcmp (memBuf.Ptr (), fileBuf.Ptr (), zeMem.unc_size) == 0);
if (0 < zip_fread (zfMem, memBuf.Ptr (), statMem.size))
{
zip_file_t* zfFile = zip_fopen_index (zFile, indexFile, 0);
if (zfFile)
{
if (0 < zip_fread (zfFile, fileBuf.Ptr (), statFile.size))
{
bMatch = (memcmp (memBuf.Ptr(), fileBuf.Ptr(), statFile.size) == 0);
}
zip_fclose (zfFile);
}
}
zip_fclose (zfMem);
}
}
}
}
else
{
// entry not found in our internal Rescue ZIP image. Skip it.
bMatch = true;
}
if (!bMatch)
break;
}
if (i == ARRAYSIZE(efiFiles))
{
// All entries processed
return true;
}
}
else
{
// entry not found in our internal Rescue ZIP image. Skip it.
bMatch = true;
}
if (!bMatch)
break;
}
if (i == ARRAYSIZE(efiFiles))
{
// All entries processed
return true;
}
}
}

View File

@@ -82,6 +82,19 @@ namespace VeraCrypt
~Buffer () { delete[] DataPtr; }
byte *Ptr () const { return DataPtr; }
size_t Size () const { return DataSize; }
void Resize (size_t newSize)
{
if (newSize > DataSize)
{
byte *tmp = new byte[newSize];
if (!tmp)
throw bad_alloc();
memcpy (tmp, DataPtr, DataSize);
delete [] DataPtr;
DataPtr = tmp;
}
DataSize = newSize;
}
protected:
byte *DataPtr;

File diff suppressed because it is too large Load Diff

View File

@@ -1,382 +0,0 @@
// XUnzip.h Version 1.3
//
// Authors: Mark Adler et al. (see below)
//
// Modified by: Lucian Wischik
// lu@wischik.com
//
// Version 1.0 - Turned C files into just a single CPP file
// - Made them compile cleanly as C++ files
// - Gave them simpler APIs
// - Added the ability to zip/unzip directly in memory without
// any intermediate files
//
// Modified by: Hans Dietrich
// hdietrich@gmail.com
//
///////////////////////////////////////////////////////////////////////////////
//
// Lucian Wischik's comments:
// --------------------------
// THIS FILE is almost entirely based upon code by info-zip.
// It has been modified by Lucian Wischik.
// The original code may be found at http://www.info-zip.org
// The original copyright text follows.
//
///////////////////////////////////////////////////////////////////////////////
//
// Original authors' comments:
// ---------------------------
// This is version 2002-Feb-16 of the Info-ZIP copyright and license. The
// definitive version of this document should be available at
// ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely.
//
// Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
//
// For the purposes of this copyright and license, "Info-ZIP" is defined as
// the following set of individuals:
//
// Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
// Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase,
// Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
// David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
// Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
// Kai Uwe Rommel, Steve Salisbury, Dave Smith, Christian Spieler,
// Antoine Verheijen, Paul von Behren, Rich Wales, Mike White
//
// This software is provided "as is", without warranty of any kind, express
// or implied. In no event shall Info-ZIP or its contributors be held liable
// for any direct, indirect, incidental, special or consequential damages
// arising out of the use of or inability to use this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. Redistributions of source code must retain the above copyright notice,
// definition, disclaimer, and this list of conditions.
//
// 2. Redistributions in binary form (compiled executables) must reproduce
// the above copyright notice, definition, disclaimer, and this list of
// conditions in documentation and/or other materials provided with the
// distribution. The sole exception to this condition is redistribution
// of a standard UnZipSFX binary as part of a self-extracting archive;
// that is permitted without inclusion of this license, as long as the
// normal UnZipSFX banner has not been removed from the binary or disabled.
//
// 3. Altered versions--including, but not limited to, ports to new
// operating systems, existing ports with new graphical interfaces, and
// dynamic, shared, or static library versions--must be plainly marked
// as such and must not be misrepresented as being the original source.
// Such altered versions also must not be misrepresented as being
// Info-ZIP releases--including, but not limited to, labeling of the
// altered versions with the names "Info-ZIP" (or any variation thereof,
// including, but not limited to, different capitalizations),
// "Pocket UnZip", "WiZ" or "MacZip" without the explicit permission of
// Info-ZIP. Such altered versions are further prohibited from
// misrepresentative use of the Zip-Bugs or Info-ZIP e-mail addresses or
// of the Info-ZIP URL(s).
//
// 4. Info-ZIP retains the right to use the names "Info-ZIP", "Zip", "UnZip",
// "UnZipSFX", "WiZ", "Pocket UnZip", "Pocket Zip", and "MacZip" for its
// own source and binary releases.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef XUNZIP_H
#define XUNZIP_H
#ifndef XZIP_H
DECLARE_HANDLE(HZIP); // An HZIP identifies a zip file that has been opened
#endif
typedef DWORD ZRESULT;
// return codes from any of the zip functions. Listed later.
#define ZIP_HANDLE 1
#define ZIP_FILENAME 2
#define ZIP_MEMORY 3
typedef struct
{ int index; // index of this file within the zip
char name[MAX_PATH]; // filename within the zip
DWORD attr; // attributes, as in GetFileAttributes.
FILETIME atime,ctime,mtime;// access, create, modify filetimes
long comp_size; // sizes of item, compressed and uncompressed. These
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
} ZIPENTRY;
typedef struct
{ int index; // index of this file within the zip
TCHAR name[MAX_PATH]; // filename within the zip
DWORD attr; // attributes, as in GetFileAttributes.
FILETIME atime,ctime,mtime;// access, create, modify filetimes
long comp_size; // sizes of item, compressed and uncompressed. These
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
} ZIPENTRYW;
///////////////////////////////////////////////////////////////////////////////
//
// OpenZip()
//
// Purpose: Open an existing zip archive file
//
// Parameters: z - archive file name if flags is ZIP_FILENAME; for other
// uses see below
// len - for memory (ZIP_MEMORY) should be the buffer size;
// for other uses, should be 0
// flags - indicates usage, see below; for files, this will be
// ZIP_FILENAME
//
// Returns: HZIP - non-zero if zip archive opened ok, otherwise 0
//
HZIP OpenZip(void *z, unsigned int len, DWORD flags);
// OpenZip - opens a zip file and returns a handle with which you can
// subsequently examine its contents. You can open a zip file from:
// from a pipe: OpenZip(hpipe_read,0, ZIP_HANDLE);
// from a file (by handle): OpenZip(hfile,0, ZIP_HANDLE);
// from a file (by name): OpenZip("c:\\test.zip",0, ZIP_FILENAME);
// from a memory block: OpenZip(bufstart, buflen, ZIP_MEMORY);
// If the file is opened through a pipe, then items may only be
// accessed in increasing order, and an item may only be unzipped once,
// although GetZipItem can be called immediately before and after unzipping
// it. If it's opened i n any other way, then full random access is possible.
// Note: pipe input is not yet implemented.
///////////////////////////////////////////////////////////////////////////////
//
// GetZipItem()
//
// Purpose: Get information about an item in an open zip archive
//
// Parameters: hz - handle of open zip archive
// index - index number (0 based) of item in zip
// ze - pointer to a ZIPENTRY (if ANSI) or ZIPENTRYW struct
// (if Unicode)
//
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
//
#ifdef _UNICODE
#define GetZipItem GetZipItemW
#else
#define GetZipItem GetZipItemA
#endif
ZRESULT GetZipItemA(HZIP hz, int index, ZIPENTRY *ze);
ZRESULT GetZipItemW(HZIP hz, int index, ZIPENTRYW *ze);
// GetZipItem - call this to get information about an item in the zip.
// If index is -1 and the file wasn't opened through a pipe,
// then it returns information about the whole zipfile
// (and in particular ze.index returns the number of index items).
// Note: the item might be a directory (ze.attr & FILE_ATTRIBUTE_DIRECTORY)
// See below for notes on what happens when you unzip such an item.
// Note: if you are opening the zip through a pipe, then random access
// is not possible and GetZipItem(-1) fails and you can't discover the number
// of items except by calling GetZipItem on each one of them in turn,
// starting at 0, until eventually the call fails. Also, in the event that
// you are opening through a pipe and the zip was itself created into a pipe,
// then then comp_size and sometimes unc_size as well may not be known until
// after the item has been unzipped.
///////////////////////////////////////////////////////////////////////////////
//
// FindZipItem()
//
// Purpose: Find item by name and return information about it
//
// Parameters: hz - handle of open zip archive
// name - name of file to look for inside zip archive
// ic - TRUE = case insensitive
// index - pointer to index number returned, or -1
// ze - pointer to a ZIPENTRY (if ANSI) or ZIPENTRYW struct
// (if Unicode)
//
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
//
#ifdef _UNICODE
#define FindZipItem FindZipItemW
#else
#define FindZipItem FindZipItemA
#endif
ZRESULT FindZipItemA(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze);
ZRESULT FindZipItemW(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRYW *ze);
// FindZipItem - finds an item by name. ic means 'insensitive to case'.
// It returns the index of the item, and returns information about it.
// If nothing was found, then index is set to -1 and the function returns
// an error code.
///////////////////////////////////////////////////////////////////////////////
//
// UnzipItem()
//
// Purpose: Find item by index and unzip it
//
// Parameters: hz - handle of open zip archive
// index - index number of file to unzip
// dst - target file name of unzipped file
// len - for memory (ZIP_MEMORY. length of buffer;
// otherwise 0
// flags - indicates usage, see below; for files, this will be
// ZIP_FILENAME
//
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
//
ZRESULT UnzipItem(HZIP hz, int index, void *dst, unsigned int len, DWORD flags);
// UnzipItem - given an index to an item, unzips it. You can unzip to:
// to a pipe: UnzipItem(hz,i, hpipe_write,0,ZIP_HANDLE);
// to a file (by handle): UnzipItem(hz,i, hfile,0,ZIP_HANDLE);
// to a file (by name): UnzipItem(hz,i, ze.name,0,ZIP_FILENAME);
// to a memory block: UnzipItem(hz,i, buf,buflen,ZIP_MEMORY);
// In the final case, if the buffer isn't large enough to hold it all,
// then the return code indicates that more is yet to come. If it was
// large enough, and you want to know precisely how big, GetZipItem.
// Note: zip files are normally stored with relative pathnames. If you
// unzip with ZIP_FILENAME a relative pathname then the item gets created
// relative to the current directory - it first ensures that all necessary
// subdirectories have been created. Also, the item may itself be a directory.
// If you unzip a directory with ZIP_FILENAME, then the directory gets created.
// If you unzip it to a handle or a memory block, then nothing gets created
// and it emits 0 bytes.
///////////////////////////////////////////////////////////////////////////////
//
// CloseZip()
//
// Purpose: Close an open zip archive
//
// Parameters: hz - handle to an open zip archive
//
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
//
ZRESULT CloseZip(HZIP hz);
// CloseZip - the zip handle must be closed with this function.
unsigned int FormatZipMessage(ZRESULT code, char *buf,unsigned int len);
// FormatZipMessage - given an error code, formats it as a string.
// It returns the length of the error message. If buf/len points
// to a real buffer, then it also writes as much as possible into there.
// These are the result codes:
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
// The following come from general system stuff (e.g. files not openable)
#define ZR_GENMASK 0x0000FF00
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
#define ZR_WRITE 0x00000400 // a general error writing to the file
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
#define ZR_READ 0x00000800 // a general error reading the file
// The following come from mistakes on the part of the caller
#define ZR_CALLERMASK 0x00FF0000
#define ZR_ARGS 0x00010000 // general mistake with the arguments
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
// The following come from bugs within the zip library itself
#define ZR_BUGMASK 0xFF000000
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
// e.g.
//
// SetCurrentDirectory("c:\\docs\\stuff");
// HZIP hz = OpenZip("c:\\stuff.zip",0,ZIP_FILENAME);
// ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numitems=ze.index;
// for (int i=0; i<numitems; i++)
// { GetZipItem(hz,i,&ze);
// UnzipItem(hz,i,ze.name,0,ZIP_FILENAME);
// }
// CloseZip(hz);
//
//
// HRSRC hrsrc = FindResource(hInstance,MAKEINTRESOURCE(1),RT_RCDATA);
// HANDLE hglob = LoadResource(hInstance,hrsrc);
// void *zipbuf=LockResource(hglob);
// unsigned int ziplen=SizeofResource(hInstance,hrsrc);
// HZIP hz = OpenZip(zipbuf, ziplen, ZIP_MEMORY);
// - unzip to a membuffer -
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",&i,&ze);
// char *ibuf = new char[ze.unc_size];
// UnzipItem(hz,i, ibuf, ze.unc_size,ZIP_MEMORY);
// delete[] buf;
// - unzip to a fixed membuff -
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",&i,&ze);
// char ibuf[1024]; ZIPRESULT zr=ZR_MORE; unsigned long totsize=0;
// while (zr==ZR_MORE)
// { zr = UnzipItem(hz,i, ibuf,1024,ZIP_MEMORY);
// unsigned long bufsize=1024; if (zr==ZR_OK) bufsize=ze.unc_size-totsize;
// totsize+=bufsize;
// }
// - unzip to a pipe -
// HANDLE hthread=CreateWavReaderThread(&hread,&hwrite);
// FindZipItem(hz,"sound.wav",&i,&ze);
// UnzipItem(hz,i, hwrite,0,ZIP_HANDLE);
// CloseHandle(hwrite);
// WaitForSingleObject(hthread,INFINITE);
// CloseHandle(hread); CloseHandle(hthread);
// - finished -
// CloseZip(hz);
// // note: no need to free resources obtained through Find/Load/LockResource
//
//
// SetCurrentDirectory("c:\\docs\\pipedzipstuff");
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite);
// CreateZipWriterThread(hwrite);
// HZIP hz = OpenZip(hread,0,ZIP_HANDLE);
// for (int i=0; ; i++)
// { ZIPENTRY ze; ZRESULT res = GetZipItem(hz,i,&ze);
// if (res!=ZE_OK) break; // no more
// UnzipItem(hz,i, ze.name,0,ZIP_FILENAME);
// }
// CloseZip(hz);
//
// Now we indulge in a little skullduggery so that the code works whether
// the user has included just zip or both zip and unzip.
// Idea: if header files for both zip and unzip are present, then presumably
// the cpp files for zip and unzip are both present, so we will call
// one or the other of them based on a dynamic choice. If the header file
// for only one is present, then we will bind to that particular one.
HZIP OpenZipU(void *z,unsigned int len,DWORD flags);
ZRESULT CloseZipU(HZIP hz);
unsigned int FormatZipMessageU(ZRESULT code, char *buf,unsigned int len);
bool IsZipHandleU(HZIP hz);
#define OpenZip OpenZipU
#ifdef XZIP_H
#undef CloseZip
#define CloseZip(hz) (IsZipHandleU(hz)?CloseZipU(hz):CloseZipZ(hz))
#else
#define CloseZip CloseZipU
#define FormatZipMessage FormatZipMessageU
#endif
#endif //XUNZIP_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,323 +0,0 @@
// XZip.h Version 1.3
//
// Authors: Mark Adler et al. (see below)
//
// Modified by: Lucian Wischik
// lu@wischik.com
//
// Version 1.0 - Turned C files into just a single CPP file
// - Made them compile cleanly as C++ files
// - Gave them simpler APIs
// - Added the ability to zip/unzip directly in memory without
// any intermediate files
//
// Modified by: Hans Dietrich
// hdietrich@gmail.com
//
///////////////////////////////////////////////////////////////////////////////
//
// Lucian Wischik's comments:
// --------------------------
// THIS FILE is almost entirely based upon code by info-zip.
// It has been modified by Lucian Wischik.
// The original code may be found at http://www.info-zip.org
// The original copyright text follows.
//
///////////////////////////////////////////////////////////////////////////////
//
// Original authors' comments:
// ---------------------------
// This is version 2002-Feb-16 of the Info-ZIP copyright and license. The
// definitive version of this document should be available at
// ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely.
//
// Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
//
// For the purposes of this copyright and license, "Info-ZIP" is defined as
// the following set of individuals:
//
// Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
// Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase,
// Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
// David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
// Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
// Kai Uwe Rommel, Steve Salisbury, Dave Smith, Christian Spieler,
// Antoine Verheijen, Paul von Behren, Rich Wales, Mike White
//
// This software is provided "as is", without warranty of any kind, express
// or implied. In no event shall Info-ZIP or its contributors be held liable
// for any direct, indirect, incidental, special or consequential damages
// arising out of the use of or inability to use this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. Redistributions of source code must retain the above copyright notice,
// definition, disclaimer, and this list of conditions.
//
// 2. Redistributions in binary form (compiled executables) must reproduce
// the above copyright notice, definition, disclaimer, and this list of
// conditions in documentation and/or other materials provided with the
// distribution. The sole exception to this condition is redistribution
// of a standard UnZipSFX binary as part of a self-extracting archive;
// that is permitted without inclusion of this license, as long as the
// normal UnZipSFX banner has not been removed from the binary or disabled.
//
// 3. Altered versions--including, but not limited to, ports to new
// operating systems, existing ports with new graphical interfaces, and
// dynamic, shared, or static library versions--must be plainly marked
// as such and must not be misrepresented as being the original source.
// Such altered versions also must not be misrepresented as being
// Info-ZIP releases--including, but not limited to, labeling of the
// altered versions with the names "Info-ZIP" (or any variation thereof,
// including, but not limited to, different capitalizations),
// "Pocket UnZip", "WiZ" or "MacZip" without the explicit permission of
// Info-ZIP. Such altered versions are further prohibited from
// misrepresentative use of the Zip-Bugs or Info-ZIP e-mail addresses or
// of the Info-ZIP URL(s).
//
// 4. Info-ZIP retains the right to use the names "Info-ZIP", "Zip", "UnZip",
// "UnZipSFX", "WiZ", "Pocket UnZip", "Pocket Zip", and "MacZip" for its
// own source and binary releases.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef XZIP_H
#define XZIP_H
// ZIP functions -- for creating zip files
// This file is a repackaged form of the Info-Zip source code available
// at www.info-zip.org. The original copyright notice may be found in
// zip.cpp. The repackaging was done by Lucian Wischik to simplify its
// use in Windows/C++.
#ifndef XUNZIP_H
DECLARE_HANDLE(HZIP); // An HZIP identifies a zip file that is being created
#endif
typedef DWORD ZRESULT; // result codes from any of the zip functions. Listed later.
// flag values passed to some functions
#define ZIP_HANDLE 1
#define ZIP_FILENAME 2
#define ZIP_MEMORY 3
#define ZIP_FOLDER 4
///////////////////////////////////////////////////////////////////////////////
//
// CreateZip()
//
// Purpose: Create a zip archive file
//
// Parameters: z - archive file name if flags is ZIP_FILENAME; for other
// uses see below
// len - for memory (ZIP_MEMORY) should be the buffer size;
// for other uses, should be 0
// flags - indicates usage, see below; for files, this will be
// ZIP_FILENAME
//
// Returns: HZIP - non-zero if zip archive created ok, otherwise 0
//
HZIP CreateZip(void *z, unsigned int len, DWORD flags);
// CreateZip - call this to start the creation of a zip file.
// As the zip is being created, it will be stored somewhere:
// to a pipe: CreateZip(hpipe_write, 0,ZIP_HANDLE);
// in a file (by handle): CreateZip(hfile, 0,ZIP_HANDLE);
// in a file (by name): CreateZip("c:\\test.zip", 0,ZIP_FILENAME);
// in memory: CreateZip(buf, len,ZIP_MEMORY);
// or in pagefile memory: CreateZip(0, len,ZIP_MEMORY);
// The final case stores it in memory backed by the system paging file,
// where the zip may not exceed len bytes. This is a bit friendlier than
// allocating memory with new[]: it won't lead to fragmentation, and the
// memory won't be touched unless needed.
// Note: because pipes don't allow random access, the structure of a zipfile
// created into a pipe is slightly different from that created into a file
// or memory. In particular, the compressed-size of the item cannot be
// stored in the zipfile until after the item itself. (Also, for an item added
// itself via a pipe, the uncompressed-size might not either be known until
// after.) This is not normally a problem. But if you try to unzip via a pipe
// as well, then the unzipper will not know these things about the item until
// after it has been unzipped. Therefore: for unzippers which don't just write
// each item to disk or to a pipe, but instead pre-allocate memory space into
// which to unzip them, then either you have to create the zip not to a pipe,
// or you have to add items not from a pipe, or at least when adding items
// from a pipe you have to specify the length.
///////////////////////////////////////////////////////////////////////////////
//
// ZipAdd()
//
// Purpose: Add a file to a zip archive
//
// Parameters: hz - handle to an open zip archive
// dstzn - name used inside the zip archive to identify the file
// src - for a file (ZIP_FILENAME) this specifies the filename
// to be added to the archive; for other uses, see below
// len - for memory (ZIP_MEMORY) this specifies the buffer
// length; for other uses, this should be 0
// flags - indicates usage, see below; for files, this will be
// ZIP_FILENAME
//
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
//
ZRESULT ZipAdd(HZIP hz, const TCHAR *dstzn, void *src, unsigned int len, DWORD flags);
// ZipAdd - call this for each file to be added to the zip.
// dstzn is the name that the file will be stored as in the zip file.
// The file to be added to the zip can come
// from a pipe: ZipAdd(hz,"file.dat", hpipe_read,0,ZIP_HANDLE);
// from a file: ZipAdd(hz,"file.dat", hfile,0,ZIP_HANDLE);
// from a fname: ZipAdd(hz,"file.dat", "c:\\docs\\origfile.dat",0,ZIP_FILENAME);
// from memory: ZipAdd(hz,"subdir\\file.dat", buf,len,ZIP_MEMORY);
// (folder): ZipAdd(hz,"subdir", 0,0,ZIP_FOLDER);
// Note: if adding an item from a pipe, and if also creating the zip file itself
// to a pipe, then you might wish to pass a non-zero length to the ZipAdd
// function. This will let the zipfile store the items size ahead of the
// compressed item itself, which in turn makes it easier when unzipping the
// zipfile into a pipe.
///////////////////////////////////////////////////////////////////////////////
//
// CloseZip()
//
// Purpose: Close an open zip archive
//
// Parameters: hz - handle to an open zip archive
//
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
//
ZRESULT CloseZip(HZIP hz);
// CloseZip - the zip handle must be closed with this function.
ZRESULT ZipGetMemory(HZIP hz, void **buf, unsigned long *len);
// ZipGetMemory - If the zip was created in memory, via ZipCreate(0,ZIP_MEMORY),
// then this function will return information about that memory block.
// buf will receive a pointer to its start, and len its length.
// Note: you can't add any more after calling this.
unsigned int FormatZipMessage(ZRESULT code, char *buf,unsigned int len);
// FormatZipMessage - given an error code, formats it as a string.
// It returns the length of the error message. If buf/len points
// to a real buffer, then it also writes as much as possible into there.
// These are the result codes:
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
// The following come from general system stuff (e.g. files not openable)
#define ZR_GENMASK 0x0000FF00
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
#define ZR_WRITE 0x00000400 // a general error writing to the file
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
#define ZR_READ 0x00000800 // a general error reading the file
// The following come from mistakes on the part of the caller
#define ZR_CALLERMASK 0x00FF0000
#define ZR_ARGS 0x00010000 // general mistake with the arguments
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
// The following come from bugs within the zip library itself
#define ZR_BUGMASK 0xFF000000
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
// e.g.
//
// (1) Traditional use, creating a zipfile from existing files
// HZIP hz = CreateZip("c:\\temp.zip",0,ZIP_FILENAME);
// ZipAdd(hz,"src1.txt", "c:\\src1.txt",0,ZIP_FILENAME);
// ZipAdd(hz,"src2.bmp", "c:\\src2_origfn.bmp",0,ZIP_FILENAME);
// CloseZip(hz);
//
// (2) Memory use, creating an auto-allocated mem-based zip file from various sources
// HZIP hz = CreateZip(0,100000,ZIP_MEMORY);
// // adding a conventional file...
// ZipAdd(hz,"src1.txt", "c:\\src1.txt",0,ZIP_FILENAME);
// // adding something from memory...
// char buf[1000]; for (int i=0; i<1000; i++) buf[i]=(char)(i&0x7F);
// ZipAdd(hz,"file.dat", buf,1000,ZIP_MEMORY);
// // adding something from a pipe...
// HANDLE hread,hwrite; CreatePipe(&hread,&write,NULL,0);
// HANDLE hthread = CreateThread(ThreadFunc,(void*)hwrite);
// ZipAdd(hz,"unz3.dat", hread,0,ZIP_HANDLE);
// WaitForSingleObject(hthread,INFINITE);
// CloseHandle(hthread); CloseHandle(hread);
// ... meanwhile DWORD CALLBACK ThreadFunc(void *dat)
// { HANDLE hwrite = (HANDLE)dat;
// char buf[1000]={17};
// DWORD writ; WriteFile(hwrite,buf,1000,&writ,NULL);
// CloseHandle(hwrite);
// return 0;
// }
// // and now that the zip is created, let's do something with it:
// void *zbuf; unsigned long zlen; ZipGetMemory(hz,&zbuf,&zlen);
// HANDLE hfz = CreateFile("test2.zip",GENERIC_WRITE,CREATE_ALWAYS);
// DWORD writ; WriteFile(hfz,zbuf,zlen,&writ,NULL);
// CloseHandle(hfz);
// CloseZip(hz);
//
// (3) Handle use, for file handles and pipes
// HANDLE hzread,hzwrite; CreatePipe(&hzread,&hzwrite);
// HANDLE hthread = CreateThread(ZipReceiverThread,(void*)hread);
// HZIP hz = ZipCreate(hzwrite,ZIP_HANDLE);
// // ... add to it
// CloseZip(hz);
// CloseHandle(hzwrite);
// WaitForSingleObject(hthread,INFINITE);
// CloseHandle(hthread);
// ... meanwhile DWORD CALLBACK ThreadFunc(void *dat)
// { HANDLE hread = (HANDLE)dat;
// char buf[1000];
// while (true)
// { DWORD red; ReadFile(hread,buf,1000,&red,NULL);
// // ... and do something with this zip data we're receiving
// if (red==0) break;
// }
// CloseHandle(hread);
// return 0;
// }
//
// Now we indulge in a little skullduggery so that the code works whether
// the user has included just zip or both zip and unzip.
// Idea: if header files for both zip and unzip are present, then presumably
// the cpp files for zip and unzip are both present, so we will call
// one or the other of them based on a dynamic choice. If the header file
// for only one is present, then we will bind to that particular one.
HZIP CreateZipZ(void *z,unsigned int len,DWORD flags);
ZRESULT CloseZipZ(HZIP hz);
unsigned int FormatZipMessageZ(ZRESULT code, char *buf,unsigned int len);
bool IsZipHandleZ(HZIP hz);
BOOL AddFolderContent(HZIP hZip, TCHAR* AbsolutePath, TCHAR* DirToAdd);
#define CreateZip CreateZipZ
#ifdef XUNZIP_H
#undef CloseZip
#define CloseZip(hz) (IsZipHandleZ(hz)?CloseZipZ(hz):CloseZipU(hz))
#else
#define CloseZip CloseZipZ
#define FormatZipMessage FormatZipMessageZ
#endif
#endif //XZIP_H

31
src/Common/libzip/LICENSE Normal file
View File

@@ -0,0 +1,31 @@
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

159
src/Common/libzip/NEWS.md Normal file
View File

@@ -0,0 +1,159 @@
1.1.3 [2016-05-28]
==================
* Fix build on Windows when using autoconf.
1.1.2 [2016-02-19]
==================
* Improve support for 3MF files
1.1.1 [2016-02-07]
==================
* Build fixes for Linux
* Fix some warnings reported by PVS-Studio
1.1 [2016-01-26]
================
* ziptool(1): command line tool to modify zip archives
* Speedups for archives with many entries
* Coverity fixes
* Better APK support
* Support for running tests on Windows
* More build fixes for Windows
* Portability fixes
* Documentation improvements
1.0.1 [2015-05-04]
==================
* Build fixes for Windows.
1.0 [2015-05-03]
================
* Implemented an I/O abstraction layer.
* Added support for native Windows API for files.
* Added support for setting the last modification time for a file.
* Added a new type zip_error_t for errors.
* Added more typedefs for structs.
* Torrentzip support was removed.
* CVE-2015-2331 was fixed.
* Addressed all Coverity CIDs.
0.11.2 [2013-12-19]
===================
* Support querying/setting operating system and external attributes.
* For newly added files, set operating system to UNIX, permissions
to 0666 (0777 for directories).
* Fix bug when writing zip archives containing files bigger than 4GB.
0.11.1 [2013-04-27]
===================
* Fix bugs in zip_set_file_compression().
* Include Xcode build infrastructure.
0.11 [2013-03-23]
=================
* Added Zip64 support (large file support)
* Added UTF-8 support for file names, file comments, and archive comments
* Changed API for name and comment related functions for UTF-8 support
* Added zip_discard()
* Added ZIP_TRUNCATE for zip_open()
* Added zip_set_file_compression()
* Added API for accessing and modifying extra fields
* Improved API type consistency
* Use gcc4's visibility __attribute__
* More changes for Windows support
* Additional test cases
0.10.1 [2012-03-20]
===================
* Fixed CVE-2012-1162
* Fixed CVE-2012-1163
0.10 [2010-03-18]
=================
* Added zip_get_num_entries(), deprecated zip_get_num_files().
* Better windows support.
* Support for traditional PKWARE encryption added.
* Fix opening archives with more than 65535 entries.
* Fix some memory leaks.
* Fix cmake build and installation
* Fix memory leak in error case in zip_open()
* Fixed CVE-2011-0421 (no security implications though)
* More documentation.
0.9.3 [2010-02-01]
==================
* Include m4/ directory in distribution; some packagers need it.
0.9.2 [2010-01-31]
==================
* Avoid passing uninitialized data to deflate().
* Fix memory leak when closing zip archives.
0.9.1 [2010-01-24]
==================
* Fix infinite loop on reading some broken files.
* Optimization in time conversion (don't call localtime()).
* Clear data descriptor flag in central directory, fixing Open Office files.
* Allow more than 64k entries.
0.9 [2008-07-25]
==================
* on Windows, explictly set dllimport/dllexport
* remove erroneous references to GPL
* add support for torrentzip
* new functions: zip_get_archive_flag, zip_set_archive_flag
* zip_source_zip: add flag to force recompression
* zip_sorce_file: only keep file open while reading from it
0.8 [2007-06-06]
==================
* fix for zip archives larger than 2GiB
* fix zip_error_strerror to include libzip error string
* add support for reading streamed zip files
* new functions: zip_add_dir, zip_error_clear, zip_file_error_clear
* add basic support for building with CMake (incomplete)
0.7.1 [2006-05-18]
==================
* bugfix for zip_close
0.7 [2006-05-06]
================
* struct zip_stat increased for future encryption support
* zip_add return value changed (now returns new index of added file)
* shared library major bump because of previous two
* added functions for reading and writing file and archive comments.
New functions: zip_get_archive_comment, zip_get_file_comment,
zip_set_archive_comment, zip_set_file_comment, zip_unchange_archive
0.6.1 [2005-07-14]
==================
* various bug fixes
0.6 [2005-06-09]
================
* first standalone release
* changed license to three-clause BSD
* overhauled API
* added man pages
* install zipcmp and zipmerge

181
src/Common/libzip/compat.h Normal file
View File

@@ -0,0 +1,181 @@
#ifndef _HAD_LIBZIP_COMPAT_H
#define _HAD_LIBZIP_COMPAT_H
/*
compat.h -- compatibility defines.
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* to have *_MAX definitions for all types when compiling with g++ */
#define __STDC_LIMIT_MACROS
#ifdef _WIN32
#define ZIP_EXTERN __declspec(dllexport)
/* for dup(), close(), etc. */
#include <io.h>
#endif
#ifdef HAVE_STDBOOL_H
#include <stdbool.h>
#else
typedef char bool;
#define true 1
#define false 0
#endif
#include <errno.h>
/* at least MinGW does not provide EOPNOTSUPP, see
* http://sourceforge.net/p/mingw/bugs/263/
*/
#ifndef EOPNOTSUPP
#define EOPNOTSUPP EINVAL
#endif
/* at least MinGW does not provide EOVERFLOW, see
* http://sourceforge.net/p/mingw/bugs/242/
*/
#ifndef EOVERFLOW
#define EOVERFLOW EFBIG
#endif
#ifdef _WIN32
#if defined(HAVE__CLOSE)
#define close _close
#endif
#if defined(HAVE__DUP)
#define dup _dup
#endif
/* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */
#if defined(HAVE__FDOPEN)
#define fdopen _fdopen
#endif
#if !defined(HAVE_FILENO) && defined(HAVE__FILENO)
#define fileno _fileno
#endif
/* Windows' open() doesn't understand Unix permissions */
#if defined(HAVE__OPEN)
#define open(a, b, c) _open((a), (b))
#endif
#if defined(HAVE__SNPRINTF)
#define snprintf _snprintf
#endif
#if defined(HAVE__STRDUP)
#if !defined(HAVE_STRDUP) || defined(_WIN32)
#undef strdup
#define strdup _strdup
#endif
#endif
#if !defined(HAVE__SETMODE) && defined(HAVE_SETMODE)
#define _setmode setmode
#endif
#endif
#ifndef HAVE_FSEEKO
#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
#endif
#ifndef HAVE_FTELLO
#define ftello(s) ((long)ftell((s)))
#endif
#ifndef HAVE_MKSTEMP
int _zip_mkstemp(char *);
#define mkstemp _zip_mkstemp
#endif
#if !defined(HAVE_STRCASECMP)
#if defined(HAVE__STRICMP)
#define strcasecmp _stricmp
#elif defined(HAVE_STRICMP)
#define strcasecmp stricmp
#endif
#endif
#if SIZEOF_OFF_T == 8
#define ZIP_OFF_MAX ZIP_INT64_MAX
#define ZIP_OFF_MIN ZIP_INT64_MIN
#elif SIZEOF_OFF_T == 4
#define ZIP_OFF_MAX ZIP_INT32_MAX
#define ZIP_OFF_MIN ZIP_INT32_MIN
#elif SIZEOF_OFF_T == 2
#define ZIP_OFF_MAX ZIP_INT16_MAX
#define ZIP_OFF_MIN ZIP_INT16_MIN
#else
#error unsupported size of off_t
#endif
#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
#define ZIP_FSEEK_MAX ZIP_OFF_MAX
#define ZIP_FSEEK_MIN ZIP_OFF_MIN
#else
#include <limits.h>
#define ZIP_FSEEK_MAX LONG_MAX
#define ZIP_FSEEK_MIN LONG_MIN
#endif
#ifndef SIZE_MAX
#if SIZEOF_SIZE_T == 8
#define SIZE_MAX ZIP_INT64_MAX
#elif SIZEOF_SIZE_T == 4
#define SIZE_MAX ZIP_INT32_MAX
#elif SIZEOF_SIZE_T == 2
#define SIZE_MAX ZIP_INT16_MAX
#else
#error unsupported size of size_t
#endif
#endif
#ifndef PRId64
#ifdef _MSC_VER
#define PRId64 "I64d"
#else
#define PRId64 "lld"
#endif
#endif
#ifndef PRIu64
#ifdef _MSC_VER
#define PRIu64 "I64u"
#else
#define PRIu64 "llu"
#endif
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#endif /* compat.h */

View File

@@ -0,0 +1,72 @@
#ifndef HAD_CONFIG_H
#define HAD_CONFIG_H
#ifndef _HAD_ZIPCONF_H
#include "zipconf.h"
#endif
/* BEGIN DEFINES */
/* #undef HAVE___PROGNAME */
#define HAVE__CLOSE
#define HAVE__DUP
#define HAVE__FDOPEN
#define HAVE__FILENO
#define HAVE__OPEN
#define HAVE__SETMODE
#define HAVE__SNPRINTF
#define HAVE__STRDUP
#define HAVE__STRICMP
#define HAVE_FILENO
/* #undef HAVE_FSEEKO */
/* #undef HAVE_FTELLO */
/* #undef HAVE_GETPROGNAME */
#define HAVE_OPEN
/* #undef HAVE_MKSTEMP */
#define HAVE_SETMODE
/* #undef HAVE_SNPRINTF */
/* #undef HAVE_SSIZE_T_LIBZIP */
/* #undef HAVE_STRCASECMP */
#define HAVE_STRDUP
#define HAVE_STRICMP
/* #undef HAVE_STRUCT_TM_TM_ZONE */
/* #undef HAVE_STDBOOL_H */
/* #undef HAVE_STRINGS_H */
/* #undef HAVE_UNISTD_H */
#define __INT8_LIBZIP 1
#define INT8_T_LIBZIP 1
#define UINT8_T_LIBZIP 1
#define __INT16_LIBZIP 2
#define INT16_T_LIBZIP 2
#define UINT16_T_LIBZIP 2
#define __INT32_LIBZIP 4
#define INT32_T_LIBZIP 4
#define UINT32_T_LIBZIP 4
#define __INT64_LIBZIP 8
#define INT64_T_LIBZIP 8
#define UINT64_T_LIBZIP 8
#define SIZEOF_OFF_T 4
#ifdef _WIN64
#define SIZE_T_LIBZIP 8
#else
#define SIZE_T_LIBZIP 4
#endif
/* #undef SSIZE_T_LIBZIP */
/* #undef HAVE_DIRENT_H */
/* #undef HAVE_NDIR_H */
/* #undef HAVE_SYS_DIR_H */
/* #undef HAVE_SYS_NDIR_H */
/* END DEFINES */
#define PACKAGE "libzip"
#define VERSION "1.1.3"
#ifndef HAVE_SSIZE_T_LIBZIP
# if SIZE_T_LIBZIP == INT_LIBZIP
typedef int ssize_t;
# elif SIZE_T_LIBZIP == LONG_LIBZIP
typedef long ssize_t;
# elif SIZE_T_LIBZIP == LONG_LONG_LIBZIP
typedef long long ssize_t;
# else
#error no suitable type for ssize_t found
# endif
#endif
#endif /* HAD_CONFIG_H */

150
src/Common/libzip/mkstemp.c Normal file
View File

@@ -0,0 +1,150 @@
/* Adapted from NetBSB libc by Dieter Baron */
/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */
/*
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifndef O_BINARY
#define O_BINARY 0
#endif
int
_zip_mkstemp(char *path)
{
#ifdef _WIN32
int ret;
ret = _creat(_mktemp(path), _S_IREAD|_S_IWRITE);
if (ret == -1) {
return 0;
} else {
return ret;
}
#else
int fd;
char *start, *trv;
struct stat sbuf;
pid_t pid;
/* To guarantee multiple calls generate unique names even if
the file is not created. 676 different possibilities with 7
or more X's, 26 with 6 or less. */
static char xtra[2] = "aa";
int xcnt = 0;
pid = getpid();
/* Move to end of path and count trailing X's. */
for (trv = path; *trv; ++trv)
if (*trv == 'X')
xcnt++;
else
xcnt = 0;
/* Use at least one from xtra. Use 2 if more than 6 X's. */
if (*(trv - 1) == 'X')
*--trv = xtra[0];
if (xcnt > 6 && *(trv - 1) == 'X')
*--trv = xtra[1];
/* Set remaining X's to pid digits with 0's to the left. */
while (*--trv == 'X') {
*trv = (pid % 10) + '0';
pid /= 10;
}
/* update xtra for next call. */
if (xtra[0] != 'z')
xtra[0]++;
else {
xtra[0] = 'a';
if (xtra[1] != 'z')
xtra[1]++;
else
xtra[1] = 'a';
}
/*
* check the target directory; if you have six X's and it
* doesn't exist this runs for a *very* long time.
*/
for (start = trv + 1;; --trv) {
if (trv <= path)
break;
if (*trv == '/') {
*trv = '\0';
if (stat(path, &sbuf))
return (0);
if (!S_ISDIR(sbuf.st_mode)) {
errno = ENOTDIR;
return (0);
}
*trv = '/';
break;
}
}
for (;;) {
if ((fd=open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0)
return (fd);
if (errno != EEXIST)
return (0);
/* tricky little algorithm for backward compatibility */
for (trv = start;;) {
if (!*trv)
return (0);
if (*trv == 'z')
*trv++ = 'a';
else {
if (isdigit((unsigned char)*trv))
*trv = 'a';
else
++*trv;
break;
}
}
}
/*NOTREACHED*/
#endif
}

422
src/Common/libzip/zip.h Normal file
View File

@@ -0,0 +1,422 @@
#ifndef _HAD_ZIP_H
#define _HAD_ZIP_H
/*
zip.h -- exported declarations.
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ZIP_EXTERN
# ifndef ZIP_STATIC
# ifdef _WIN32
# define ZIP_EXTERN __declspec(dllimport)
# elif defined(__GNUC__) && __GNUC__ >= 4
# define ZIP_EXTERN __attribute__ ((visibility ("default")))
# else
# define ZIP_EXTERN
# endif
# else
# define ZIP_EXTERN
# endif
#endif
#ifdef __cplusplus
extern "C" {
#if 0
} /* fix autoindent */
#endif
#endif
#include <zipconf.h>
#include <sys/types.h>
#include <stdio.h>
#include <time.h>
/* flags for zip_open */
#define ZIP_CREATE 1
#define ZIP_EXCL 2
#define ZIP_CHECKCONS 4
#define ZIP_TRUNCATE 8
#define ZIP_RDONLY 16
/* flags for zip_name_locate, zip_fopen, zip_stat, ... */
#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */
#define ZIP_FL_NODIR 2u /* ignore directory component */
#define ZIP_FL_COMPRESSED 4u /* read compressed data */
#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */
#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */
#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */
#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */
#define ZIP_FL_ENC_RAW 64u /* get unmodified string */
#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */
#define ZIP_FL_LOCAL 256u /* in local header */
#define ZIP_FL_CENTRAL 512u /* in central directory */
/* 1024u reserved for internal use */
#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */
#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */
#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */
/* archive global flags flags */
#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */
/* create a new extra field */
#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX
#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX
/* libzip error codes */
#define ZIP_ER_OK 0 /* N No error */
#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */
#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */
#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */
#define ZIP_ER_SEEK 4 /* S Seek error */
#define ZIP_ER_READ 5 /* S Read error */
#define ZIP_ER_WRITE 6 /* S Write error */
#define ZIP_ER_CRC 7 /* N CRC error */
#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */
#define ZIP_ER_NOENT 9 /* N No such file */
#define ZIP_ER_EXISTS 10 /* N File already exists */
#define ZIP_ER_OPEN 11 /* S Can't open file */
#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */
#define ZIP_ER_ZLIB 13 /* Z Zlib error */
#define ZIP_ER_MEMORY 14 /* N Malloc failure */
#define ZIP_ER_CHANGED 15 /* N Entry has been changed */
#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */
#define ZIP_ER_EOF 17 /* N Premature end of file */
#define ZIP_ER_INVAL 18 /* N Invalid argument */
#define ZIP_ER_NOZIP 19 /* N Not a zip archive */
#define ZIP_ER_INTERNAL 20 /* N Internal error */
#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */
#define ZIP_ER_REMOVE 22 /* S Can't remove file */
#define ZIP_ER_DELETED 23 /* N Entry has been deleted */
#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */
#define ZIP_ER_RDONLY 25 /* N Read-only archive */
#define ZIP_ER_NOPASSWD 26 /* N No password provided */
#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */
#define ZIP_ER_OPNOTSUPP 28 /* N Operation not supported */
#define ZIP_ER_INUSE 29 /* N Resource still in use */
#define ZIP_ER_TELL 30 /* S Tell error */
/* type of system error value */
#define ZIP_ET_NONE 0 /* sys_err unused */
#define ZIP_ET_SYS 1 /* sys_err is errno */
#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */
/* compression methods */
#define ZIP_CM_DEFAULT -1 /* better of deflate or store */
#define ZIP_CM_STORE 0 /* stored (uncompressed) */
#define ZIP_CM_SHRINK 1 /* shrunk */
#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */
#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */
#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */
#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */
#define ZIP_CM_IMPLODE 6 /* imploded */
/* 7 - Reserved for Tokenizing compression algorithm */
#define ZIP_CM_DEFLATE 8 /* deflated */
#define ZIP_CM_DEFLATE64 9 /* deflate64 */
#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */
/* 11 - Reserved by PKWARE */
#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */
/* 13 - Reserved by PKWARE */
#define ZIP_CM_LZMA 14 /* LZMA (EFS) */
/* 15-17 - Reserved by PKWARE */
#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */
#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */
#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */
#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */
/* encryption methods */
#define ZIP_EM_NONE 0 /* not encrypted */
#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */
#if 0 /* Strong Encryption Header not parsed yet */
#define ZIP_EM_DES 0x6601 /* strong encryption: DES */
#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */
#define ZIP_EM_3DES_168 0x6603
#define ZIP_EM_3DES_112 0x6609
#define ZIP_EM_AES_128 0x660e
#define ZIP_EM_AES_192 0x660f
#define ZIP_EM_AES_256 0x6610
#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */
#define ZIP_EM_RC4 0x6801
#endif
#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */
#define ZIP_OPSYS_DOS 0x00u
#define ZIP_OPSYS_AMIGA 0x01u
#define ZIP_OPSYS_OPENVMS 0x02u
#define ZIP_OPSYS_UNIX 0x03u
#define ZIP_OPSYS_VM_CMS 0x04u
#define ZIP_OPSYS_ATARI_ST 0x05u
#define ZIP_OPSYS_OS_2 0x06u
#define ZIP_OPSYS_MACINTOSH 0x07u
#define ZIP_OPSYS_Z_SYSTEM 0x08u
#define ZIP_OPSYS_CPM 0x09u
#define ZIP_OPSYS_WINDOWS_NTFS 0x0au
#define ZIP_OPSYS_MVS 0x0bu
#define ZIP_OPSYS_VSE 0x0cu
#define ZIP_OPSYS_ACORN_RISC 0x0du
#define ZIP_OPSYS_VFAT 0x0eu
#define ZIP_OPSYS_ALTERNATE_MVS 0x0fu
#define ZIP_OPSYS_BEOS 0x10u
#define ZIP_OPSYS_TANDEM 0x11u
#define ZIP_OPSYS_OS_400 0x12u
#define ZIP_OPSYS_OS_X 0x13u
#define ZIP_OPSYS_DEFAULT ZIP_OPSYS_UNIX
enum zip_source_cmd {
ZIP_SOURCE_OPEN, /* prepare for reading */
ZIP_SOURCE_READ, /* read data */
ZIP_SOURCE_CLOSE, /* reading is done */
ZIP_SOURCE_STAT, /* get meta information */
ZIP_SOURCE_ERROR, /* get error information */
ZIP_SOURCE_FREE, /* cleanup and free resources */
ZIP_SOURCE_SEEK, /* set position for reading */
ZIP_SOURCE_TELL, /* get read position */
ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */
ZIP_SOURCE_COMMIT_WRITE, /* writing is done */
ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */
ZIP_SOURCE_WRITE, /* write data */
ZIP_SOURCE_SEEK_WRITE, /* set position for writing */
ZIP_SOURCE_TELL_WRITE, /* get write position */
ZIP_SOURCE_SUPPORTS, /* check whether source supports command */
ZIP_SOURCE_REMOVE /* remove file */
};
typedef enum zip_source_cmd zip_source_cmd_t;
#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (1<<(cmd))
#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_CLOSE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_STAT) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ERROR) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_FREE))
#define ZIP_SOURCE_SUPPORTS_SEEKABLE (ZIP_SOURCE_SUPPORTS_READABLE \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS))
#define ZIP_SOURCE_SUPPORTS_WRITABLE (ZIP_SOURCE_SUPPORTS_SEEKABLE \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_COMMIT_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ROLLBACK_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE))
/* for use by sources */
struct zip_source_args_seek {
zip_int64_t offset;
int whence;
};
typedef struct zip_source_args_seek zip_source_args_seek_t;
#define ZIP_SOURCE_GET_ARGS(type, data, len, error) ((len) < sizeof(type) ? zip_error_set((error), ZIP_ER_INVAL, 0), (type *)NULL : (type *)(data))
/* error information */
/* use zip_error_*() to access */
struct zip_error {
int zip_err; /* libzip error code (ZIP_ER_*) */
int sys_err; /* copy of errno (E*) or zlib error code */
char *str; /* string representation or NULL */
};
#define ZIP_STAT_NAME 0x0001u
#define ZIP_STAT_INDEX 0x0002u
#define ZIP_STAT_SIZE 0x0004u
#define ZIP_STAT_COMP_SIZE 0x0008u
#define ZIP_STAT_MTIME 0x0010u
#define ZIP_STAT_CRC 0x0020u
#define ZIP_STAT_COMP_METHOD 0x0040u
#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u
#define ZIP_STAT_FLAGS 0x0100u
struct zip_stat {
zip_uint64_t valid; /* which fields have valid values */
const char *name; /* name of the file */
zip_uint64_t index; /* index within archive */
zip_uint64_t size; /* size of file (uncompressed) */
zip_uint64_t comp_size; /* size of file (compressed) */
time_t mtime; /* modification time */
zip_uint32_t crc; /* crc of file data */
zip_uint16_t comp_method; /* compression method used */
zip_uint16_t encryption_method; /* encryption method used */
zip_uint32_t flags; /* reserved for future use */
};
struct zip;
struct zip_file;
struct zip_source;
typedef struct zip zip_t;
typedef struct zip_error zip_error_t;
typedef struct zip_file zip_file_t;
typedef struct zip_source zip_source_t;
typedef struct zip_stat zip_stat_t;
typedef zip_uint32_t zip_flags_t;
typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, zip_source_cmd_t);
#ifndef ZIP_DISABLE_DEPRECATED
ZIP_EXTERN zip_int64_t zip_add(zip_t *, const char *, zip_source_t *); /* use zip_file_add */
ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *, const char *); /* use zip_dir_add */
ZIP_EXTERN const char *zip_get_file_comment(zip_t *, zip_uint64_t, int *, int); /* use zip_file_get_comment */
ZIP_EXTERN int zip_get_num_files(zip_t *); /* use zip_get_num_entries instead */
ZIP_EXTERN int zip_rename(zip_t *, zip_uint64_t, const char *); /* use zip_file_rename */
ZIP_EXTERN int zip_replace(zip_t *, zip_uint64_t, zip_source_t *); /* use zip_file_replace */
ZIP_EXTERN int zip_set_file_comment(zip_t *, zip_uint64_t, const char *, int); /* use zip_file_set_comment */
ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */
ZIP_EXTERN void zip_error_get(zip_t *, int *, int *); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */
ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int);
ZIP_EXTERN void zip_file_error_get(zip_file_t *, int *, int *); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */
#endif
ZIP_EXTERN int zip_archive_set_tempdir(zip_t *, const char *);
ZIP_EXTERN int zip_close(zip_t *);
ZIP_EXTERN int zip_delete(zip_t *, zip_uint64_t);
ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *, const char *, zip_flags_t);
ZIP_EXTERN void zip_discard(zip_t *);
ZIP_EXTERN zip_error_t *zip_get_error(zip_t *);
ZIP_EXTERN void zip_error_clear(zip_t *);
ZIP_EXTERN int zip_error_code_zip(const zip_error_t *);
ZIP_EXTERN int zip_error_code_system(const zip_error_t *);
ZIP_EXTERN void zip_error_fini(zip_error_t *);
ZIP_EXTERN void zip_error_init(zip_error_t *);
ZIP_EXTERN void zip_error_init_with_code(zip_error_t *, int);
ZIP_EXTERN void zip_error_set(zip_error_t *, int, int);
ZIP_EXTERN const char *zip_error_strerror(zip_error_t *);
ZIP_EXTERN int zip_error_system_type(const zip_error_t *);
ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *, void *, zip_uint64_t);
ZIP_EXTERN int zip_fclose(zip_file_t *);
ZIP_EXTERN zip_t *zip_fdopen(int, int, int *);
ZIP_EXTERN zip_int64_t zip_file_add(zip_t *, const char *, zip_source_t *, zip_flags_t);
ZIP_EXTERN void zip_file_error_clear(zip_file_t *);
ZIP_EXTERN int zip_file_extra_field_delete(zip_t *, zip_uint64_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_extra_field_set(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t, zip_flags_t);
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *, zip_flags_t);
ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *, zip_flags_t);
ZIP_EXTERN const char *zip_file_get_comment(zip_t *, zip_uint64_t, zip_uint32_t *, zip_flags_t);
ZIP_EXTERN zip_error_t *zip_file_get_error(zip_file_t *);
ZIP_EXTERN int zip_file_get_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t *, zip_uint32_t *);
ZIP_EXTERN int zip_file_rename(zip_t *, zip_uint64_t, const char *, zip_flags_t);
ZIP_EXTERN int zip_file_replace(zip_t *, zip_uint64_t, zip_source_t *, zip_flags_t);
ZIP_EXTERN int zip_file_set_comment(zip_t *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_set_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
ZIP_EXTERN int zip_file_set_mtime(zip_t *, zip_uint64_t, time_t, zip_flags_t);
ZIP_EXTERN const char *zip_file_strerror(zip_file_t *);
ZIP_EXTERN zip_file_t *zip_fopen(zip_t *, const char *, zip_flags_t);
ZIP_EXTERN zip_file_t *zip_fopen_encrypted(zip_t *, const char *, zip_flags_t, const char *);
ZIP_EXTERN zip_file_t *zip_fopen_index(zip_t *, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_file_t *zip_fopen_index_encrypted(zip_t *, zip_uint64_t, zip_flags_t, const char *);
ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *, void *, zip_uint64_t);
ZIP_EXTERN const char *zip_get_archive_comment(zip_t *, int *, zip_flags_t);
ZIP_EXTERN int zip_get_archive_flag(zip_t *, zip_flags_t, zip_flags_t);
ZIP_EXTERN const char *zip_get_name(zip_t *, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *, zip_flags_t);
ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *, const char *, zip_flags_t);
ZIP_EXTERN zip_t *zip_open(const char *, int, int *);
ZIP_EXTERN zip_t *zip_open_from_source(zip_source_t *, int, zip_error_t *);
ZIP_EXTERN int zip_set_archive_comment(zip_t *, const char *, zip_uint16_t);
ZIP_EXTERN int zip_set_archive_flag(zip_t *, zip_flags_t, int);
ZIP_EXTERN int zip_set_default_password(zip_t *, const char *);
ZIP_EXTERN int zip_set_file_compression(zip_t *, zip_uint64_t, zip_int32_t, zip_uint32_t);
ZIP_EXTERN int zip_source_begin_write(zip_source_t *);
ZIP_EXTERN zip_source_t *zip_source_buffer(zip_t *, const void *, zip_uint64_t, int);
ZIP_EXTERN zip_source_t *zip_source_buffer_create(const void *, zip_uint64_t, int, zip_error_t *);
ZIP_EXTERN int zip_source_close(zip_source_t *);
ZIP_EXTERN int zip_source_commit_write(zip_source_t *);
ZIP_EXTERN zip_error_t *zip_source_error(zip_source_t *src);
ZIP_EXTERN zip_source_t *zip_source_file(zip_t *, const char *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_file_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
ZIP_EXTERN zip_source_t *zip_source_filep(zip_t *, FILE *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_filep_create(FILE *, zip_uint64_t, zip_int64_t, zip_error_t *);
ZIP_EXTERN void zip_source_free(zip_source_t *);
ZIP_EXTERN zip_source_t *zip_source_function(zip_t *, zip_source_callback, void *);
ZIP_EXTERN zip_source_t *zip_source_function_create(zip_source_callback, void *, zip_error_t *);
ZIP_EXTERN int zip_source_is_deleted(zip_source_t *);
ZIP_EXTERN void zip_source_keep(zip_source_t *);
ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t, ...);
ZIP_EXTERN int zip_source_open(zip_source_t *);
ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *, void *, zip_uint64_t);
ZIP_EXTERN void zip_source_rollback_write(zip_source_t *);
ZIP_EXTERN int zip_source_seek(zip_source_t *, zip_int64_t, int);
ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *, zip_uint64_t, zip_error_t *);
ZIP_EXTERN int zip_source_seek_write(zip_source_t *, zip_int64_t, int);
ZIP_EXTERN int zip_source_stat(zip_source_t *, zip_stat_t *);
ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *);
ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *);
#ifdef _WIN32
ZIP_EXTERN zip_source_t *zip_source_win32a(zip_t *, const char *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_win32a_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
ZIP_EXTERN zip_source_t *zip_source_win32handle(zip_t *, void *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip_int64_t, zip_error_t *);
ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *);
#endif
ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *, const void *, zip_uint64_t);
ZIP_EXTERN zip_source_t *zip_source_zip(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
ZIP_EXTERN int zip_stat(zip_t *, const char *, zip_flags_t, zip_stat_t *);
ZIP_EXTERN int zip_stat_index(zip_t *, zip_uint64_t, zip_flags_t, zip_stat_t *);
ZIP_EXTERN void zip_stat_init(zip_stat_t *);
ZIP_EXTERN const char *zip_strerror(zip_t *);
ZIP_EXTERN int zip_unchange(zip_t *, zip_uint64_t);
ZIP_EXTERN int zip_unchange_all(zip_t *);
ZIP_EXTERN int zip_unchange_archive(zip_t *);
#ifdef __cplusplus
}
#endif
#endif /* _HAD_ZIP_H */

View File

@@ -0,0 +1,50 @@
/*
zip_add.c -- add file via callback function
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
/*
NOTE: Return type is signed so we can return -1 on error.
The index can not be larger than ZIP_INT64_MAX since the size
of the central directory cannot be larger than
ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
*/
ZIP_EXTERN zip_int64_t
zip_add(zip_t *za, const char *name, zip_source_t *source)
{
return zip_file_add(za, name, source, 0);
}

View File

@@ -0,0 +1,45 @@
/*
zip_add_dir.c -- add directory
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
ZIP_EXTERN zip_int64_t
zip_add_dir(zip_t *za, const char *name)
{
return zip_dir_add(za, name, 0);
}

View File

@@ -0,0 +1,81 @@
/*
zip_add_entry.c -- create and init struct zip_entry
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
zip_int64_t
_zip_add_entry(zip_t *za)
{
zip_uint64_t idx;
if (za->nentry+1 >= za->nentry_alloc) {
zip_entry_t *rentries;
zip_uint64_t nalloc = za->nentry_alloc;
zip_uint64_t additional_entries = 2 * nalloc;
zip_uint64_t realloc_size;
if (additional_entries < 16) {
additional_entries = 16;
}
else if (additional_entries > 1024) {
additional_entries = 1024;
}
/* neither + nor * overflows can happen: nentry_alloc * sizeof(struct zip_entry) < UINT64_MAX */
nalloc += additional_entries;
realloc_size = sizeof(struct zip_entry) * (size_t)nalloc;
if (sizeof(struct zip_entry) * (size_t)za->nentry_alloc > realloc_size) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
rentries = (zip_entry_t *)realloc(za->entry, sizeof(struct zip_entry) * (size_t)nalloc);
if (!rentries) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
za->entry = rentries;
za->nentry_alloc = nalloc;
}
idx = za->nentry++;
_zip_entry_init(za->entry+idx);
return (zip_int64_t)idx;
}

View File

@@ -0,0 +1,321 @@
/*
zip_buffer.c -- bounds checked access to memory buffer
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
zip_uint8_t *
_zip_buffer_data(zip_buffer_t *buffer)
{
return buffer->data;
}
void
_zip_buffer_free(zip_buffer_t *buffer)
{
if (buffer == NULL) {
return;
}
if (buffer->free_data) {
free(buffer->data);
}
free(buffer);
}
bool
_zip_buffer_eof(zip_buffer_t *buffer)
{
return buffer->ok && buffer->offset == buffer->size;
}
zip_uint8_t *
_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length)
{
zip_uint8_t *data;
if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) {
buffer->ok = false;
return NULL;
}
data = buffer->data + buffer->offset;
buffer->offset += length;
return data;
}
zip_uint16_t
_zip_buffer_get_16(zip_buffer_t *buffer)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
if (data == NULL) {
return 0;
}
return (zip_uint16_t)(data[0] + (data[1] << 8));
}
zip_uint32_t
_zip_buffer_get_32(zip_buffer_t *buffer)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
if (data == NULL) {
return 0;
}
return ((((((zip_uint32_t)data[3] << 8) + data[2]) << 8) + data[1]) << 8) + data[0];
}
zip_uint64_t
_zip_buffer_get_64(zip_buffer_t *buffer)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
if (data == NULL) {
return 0;
}
return ((zip_uint64_t)data[7] << 56) + ((zip_uint64_t)data[6] << 48) + ((zip_uint64_t)data[5] << 40) + ((zip_uint64_t)data[4] << 32) + ((zip_uint64_t)data[3] << 24) + ((zip_uint64_t)data[2] << 16) + ((zip_uint64_t)data[1] << 8) + (zip_uint64_t)data[0];
}
zip_uint8_t
_zip_buffer_get_8(zip_buffer_t *buffer)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
if (data == NULL) {
return 0;
}
return data[0];
}
zip_uint64_t
_zip_buffer_left(zip_buffer_t *buffer)
{
return buffer->ok ? buffer->size - buffer->offset : 0;
}
zip_buffer_t *
_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size)
{
bool free_data = (data == NULL);
zip_buffer_t *buffer;
if (data == NULL) {
if ((data = (zip_uint8_t *)malloc(size)) == NULL) {
return NULL;
}
}
if ((buffer = (zip_buffer_t *)malloc(sizeof(*buffer))) == NULL) {
if (free_data) {
free(data);
}
return NULL;
}
buffer->ok = true;
buffer->data = data;
buffer->size = size;
buffer->offset = 0;
buffer->free_data = free_data;
return buffer;
}
zip_buffer_t *
_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error)
{
zip_buffer_t *buffer;
if ((buffer = _zip_buffer_new(buf, size)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (_zip_read(src, buffer->data, size, error) < 0) {
_zip_buffer_free(buffer);
return NULL;
}
return buffer;
}
zip_uint64_t
_zip_buffer_offset(zip_buffer_t *buffer)
{
return buffer->ok ? buffer->offset : 0;
}
bool
_zip_buffer_ok(zip_buffer_t *buffer)
{
return buffer->ok;
}
int
_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length)
{
zip_uint8_t *dst = _zip_buffer_get(buffer, length);
if (dst == NULL) {
return -1;
}
memcpy(dst, src, length);
return 0;
}
int
_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
if (data == NULL) {
return -1;
}
data[0] = (zip_uint8_t)(i & 0xff);
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
return 0;
}
int
_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
if (data == NULL) {
return -1;
}
data[0] = (zip_uint8_t)(i & 0xff);
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
data[3] = (zip_uint8_t)((i >> 24) & 0xff);
return 0;
}
int
_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
if (data == NULL) {
return -1;
}
data[0] = (zip_uint8_t)(i & 0xff);
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
data[3] = (zip_uint8_t)((i >> 24) & 0xff);
data[4] = (zip_uint8_t)((i >> 32) & 0xff);
data[5] = (zip_uint8_t)((i >> 40) & 0xff);
data[6] = (zip_uint8_t)((i >> 48) & 0xff);
data[7] = (zip_uint8_t)((i >> 56) & 0xff);
return 0;
}
int
_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
if (data == NULL) {
return -1;
}
data[0] = i;
return 0;
}
int
_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset)
{
if (offset > buffer->size) {
buffer->ok = false;
return -1;
}
buffer->ok = true;
buffer->offset = offset;
return 0;
}
int
_zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) {
zip_uint64_t offset = buffer->offset + length;
if (offset < buffer->offset) {
buffer->ok = false;
return -1;
}
return _zip_buffer_set_offset(buffer, offset);
}
zip_uint64_t
_zip_buffer_size(zip_buffer_t *buffer)
{
return buffer->size;
}

View File

@@ -0,0 +1,492 @@
/*
zip_close.c -- close zip archive and update changes
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
#endif
/* max deflate size increase: size + ceil(size/16k)*5+6 */
#define MAX_DEFLATE_SIZE_32 4293656963u
static int add_data(zip_t *, zip_source_t *, zip_dirent_t *);
static int copy_data(zip_t *, zip_uint64_t);
static int copy_source(zip_t *, zip_source_t *);
static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
ZIP_EXTERN int
zip_close(zip_t *za)
{
zip_uint64_t i, j, survivors;
zip_int64_t off;
int error;
zip_filelist_t *filelist;
int changed;
if (za == NULL)
return -1;
changed = _zip_changed(za, &survivors);
/* don't create zip files with no entries */
if (survivors == 0) {
if ((za->open_flags & ZIP_TRUNCATE) || changed) {
if (zip_source_remove(za->src) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
}
zip_discard(za);
return 0;
}
if (!changed) {
zip_discard(za);
return 0;
}
if (survivors > za->nentry) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
if ((filelist=(zip_filelist_t *)malloc(sizeof(filelist[0])*(size_t)survivors)) == NULL)
return -1;
/* create list of files with index into original archive */
for (i=j=0; i<za->nentry; i++) {
if (za->entry[i].deleted)
continue;
if (j >= survivors) {
free(filelist);
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
filelist[j].idx = i;
j++;
}
if (j < survivors) {
free(filelist);
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
if (zip_source_begin_write(za->src) < 0) {
_zip_error_set_from_source(&za->error, za->src);
free(filelist);
return -1;
}
error = 0;
for (j=0; j<survivors; j++) {
int new_data;
zip_entry_t *entry;
zip_dirent_t *de;
i = filelist[j].idx;
entry = za->entry+i;
new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD));
/* create new local directory entry */
if (entry->changes == NULL) {
if ((entry->changes=_zip_dirent_clone(entry->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
error = 1;
break;
}
}
de = entry->changes;
if (_zip_read_local_ef(za, i) < 0) {
error = 1;
break;
}
if ((off = zip_source_tell_write(za->src)) < 0) {
error = 1;
break;
}
de->offset = (zip_uint64_t)off;
if (new_data) {
zip_source_t *zs;
zs = NULL;
if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) {
error = 1;
break;
}
}
/* add_data writes dirent */
if (add_data(za, zs ? zs : entry->source, de) < 0) {
error = 1;
if (zs)
zip_source_free(zs);
break;
}
if (zs)
zip_source_free(zs);
}
else {
zip_uint64_t offset;
/* when copying data, all sizes are known -> no data descriptor needed */
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) {
error = 1;
break;
}
if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) {
error = 1;
break;
}
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
error = 1;
break;
}
if (copy_data(za, de->comp_size) < 0) {
error = 1;
break;
}
}
}
if (!error) {
if (write_cdir(za, filelist, survivors) < 0)
error = 1;
}
free(filelist);
if (!error) {
if (zip_source_commit_write(za->src) != 0) {
_zip_error_set_from_source(&za->error, za->src);
error = 1;
}
}
if (error) {
zip_source_rollback_write(za->src);
return -1;
}
zip_discard(za);
return 0;
}
static int
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de)
{
zip_int64_t offstart, offdata, offend;
struct zip_stat st;
zip_source_t *s2;
int ret;
int is_zip64;
zip_flags_t flags;
if (zip_source_stat(src, &st) < 0) {
_zip_error_set_from_source(&za->error, src);
return -1;
}
if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
st.valid |= ZIP_STAT_COMP_METHOD;
st.comp_method = ZIP_CM_STORE;
}
if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE)
de->comp_method = st.comp_method;
else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
st.valid |= ZIP_STAT_COMP_SIZE;
st.comp_size = st.size;
}
else {
/* we'll recompress */
st.valid &= ~ZIP_STAT_COMP_SIZE;
}
flags = ZIP_EF_LOCAL;
if ((st.valid & ZIP_STAT_SIZE) == 0)
flags |= ZIP_FL_FORCE_ZIP64;
else {
de->uncomp_size = st.size;
if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) {
if (( ((de->comp_method == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(de->comp_method)) && st.size > MAX_DEFLATE_SIZE_32)
|| (de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(de->comp_method))))
flags |= ZIP_FL_FORCE_ZIP64;
}
else
de->comp_size = st.comp_size;
}
if ((offstart = zip_source_tell_write(za->src)) < 0) {
return -1;
}
/* as long as we don't support non-seekable output, clear data descriptor bit */
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
if ((is_zip64=_zip_dirent_write(za, de, flags)) < 0)
return -1;
if (st.comp_method == ZIP_CM_STORE || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != de->comp_method)) {
zip_source_t *s_store, *s_crc;
zip_compression_implementation comp_impl;
if (st.comp_method != ZIP_CM_STORE) {
if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) {
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
return -1;
}
if ((s_store=comp_impl(za, src, st.comp_method, ZIP_CODEC_DECODE)) == NULL) {
/* error set by comp_impl */
return -1;
}
}
else {
/* to have the same reference count to src as in the case where it's not stored */
zip_source_keep(src);
s_store = src;
}
s_crc = zip_source_crc(za, s_store, 0);
zip_source_free(s_store);
if (s_crc == NULL) {
return -1;
}
if (de->comp_method != ZIP_CM_STORE && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
if ((comp_impl=_zip_get_compression_implementation(de->comp_method)) == NULL) {
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
zip_source_free(s_crc);
return -1;
}
s2 = comp_impl(za, s_crc, de->comp_method, ZIP_CODEC_ENCODE);
zip_source_free(s_crc);
if (s2 == NULL) {
return -1;
}
}
else {
s2 = s_crc;
}
}
else {
zip_source_keep(src);
s2 = src;
}
if ((offdata = zip_source_tell_write(za->src)) < 0) {
return -1;
}
ret = copy_source(za, s2);
if (zip_source_stat(s2, &st) < 0)
ret = -1;
zip_source_free(s2);
if (ret < 0)
return -1;
if ((offend = zip_source_tell_write(za->src)) < 0) {
return -1;
}
if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
if ((st.valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
if (st.valid & ZIP_STAT_MTIME)
de->last_mod = st.mtime;
else
time(&de->last_mod);
}
de->comp_method = st.comp_method;
de->crc = st.crc;
de->uncomp_size = st.size;
de->comp_size = (zip_uint64_t)(offend - offdata);
if ((ret=_zip_dirent_write(za, de, flags)) < 0)
return -1;
if (is_zip64 != ret) {
/* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
return 0;
}
static int
copy_data(zip_t *za, zip_uint64_t len)
{
zip_uint8_t buf[BUFSIZE];
size_t n;
while (len > 0) {
n = len > sizeof(buf) ? sizeof(buf) : len;
if (_zip_read(za->src, buf, n, &za->error) < 0) {
return -1;
}
if (_zip_write(za, buf, n) < 0) {
return -1;
}
len -= n;
}
return 0;
}
static int
copy_source(zip_t *za, zip_source_t *src)
{
zip_uint8_t buf[BUFSIZE];
zip_int64_t n;
int ret;
if (zip_source_open(src) < 0) {
_zip_error_set_from_source(&za->error, src);
return -1;
}
ret = 0;
while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
if (_zip_write(za, buf, (zip_uint64_t)n) < 0) {
ret = -1;
break;
}
}
if (n < 0) {
_zip_error_set_from_source(&za->error, src);
ret = -1;
}
zip_source_close(src);
return ret;
}
static int
write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
{
zip_int64_t cd_start, end, size;
if ((cd_start = zip_source_tell_write(za->src)) < 0) {
return -1;
}
if ((size=_zip_cdir_write(za, filelist, survivors)) < 0) {
return -1;
}
if ((end = zip_source_tell_write(za->src)) < 0) {
return -1;
}
return 0;
}
int
_zip_changed(const zip_t *za, zip_uint64_t *survivorsp)
{
int changed;
zip_uint64_t i, survivors;
changed = 0;
survivors = 0;
if (za->comment_changed || za->ch_flags != za->flags)
changed = 1;
for (i=0; i<za->nentry; i++) {
if (za->entry[i].deleted || za->entry[i].source || (za->entry[i].changes && za->entry[i].changes->changed != 0))
changed = 1;
if (!za->entry[i].deleted)
survivors++;
}
if (survivorsp)
*survivorsp = survivors;
return changed;
}

View File

@@ -0,0 +1,70 @@
/*
zip_delete.c -- delete file from zip archive
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_delete(zip_t *za, zip_uint64_t idx)
{
const char *name;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if ((name=_zip_get_name(za, idx, 0, &za->error)) == NULL) {
return -1;
}
if (!_zip_hash_delete(za->names, (const zip_uint8_t *)name, &za->error)) {
return -1;
}
/* allow duplicate file names, because the file will
* be removed directly afterwards */
if (_zip_unchange(za, idx, 1) != 0)
return -1;
za->entry[idx].deleted = 1;
return 0;
}

View File

@@ -0,0 +1,93 @@
/*
zip_dir_add.c -- add directory
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
ZIP_EXTERN zip_int64_t
zip_dir_add(zip_t *za, const char *name, zip_flags_t flags)
{
size_t len;
zip_int64_t idx;
char *s;
zip_source_t *source;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (name == NULL) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
s = NULL;
len = strlen(name);
if (name[len-1] != '/') {
if ((s=(char *)malloc(len+2)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
strcpy(s, name);
s[len] = '/';
s[len+1] = '\0';
}
if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) {
free(s);
return -1;
}
idx = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags);
free(s);
if (idx < 0)
zip_source_free(source);
else {
if (zip_file_set_external_attributes(za, (zip_uint64_t)idx, 0, ZIP_OPSYS_DEFAULT, ZIP_EXT_ATTRIB_DEFAULT_DIR) < 0) {
zip_delete(za, (zip_uint64_t)idx);
return -1;
}
}
return idx;
}

View File

@@ -0,0 +1,913 @@
/*
zip_dirent.c -- read directory entry (local or central), clean dirent
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include "zipint.h"
static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
void
_zip_cdir_free(zip_cdir_t *cd)
{
zip_uint64_t i;
if (!cd)
return;
for (i=0; i<cd->nentry; i++)
_zip_entry_finalize(cd->entry+i);
free(cd->entry);
_zip_string_free(cd->comment);
free(cd);
}
zip_cdir_t *
_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error)
{
zip_cdir_t *cd;
zip_uint64_t i;
if ((cd=(zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (nentry == 0)
cd->entry = NULL;
else if ((nentry > SIZE_MAX/sizeof(*(cd->entry))) || (cd->entry=(zip_entry_t *)malloc(sizeof(*(cd->entry))*(size_t)nentry)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(cd);
return NULL;
}
for (i=0; i<nentry; i++)
_zip_entry_init(cd->entry+i);
cd->nentry = cd->nentry_alloc = nentry;
cd->size = cd->offset = 0;
cd->comment = NULL;
return cd;
}
zip_int64_t
_zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
{
zip_uint64_t offset, size;
zip_string_t *comment;
zip_uint8_t buf[EOCDLEN + EOCD64LEN + EOCD64LOCLEN];
zip_buffer_t *buffer;
zip_int64_t off;
zip_uint64_t i;
bool is_zip64;
int ret;
if ((off = zip_source_tell_write(za->src)) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
offset = (zip_uint64_t)off;
is_zip64 = false;
for (i=0; i<survivors; i++) {
zip_entry_t *entry = za->entry+filelist[i].idx;
if ((ret=_zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0)
return -1;
if (ret)
is_zip64 = true;
}
if ((off = zip_source_tell_write(za->src)) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
size = (zip_uint64_t)off - offset;
if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX)
is_zip64 = true;
if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
if (is_zip64) {
_zip_buffer_put(buffer, EOCD64_MAGIC, 4);
_zip_buffer_put_64(buffer, EOCD64LEN-12);
_zip_buffer_put_16(buffer, 45);
_zip_buffer_put_16(buffer, 45);
_zip_buffer_put_32(buffer, 0);
_zip_buffer_put_32(buffer, 0);
_zip_buffer_put_64(buffer, survivors);
_zip_buffer_put_64(buffer, survivors);
_zip_buffer_put_64(buffer, size);
_zip_buffer_put_64(buffer, offset);
_zip_buffer_put(buffer, EOCD64LOC_MAGIC, 4);
_zip_buffer_put_32(buffer, 0);
_zip_buffer_put_64(buffer, offset+size);
_zip_buffer_put_32(buffer, 1);
}
_zip_buffer_put(buffer, EOCD_MAGIC, 4);
_zip_buffer_put_32(buffer, 0);
_zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
_zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
_zip_buffer_put_32(buffer, size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size);
_zip_buffer_put_32(buffer, offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset);
comment = za->comment_changed ? za->comment_changes : za->comment_orig;
_zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));
if (!_zip_buffer_ok(buffer)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(buffer);
return -1;
}
if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) {
_zip_buffer_free(buffer);
return -1;
}
_zip_buffer_free(buffer);
if (comment) {
if (_zip_write(za, comment->raw, comment->length) < 0) {
return -1;
}
}
return (zip_int64_t)size;
}
zip_dirent_t *
_zip_dirent_clone(const zip_dirent_t *sde)
{
zip_dirent_t *tde;
if ((tde=(zip_dirent_t *)malloc(sizeof(*tde))) == NULL)
return NULL;
if (sde)
memcpy(tde, sde, sizeof(*sde));
else
_zip_dirent_init(tde);
tde->changed = 0;
tde->cloned = 1;
return tde;
}
void
_zip_dirent_finalize(zip_dirent_t *zde)
{
if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) {
_zip_string_free(zde->filename);
zde->filename = NULL;
}
if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) {
_zip_ef_free(zde->extra_fields);
zde->extra_fields = NULL;
}
if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) {
_zip_string_free(zde->comment);
zde->comment = NULL;
}
}
void
_zip_dirent_free(zip_dirent_t *zde)
{
if (zde == NULL)
return;
_zip_dirent_finalize(zde);
free(zde);
}
void
_zip_dirent_init(zip_dirent_t *de)
{
de->changed = 0;
de->local_extra_fields_read = 0;
de->cloned = 0;
de->version_madeby = 20 | (ZIP_OPSYS_DEFAULT << 8);
de->version_needed = 20; /* 2.0 */
de->bitflags = 0;
de->comp_method = ZIP_CM_DEFAULT;
de->last_mod = 0;
de->crc = 0;
de->comp_size = 0;
de->uncomp_size = 0;
de->filename = NULL;
de->extra_fields = NULL;
de->comment = NULL;
de->disk_number = 0;
de->int_attrib = 0;
de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
de->offset = 0;
}
bool
_zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags)
{
if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX
|| ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX))
return true;
return false;
}
zip_dirent_t *
_zip_dirent_new(void)
{
zip_dirent_t *de;
if ((de=(zip_dirent_t *)malloc(sizeof(*de))) == NULL)
return NULL;
_zip_dirent_init(de);
return de;
}
/* _zip_dirent_read(zde, fp, bufp, left, localp, error):
Fills the zip directory entry zde.
If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed.
If local is true, it reads a local header instead of a central directory entry.
Returns size of dirent read if successful. On error, error is filled in and -1 is returned.
*/
zip_int64_t
_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error)
{
zip_uint8_t buf[CDENTRYSIZE];
zip_uint16_t dostime, dosdate;
zip_uint32_t size, variable_size;
zip_uint16_t filename_len, comment_len, ef_len;
bool from_buffer = (buffer != NULL);
size = local ? LENTRYSIZE : CDENTRYSIZE;
if (buffer) {
if (_zip_buffer_left(buffer) < size) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
return -1;
}
}
else {
if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) {
return -1;
}
}
if (memcmp(_zip_buffer_get(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
/* convert buffercontents to zip_dirent */
_zip_dirent_init(zde);
if (!local)
zde->version_madeby = _zip_buffer_get_16(buffer);
else
zde->version_madeby = 0;
zde->version_needed = _zip_buffer_get_16(buffer);
zde->bitflags = _zip_buffer_get_16(buffer);
zde->comp_method = _zip_buffer_get_16(buffer);
/* convert to time_t */
dostime = _zip_buffer_get_16(buffer);
dosdate = _zip_buffer_get_16(buffer);
zde->last_mod = _zip_d2u_time(dostime, dosdate);
zde->crc = _zip_buffer_get_32(buffer);
zde->comp_size = _zip_buffer_get_32(buffer);
zde->uncomp_size = _zip_buffer_get_32(buffer);
filename_len = _zip_buffer_get_16(buffer);
ef_len = _zip_buffer_get_16(buffer);
if (local) {
comment_len = 0;
zde->disk_number = 0;
zde->int_attrib = 0;
zde->ext_attrib = 0;
zde->offset = 0;
} else {
comment_len = _zip_buffer_get_16(buffer);
zde->disk_number = _zip_buffer_get_16(buffer);
zde->int_attrib = _zip_buffer_get_16(buffer);
zde->ext_attrib = _zip_buffer_get_32(buffer);
zde->offset = _zip_buffer_get_32(buffer);
}
if (!_zip_buffer_ok(buffer)) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
zde->filename = NULL;
zde->extra_fields = NULL;
zde->comment = NULL;
variable_size = (zip_uint32_t)filename_len+(zip_uint32_t)ef_len+(zip_uint32_t)comment_len;
if (from_buffer) {
if (_zip_buffer_left(buffer) < variable_size) {
zip_error_set(error, ZIP_ER_INCONS, 0);
return -1;
}
}
else {
_zip_buffer_free(buffer);
if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) {
return -1;
}
}
if (filename_len) {
zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
if (!zde->filename) {
if (zip_error_code_zip(error) == ZIP_ER_EOF) {
zip_error_set(error, ZIP_ER_INCONS, 0);
}
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
zip_error_set(error, ZIP_ER_INCONS, 0);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
}
}
if (ef_len) {
zip_uint8_t *ef = _zip_read_data(buffer, src, ef_len, 0, error);
if (ef == NULL) {
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, &zde->extra_fields, error)) {
free(ef);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
free(ef);
if (local)
zde->local_extra_fields_read = 1;
}
if (comment_len) {
zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
if (!zde->comment) {
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
zip_error_set(error, ZIP_ER_INCONS, 0);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
}
}
zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename);
zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);
/* Zip64 */
if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
zip_uint16_t got_len;
zip_buffer_t *ef_buffer;
const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error);
/* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */
if (ef == NULL) {
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
if (zde->uncomp_size == ZIP_UINT32_MAX)
zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
else if (local) {
/* From appnote.txt: This entry in the Local header MUST
include BOTH original and compressed file size fields. */
(void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
}
if (zde->comp_size == ZIP_UINT32_MAX)
zde->comp_size = _zip_buffer_get_64(ef_buffer);
if (!local) {
if (zde->offset == ZIP_UINT32_MAX)
zde->offset = _zip_buffer_get_64(ef_buffer);
if (zde->disk_number == ZIP_UINT16_MAX)
zde->disk_number = _zip_buffer_get_32(buffer);
}
if (!_zip_buffer_eof(ef_buffer)) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(ef_buffer);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
_zip_buffer_free(ef_buffer);
}
if (!_zip_buffer_ok(buffer)) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
if (!from_buffer) {
_zip_buffer_free(buffer);
}
/* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */
if (zde->offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return -1;
}
zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
return (zip_int64_t)(size + variable_size);
}
static zip_string_t *
_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str)
{
zip_uint16_t ef_len;
zip_uint32_t ef_crc;
zip_buffer_t *buffer;
const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL);
if (ef == NULL || ef_len < 5 || ef[0] != 1) {
return str;
}
if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
return str;
}
_zip_buffer_get_8(buffer);
ef_crc = _zip_buffer_get_32(buffer);
if (_zip_string_crc32(str) == ef_crc) {
zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer);
zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL);
if (ef_str != NULL) {
_zip_string_free(str);
str = ef_str;
}
}
_zip_buffer_free(buffer);
return str;
}
zip_int32_t
_zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error)
{
zip_int32_t size;
bool local = (flags & ZIP_EF_LOCAL) != 0;
int i;
zip_uint8_t b[6];
zip_buffer_t *buffer;
size = local ? LENTRYSIZE : CDENTRYSIZE;
if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) {
_zip_error_set_from_source(error, src);
return -1;
}
if ((buffer = _zip_buffer_new_from_source(src, local ? 4 : 6, b, error)) == NULL) {
return -1;
}
for (i=0; i<(local ? 2 : 3); i++) {
size += _zip_buffer_get_16(buffer);
}
if (!_zip_buffer_eof(buffer)) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(buffer);
return -1;
}
_zip_buffer_free(buffer);
return size;
}
/* _zip_dirent_write
Writes zip directory entry.
If flags & ZIP_EF_LOCAL, it writes a local header instead of a central
directory entry. If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed.
Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is
returned.
*/
int
_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
{
zip_uint16_t dostime, dosdate;
zip_encoding_type_t com_enc, name_enc;
zip_extra_field_t *ef;
zip_extra_field_t *ef64;
zip_uint32_t ef_total_size;
bool is_zip64;
bool is_really_zip64;
zip_uint8_t buf[CDENTRYSIZE];
zip_buffer_t *buffer;
ef = NULL;
name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN);
com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN);
if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) ||
(name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) ||
(name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN))
de->bitflags |= ZIP_GPBF_ENCODING_UTF_8;
else {
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCODING_UTF_8;
if (name_enc == ZIP_ENCODING_UTF8_KNOWN) {
ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, &za->error);
if (ef == NULL)
return -1;
}
if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN){
zip_extra_field_t *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, &za->error);
if (ef2 == NULL) {
_zip_ef_free(ef);
return -1;
}
ef2->next = ef;
ef = ef2;
}
}
is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
is_zip64 = (flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64) || is_really_zip64;
if (is_zip64) {
zip_uint8_t ef_zip64[EFZIP64SIZE];
zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64));
if (ef_buffer == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
_zip_ef_free(ef);
return -1;
}
if (flags & ZIP_FL_LOCAL) {
if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) {
_zip_buffer_put_64(ef_buffer, de->uncomp_size);
_zip_buffer_put_64(ef_buffer, de->comp_size);
}
}
else {
if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) {
if (de->uncomp_size >= ZIP_UINT32_MAX) {
_zip_buffer_put_64(ef_buffer, de->uncomp_size);
}
if (de->comp_size >= ZIP_UINT32_MAX) {
_zip_buffer_put_64(ef_buffer, de->comp_size);
}
if (de->offset >= ZIP_UINT32_MAX) {
_zip_buffer_put_64(ef_buffer, de->offset);
}
}
}
if (!_zip_buffer_ok(ef_buffer)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(ef_buffer);
_zip_ef_free(ef);
return -1;
}
ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64, ZIP_EF_BOTH);
_zip_buffer_free(ef_buffer);
ef64->next = ef;
ef = ef64;
}
if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
_zip_ef_free(ef);
return -1;
}
_zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4);
if ((flags & ZIP_FL_LOCAL) == 0) {
_zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby));
}
_zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
_zip_buffer_put_16(buffer, de->bitflags&0xfff9); /* clear compression method specific flags */
_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
_zip_buffer_put_16(buffer, dostime);
_zip_buffer_put_16(buffer, dosdate);
_zip_buffer_put_32(buffer, de->crc);
if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
/* In local headers, if a ZIP64 EF is written, it MUST contain
* both compressed and uncompressed sizes (even if one of the
* two is smaller than 0xFFFFFFFF); on the other hand, those
* may only appear when the corresponding standard entry is
* 0xFFFFFFFF. (appnote.txt 4.5.3) */
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
}
else {
if (de->comp_size < ZIP_UINT32_MAX) {
_zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
}
else {
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
}
if (de->uncomp_size < ZIP_UINT32_MAX) {
_zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
}
else {
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
}
}
_zip_buffer_put_16(buffer, _zip_string_length(de->filename));
/* TODO: check for overflow */
ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH);
_zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size);
if ((flags & ZIP_FL_LOCAL) == 0) {
_zip_buffer_put_16(buffer, _zip_string_length(de->comment));
_zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
_zip_buffer_put_16(buffer, de->int_attrib);
_zip_buffer_put_32(buffer, de->ext_attrib);
if (de->offset < ZIP_UINT32_MAX)
_zip_buffer_put_32(buffer, (zip_uint32_t)de->offset);
else
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
}
if (!_zip_buffer_ok(buffer)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(buffer);
_zip_ef_free(ef);
return -1;
}
if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) {
_zip_buffer_free(buffer);
_zip_ef_free(ef);
return -1;
}
_zip_buffer_free(buffer);
if (de->filename) {
if (_zip_string_write(za, de->filename) < 0) {
_zip_ef_free(ef);
return -1;
}
}
if (ef) {
if (_zip_ef_write(za, ef, ZIP_EF_BOTH) < 0) {
_zip_ef_free(ef);
return -1;
}
}
_zip_ef_free(ef);
if (de->extra_fields) {
if (_zip_ef_write(za, de->extra_fields, flags) < 0) {
return -1;
}
}
if ((flags & ZIP_FL_LOCAL) == 0) {
if (de->comment) {
if (_zip_string_write(za, de->comment) < 0) {
return -1;
}
}
}
return is_zip64;
}
static time_t
_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate)
{
struct tm tm;
memset(&tm, 0, sizeof(tm));
/* let mktime decide if DST is in effect */
tm.tm_isdst = -1;
tm.tm_year = ((ddate>>9)&127) + 1980 - 1900;
tm.tm_mon = ((ddate>>5)&15) - 1;
tm.tm_mday = ddate&31;
tm.tm_hour = (dtime>>11)&31;
tm.tm_min = (dtime>>5)&63;
tm.tm_sec = (dtime<<1)&62;
return mktime(&tm);
}
static zip_extra_field_t *
_zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error)
{
const zip_uint8_t *raw;
zip_uint32_t len;
zip_buffer_t *buffer;
zip_extra_field_t *ef;
if ((raw=_zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) {
/* error already set */
return NULL;
}
if (len+5 > ZIP_UINT16_MAX) {
zip_error_set(error, ZIP_ER_INVAL, 0); /* TODO: better error code? */
return NULL;
}
if ((buffer = _zip_buffer_new(NULL, len+5)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
_zip_buffer_put_8(buffer, 1);
_zip_buffer_put_32(buffer, _zip_string_crc32(str));
_zip_buffer_put(buffer, raw, len);
if (!_zip_buffer_ok(buffer)) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(buffer);
return NULL;
}
ef = _zip_ef_new(id, (zip_uint16_t)(_zip_buffer_offset(buffer)), _zip_buffer_data(buffer), ZIP_EF_BOTH);
_zip_buffer_free(buffer);
return ef;
}
zip_dirent_t *
_zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error)
{
if (error == NULL)
error = &za->error;
if (idx >= za->nentry) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) {
if (za->entry[idx].orig == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) {
zip_error_set(error, ZIP_ER_DELETED, 0);
return NULL;
}
return za->entry[idx].orig;
}
else
return za->entry[idx].changes;
}
void
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate)
{
struct tm *tm;
tm = localtime(&intime);
if (tm->tm_year < 80) {
tm->tm_year = 80;
}
*ddate = (zip_uint16_t)(((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday);
*dtime = (zip_uint16_t)(((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1));
return;
}

View File

@@ -0,0 +1,79 @@
/*
zip_discard.c -- discard and free struct zip
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
/* zip_discard:
frees the space allocated to a zipfile struct, and closes the
corresponding file. */
void
zip_discard(zip_t *za)
{
zip_uint64_t i;
if (za == NULL)
return;
if (za->src) {
zip_source_close(za->src);
zip_source_free(za->src);
}
free(za->default_password);
_zip_string_free(za->comment_orig);
_zip_string_free(za->comment_changes);
_zip_hash_free(za->names);
if (za->entry) {
for (i=0; i<za->nentry; i++)
_zip_entry_finalize(za->entry+i);
free(za->entry);
}
for (i=0; i<za->nopen_source; i++) {
_zip_source_invalidate(za->open_source[i]);
}
free(za->open_source);
zip_error_fini(&za->error);
free(za);
return;
}

View File

@@ -0,0 +1,53 @@
/*
zip_entry.c -- struct zip_entry helper functions
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
void
_zip_entry_finalize(zip_entry_t *e)
{
_zip_unchange_data(e);
_zip_dirent_free(e->orig);
_zip_dirent_free(e->changes);
}
void
_zip_entry_init(zip_entry_t *e)
{
e->orig = NULL;
e->changes = NULL;
e->source = NULL;
e->deleted = 0;
}

View File

@@ -0,0 +1,80 @@
/*
This file was generated automatically by ./make_zip_err_str.sh
from ./zip.h; make changes there.
*/
#include "zipint.h"
const char * const _zip_err_str[] = {
"No error",
"Multi-disk zip archives not supported",
"Renaming temporary file failed",
"Closing zip archive failed",
"Seek error",
"Read error",
"Write error",
"CRC error",
"Containing zip archive was closed",
"No such file",
"File already exists",
"Can't open file",
"Failure to create temporary file",
"Zlib error",
"Malloc failure",
"Entry has been changed",
"Compression method not supported",
"Premature end of file",
"Invalid argument",
"Not a zip archive",
"Internal error",
"Zip archive inconsistent",
"Can't remove file",
"Entry has been deleted",
"Encryption method not supported",
"Read-only archive",
"No password provided",
"Wrong password provided",
"Operation not supported",
"Resource still in use",
"Tell error",
};
const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
#define N ZIP_ET_NONE
#define S ZIP_ET_SYS
#define Z ZIP_ET_ZLIB
const int _zip_err_type[] = {
N,
N,
S,
S,
S,
S,
S,
N,
N,
N,
N,
S,
S,
Z,
N,
N,
N,
N,
N,
N,
N,
N,
S,
N,
N,
N,
N,
N,
N,
N,
S,
};

View File

@@ -0,0 +1,155 @@
/*
zip_error.c -- zip_error_t helper functions
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN int
zip_error_code_system(const zip_error_t *error) {
return error->sys_err;
}
ZIP_EXTERN int
zip_error_code_zip(const zip_error_t *error) {
return error->zip_err;
}
ZIP_EXTERN void
zip_error_fini(zip_error_t *err)
{
free(err->str);
err->str = NULL;
}
ZIP_EXTERN void
zip_error_init(zip_error_t *err)
{
err->zip_err = ZIP_ER_OK;
err->sys_err = 0;
err->str = NULL;
}
ZIP_EXTERN void
zip_error_init_with_code(zip_error_t *error, int ze)
{
zip_error_init(error);
error->zip_err = ze;
switch (zip_error_system_type(error)) {
case ZIP_ET_SYS:
error->sys_err = errno;
break;
default:
error->sys_err = 0;
break;
}
}
ZIP_EXTERN int
zip_error_system_type(const zip_error_t *error) {
if (error->zip_err < 0 || error->zip_err >= _zip_nerr_str)
return ZIP_ET_NONE;
return _zip_err_type[error->zip_err];
}
void
_zip_error_clear(zip_error_t *err)
{
if (err == NULL)
return;
err->zip_err = ZIP_ER_OK;
err->sys_err = 0;
}
void
_zip_error_copy(zip_error_t *dst, const zip_error_t *src)
{
dst->zip_err = src->zip_err;
dst->sys_err = src->sys_err;
}
void
_zip_error_get(const zip_error_t *err, int *zep, int *sep)
{
if (zep)
*zep = err->zip_err;
if (sep) {
if (zip_error_system_type(err) != ZIP_ET_NONE)
*sep = err->sys_err;
else
*sep = 0;
}
}
void
zip_error_set(zip_error_t *err, int ze, int se)
{
if (err) {
err->zip_err = ze;
err->sys_err = se;
}
}
void
_zip_error_set_from_source(zip_error_t *err, zip_source_t *src)
{
_zip_error_copy(err, zip_source_error(src));
}
zip_int64_t
zip_error_to_data(const zip_error_t *error, void *data, zip_uint64_t length)
{
int *e = (int *)data;
if (length < sizeof(int)*2) {
return -1;
}
e[0] = zip_error_code_zip(error);
e[1] = zip_error_code_system(error);
return sizeof(int)*2;
}

View File

@@ -0,0 +1,45 @@
/*
zip_error_clear.c -- clear zip error
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN void
zip_error_clear(zip_t *za)
{
if (za == NULL)
return;
_zip_error_clear(&za->error);
}

View File

@@ -0,0 +1,57 @@
/*
zip_error_get.c -- get zip error
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN void
zip_error_get(zip_t *za, int *zep, int *sep)
{
_zip_error_get(&za->error, zep, sep);
}
ZIP_EXTERN zip_error_t *
zip_get_error(zip_t *za)
{
return &za->error;
}
ZIP_EXTERN zip_error_t *
zip_file_get_error(zip_file_t *f)
{
return &f->error;
}

View File

@@ -0,0 +1,45 @@
/*
zip_error_get_sys_type.c -- return type of system error code
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN int
zip_error_get_sys_type(int ze)
{
if (ze < 0 || ze >= _zip_nerr_str)
return 0;
return _zip_err_type[ze];
}

View File

@@ -0,0 +1,87 @@
/*
zip_error_sterror.c -- get string representation of struct zip_error
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
ZIP_EXTERN const char *
zip_error_strerror(zip_error_t *err)
{
const char *zs, *ss;
char buf[128], *s;
zip_error_fini(err);
if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) {
sprintf(buf, "Unknown error %d", err->zip_err);
zs = NULL;
ss = buf;
}
else {
zs = _zip_err_str[err->zip_err];
switch (_zip_err_type[err->zip_err]) {
case ZIP_ET_SYS:
ss = strerror(err->sys_err);
break;
case ZIP_ET_ZLIB:
ss = zError(err->sys_err);
break;
default:
ss = NULL;
}
}
if (ss == NULL)
return zs;
else {
if ((s=(char *)malloc(strlen(ss)
+ (zs ? strlen(zs)+2 : 0) + 1)) == NULL)
return _zip_err_str[ZIP_ER_MEMORY];
sprintf(s, "%s%s%s",
(zs ? zs : ""),
(zs ? ": " : ""),
ss);
err->str = s;
return s;
}
}

View File

@@ -0,0 +1,68 @@
/*
zip_error_to_str.c -- get string representation of zip error code
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN int
zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se)
{
const char *zs, *ss;
if (ze < 0 || ze >= _zip_nerr_str)
return snprintf(buf, len, "Unknown error %d", ze);
zs = _zip_err_str[ze];
switch (_zip_err_type[ze]) {
case ZIP_ET_SYS:
ss = strerror(se);
break;
case ZIP_ET_ZLIB:
ss = zError(se);
break;
default:
ss = NULL;
}
return snprintf(buf, len, "%s%s%s",
zs, (ss ? ": " : ""), (ss ? ss : ""));
}

View File

@@ -0,0 +1,438 @@
/*
zip_extra_field.c -- manipulate extra fields
Copyright (C) 2012-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
zip_extra_field_t *
_zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error)
{
zip_extra_field_t *head, *prev, *def;
head = prev = NULL;
while (ef) {
if ((def=_zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
_zip_ef_free(head);
return NULL;
}
if (head == NULL)
head = def;
if (prev)
prev->next = def;
prev = def;
ef = ef->next;
}
return head;
}
zip_extra_field_t *
_zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags)
{
zip_extra_field_t *head, *prev;
int i;
i = 0;
head = ef;
prev = NULL;
for (; ef; ef=(prev ? prev->next : head)) {
if ((ef->flags & flags & ZIP_EF_BOTH) && ((ef->id == id) || (id == ZIP_EXTRA_FIELD_ALL))) {
if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) {
ef->flags &= ~(flags & ZIP_EF_BOTH);
if ((ef->flags & ZIP_EF_BOTH) == 0) {
if (prev)
prev->next = ef->next;
else
head = ef->next;
ef->next = NULL;
_zip_ef_free(ef);
if (id_idx == ZIP_EXTRA_FIELD_ALL)
continue;
}
}
i++;
if (i > id_idx)
break;
}
prev = ef;
}
return head;
}
void
_zip_ef_free(zip_extra_field_t *ef)
{
zip_extra_field_t *ef2;
while (ef) {
ef2 = ef->next;
free(ef->data);
free(ef);
ef = ef2;
}
}
const zip_uint8_t *
_zip_ef_get_by_id(const zip_extra_field_t *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, zip_error_t *error)
{
static const zip_uint8_t empty[1] = { '\0' };
int i;
i = 0;
for (; ef; ef=ef->next) {
if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) {
if (i < id_idx) {
i++;
continue;
}
if (lenp)
*lenp = ef->size;
if (ef->size > 0)
return ef->data;
else
return empty;
}
}
zip_error_set(error, ZIP_ER_NOENT, 0);
return NULL;
}
zip_extra_field_t *
_zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from)
{
zip_extra_field_t *ef2, *tt, *tail;
int duplicate;
if (to == NULL)
return from;
for (tail=to; tail->next; tail=tail->next)
;
for (; from; from=ef2) {
ef2 = from->next;
duplicate = 0;
for (tt=to; tt; tt=tt->next) {
if (tt->id == from->id && tt->size == from->size && memcmp(tt->data, from->data, tt->size) == 0) {
tt->flags |= (from->flags & ZIP_EF_BOTH);
duplicate = 1;
break;
}
}
from->next = NULL;
if (duplicate)
_zip_ef_free(from);
else
tail = tail->next = from;
}
return to;
}
zip_extra_field_t *
_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags)
{
zip_extra_field_t *ef;
if ((ef=(zip_extra_field_t *)malloc(sizeof(*ef))) == NULL)
return NULL;
ef->next = NULL;
ef->flags = flags;
ef->id = id;
ef->size = size;
if (size > 0) {
if ((ef->data=(zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) {
free(ef);
return NULL;
}
}
else
ef->data = NULL;
return ef;
}
bool
_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_extra_field_t **ef_head_p, zip_error_t *error)
{
zip_buffer_t *buffer;
zip_extra_field_t *ef, *ef2, *ef_head;
if ((buffer = _zip_buffer_new((zip_uint8_t *)data, len)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return false;
}
ef_head = ef = NULL;
while (_zip_buffer_ok(buffer) && _zip_buffer_left(buffer) >= 4) {
zip_uint16_t fid, flen;
zip_uint8_t *ef_data;
fid = _zip_buffer_get_16(buffer);
flen = _zip_buffer_get_16(buffer);
ef_data = _zip_buffer_get(buffer, flen);
if (ef_data == NULL) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(buffer);
_zip_ef_free(ef_head);
return false;
}
if ((ef2=_zip_ef_new(fid, flen, ef_data, flags)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
_zip_buffer_free(buffer);
_zip_ef_free(ef_head);
return false;
}
if (ef_head) {
ef->next = ef2;
ef = ef2;
}
else
ef_head = ef = ef2;
}
if (!_zip_buffer_eof(buffer)) {
/* Android APK files align stored file data with padding in extra fields; ignore. */
/* see https://android.googlesource.com/platform/build/+/master/tools/zipalign/ZipAlign.cpp */
size_t glen = _zip_buffer_left(buffer);
zip_uint8_t *garbage;
garbage = _zip_buffer_get(buffer, glen);
if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(buffer);
_zip_ef_free(ef_head);
return false;
}
}
_zip_buffer_free(buffer);
if (ef_head_p) {
*ef_head_p = ef_head;
}
else {
_zip_ef_free(ef_head);
}
return true;
}
zip_extra_field_t *
_zip_ef_remove_internal(zip_extra_field_t *ef)
{
zip_extra_field_t *ef_head;
zip_extra_field_t *prev, *next;
ef_head = ef;
prev = NULL;
while (ef) {
if (ZIP_EF_IS_INTERNAL(ef->id)) {
next = ef->next;
if (ef_head == ef)
ef_head = next;
ef->next = NULL;
_zip_ef_free(ef);
if (prev)
prev->next = next;
ef = next;
}
else {
prev = ef;
ef = ef->next;
}
}
return ef_head;
}
zip_uint16_t
_zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags)
{
zip_uint16_t size;
size = 0;
for (; ef; ef=ef->next) {
if (ef->flags & flags & ZIP_EF_BOTH)
size = (zip_uint16_t)(size+4+ef->size);
}
return size;
}
int
_zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags)
{
zip_uint8_t b[4];
zip_buffer_t *buffer = _zip_buffer_new(b, sizeof(b));
if (buffer == NULL) {
return -1;
}
for (; ef; ef=ef->next) {
if (ef->flags & flags & ZIP_EF_BOTH) {
_zip_buffer_set_offset(buffer, 0);
_zip_buffer_put_16(buffer, ef->id);
_zip_buffer_put_16(buffer, ef->size);
if (!_zip_buffer_ok(buffer)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(buffer);
return -1;
}
if (_zip_write(za, b, 4) < 0) {
_zip_buffer_free(buffer);
return -1;
}
if (ef->size > 0) {
if (_zip_write(za, ef->data, ef->size) < 0) {
_zip_buffer_free(buffer);
return -1;
}
}
}
}
_zip_buffer_free(buffer);
return 0;
}
int
_zip_read_local_ef(zip_t *za, zip_uint64_t idx)
{
zip_entry_t *e;
unsigned char b[4];
zip_buffer_t *buffer;
zip_uint16_t fname_len, ef_len;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
e = za->entry+idx;
if (e->orig == NULL || e->orig->local_extra_fields_read)
return 0;
if (e->orig->offset + 26 > ZIP_INT64_MAX) {
zip_error_set(&za->error, ZIP_ER_SEEK, EFBIG);
return -1;
}
if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
if ((buffer = _zip_buffer_new_from_source(za->src, sizeof(b), b, &za->error)) == NULL) {
return -1;
}
fname_len = _zip_buffer_get_16(buffer);
ef_len = _zip_buffer_get_16(buffer);
if (!_zip_buffer_eof(buffer)) {
_zip_buffer_free(buffer);
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
_zip_buffer_free(buffer);
if (ef_len > 0) {
zip_extra_field_t *ef;
zip_uint8_t *ef_raw;
if (zip_source_seek(za->src, fname_len, SEEK_CUR) < 0) {
zip_error_set(&za->error, ZIP_ER_SEEK, errno);
return -1;
}
ef_raw = _zip_read_data(NULL, za->src, ef_len, 0, &za->error);
if (ef_raw == NULL)
return -1;
if (!_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &ef, &za->error)) {
free(ef_raw);
return -1;
}
free(ef_raw);
if (ef) {
ef = _zip_ef_remove_internal(ef);
e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef);
}
}
e->orig->local_extra_fields_read = 1;
if (e->changes && e->changes->local_extra_fields_read == 0) {
e->changes->extra_fields = e->orig->extra_fields;
e->changes->local_extra_fields_read = 1;
}
return 0;
}

View File

@@ -0,0 +1,366 @@
/*
zip_extra_field_api.c -- public extra fields API functions
Copyright (C) 2012-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags)
{
zip_dirent_t *de;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
return -1;
de = za->entry[idx].changes;
de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags);
return 0;
}
ZIP_EXTERN int
zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags)
{
zip_dirent_t *de;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
return -1;
de = za->entry[idx].changes;
de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags);
return 0;
}
ZIP_EXTERN const zip_uint8_t *
zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags)
{
static const zip_uint8_t empty[1] = { '\0' };
zip_dirent_t *de;
zip_extra_field_t *ef;
int i;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
return NULL;
if (flags & ZIP_FL_LOCAL)
if (_zip_read_local_ef(za, idx) < 0)
return NULL;
i = 0;
for (ef=de->extra_fields; ef; ef=ef->next) {
if (ef->flags & flags & ZIP_EF_BOTH) {
if (i < ef_idx) {
i++;
continue;
}
if (idp)
*idp = ef->id;
if (lenp)
*lenp = ef->size;
if (ef->size > 0)
return ef->data;
else
return empty;
}
}
zip_error_set(&za->error, ZIP_ER_NOENT, 0);
return NULL;
}
ZIP_EXTERN const zip_uint8_t *
zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags)
{
zip_dirent_t *de;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
return NULL;
if (flags & ZIP_FL_LOCAL)
if (_zip_read_local_ef(za, idx) < 0)
return NULL;
return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error);
}
ZIP_EXTERN zip_int16_t
zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags)
{
zip_dirent_t *de;
zip_extra_field_t *ef;
zip_uint16_t n;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
return -1;
if (flags & ZIP_FL_LOCAL)
if (_zip_read_local_ef(za, idx) < 0)
return -1;
n = 0;
for (ef=de->extra_fields; ef; ef=ef->next)
if (ef->flags & flags & ZIP_EF_BOTH)
n++;
return (zip_int16_t)n;
}
ZIP_EXTERN zip_int16_t
zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags)
{
zip_dirent_t *de;
zip_extra_field_t *ef;
zip_uint16_t n;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
return -1;
if (flags & ZIP_FL_LOCAL)
if (_zip_read_local_ef(za, idx) < 0)
return -1;
n = 0;
for (ef=de->extra_fields; ef; ef=ef->next)
if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH))
n++;
return (zip_int16_t)n;
}
ZIP_EXTERN int
zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags)
{
zip_dirent_t *de;
zip_uint16_t ls, cs;
zip_extra_field_t *ef, *ef_prev, *ef_new;
int i, found, new_len;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (ZIP_EF_IS_INTERNAL(ef_id)) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
return -1;
de = za->entry[idx].changes;
ef = de->extra_fields;
ef_prev = NULL;
i = 0;
found = 0;
for (; ef; ef=ef->next) {
if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) {
if (i == ef_idx) {
found = 1;
break;
}
i++;
}
ef_prev = ef;
}
if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (flags & ZIP_EF_LOCAL)
ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL);
else
ls = 0;
if (flags & ZIP_EF_CENTRAL)
cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL);
else
cs = 0;
new_len = ls > cs ? ls : cs;
if (found)
new_len -= ef->size + 4;
new_len += len + 4;
if (new_len > ZIP_UINT16_MAX) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
if (found) {
if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) {
ef_new->next = ef->next;
ef->next = NULL;
_zip_ef_free(ef);
if (ef_prev)
ef_prev->next = ef_new;
else
de->extra_fields = ef_new;
}
else {
ef->flags &= ~(flags & ZIP_EF_BOTH);
ef_new->next = ef->next;
ef->next = ef_new;
}
}
else if (ef_prev) {
ef_new->next = ef_prev->next;
ef_prev->next = ef_new;
}
else
de->extra_fields = ef_new;
return 0;
}
int
_zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx)
{
zip_entry_t *e;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
e = za->entry+idx;
if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD))
return 0;
if (e->orig) {
if (_zip_read_local_ef(za, idx) < 0)
return -1;
}
if (e->changes == NULL) {
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
if (e->orig && e->orig->extra_fields) {
if ((e->changes->extra_fields=_zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL)
return -1;
}
e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD;
return 0;
}

View File

@@ -0,0 +1,55 @@
/*
zip_fclose.c -- close file in zip archive
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN int
zip_fclose(zip_file_t *zf)
{
int ret;
if (zf->src)
zip_source_free(zf->src);
ret = 0;
if (zf->error.zip_err)
ret = zf->error.zip_err;
zip_error_fini(&zf->error);
free(zf);
return ret;
}

View File

@@ -0,0 +1,85 @@
/*
zip_fdopen.c -- open read-only archive from file descriptor
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
ZIP_EXTERN zip_t *
zip_fdopen(int fd_orig, int _flags, int *zep)
{
int fd;
FILE *fp;
zip_t *za;
zip_source_t *src;
struct zip_error error;
if (_flags < 0 || (_flags & ZIP_TRUNCATE)) {
_zip_set_open_error(zep, NULL, ZIP_ER_INVAL);
return NULL;
}
/* We dup() here to avoid messing with the passed in fd.
We could not restore it to the original state in case of error. */
if ((fd=dup(fd_orig)) < 0) {
_zip_set_open_error(zep, NULL, ZIP_ER_OPEN);
return NULL;
}
if ((fp=fdopen(fd, "rb")) == NULL) {
close(fd);
_zip_set_open_error(zep, NULL, ZIP_ER_OPEN);
return NULL;
}
zip_error_init(&error);
if ((src = zip_source_filep_create(fp, 0, -1, &error)) == NULL) {
_zip_set_open_error(zep, &error, 0);
zip_error_fini(&error);
return NULL;
}
if ((za = zip_open_from_source(src, _flags, &error)) == NULL) {
_zip_set_open_error(zep, &error, 0);
zip_error_fini(&error);
return NULL;
}
zip_error_fini(&error);
close(fd_orig);
return za;
}

View File

@@ -0,0 +1,53 @@
/*
zip_file_add.c -- add file via callback function
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
/*
NOTE: Return type is signed so we can return -1 on error.
The index can not be larger than ZIP_INT64_MAX since the size
of the central directory cannot be larger than
ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
*/
ZIP_EXTERN zip_int64_t
zip_file_add(zip_t *za, const char *name, zip_source_t *source, zip_flags_t flags)
{
if (name == NULL || source == NULL) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
return _zip_file_replace(za, ZIP_UINT64_MAX, name, source, flags);
}

View File

@@ -0,0 +1,45 @@
/*
zip_file_error_clear.c -- clear zip file error
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN void
zip_file_error_clear(zip_file_t *zf)
{
if (zf == NULL)
return;
_zip_error_clear(&zf->error);
}

View File

@@ -0,0 +1,42 @@
/*
zip_file_error_get.c -- get zip file error
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN void
zip_file_error_get(zip_file_t *zf, int *zep, int *sep)
{
_zip_error_get(&zf->error, zep, sep);
}

View File

@@ -0,0 +1,56 @@
/*
zip_file_get_comment.c -- get file comment
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
/* lenp is 32 bit because converted comment can be longer than ZIP_UINT16_MAX */
ZIP_EXTERN const char *
zip_file_get_comment(zip_t *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags)
{
zip_dirent_t *de;
zip_uint32_t len;
const zip_uint8_t *str;
if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL)
return NULL;
if ((str=_zip_string_get(de->comment, &len, flags, &za->error)) == NULL)
return NULL;
if (lenp)
*lenp = len;
return (const char *)str;
}

View File

@@ -0,0 +1,51 @@
/*
zip_file_get_external_attributes.c -- get opsys/external attributes
Copyright (C) 2013-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
int
zip_file_get_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes)
{
zip_dirent_t *de;
if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL)
return -1;
if (opsys)
*opsys = (zip_uint8_t)((de->version_madeby >> 8) & 0xff);
if (attributes)
*attributes = de->ext_attrib;
return 0;
}

View File

@@ -0,0 +1,73 @@
/*
zip_file_get_offset.c -- get offset of file data in archive.
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "zipint.h"
/* _zip_file_get_offset(za, ze):
Returns the offset of the file data for entry ze.
On error, fills in za->error and returns 0.
*/
zip_uint64_t
_zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error)
{
zip_uint64_t offset;
zip_int32_t size;
offset = za->entry[idx].orig->offset;
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
_zip_error_set_from_source(error, za->src);
return 0;
}
/* TODO: cache? */
if ((size=_zip_dirent_size(za->src, ZIP_EF_LOCAL, error)) < 0)
return 0;
if (offset+(zip_uint32_t)size > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return 0;
}
return offset + (zip_uint32_t)size;
}

View File

@@ -0,0 +1,68 @@
/*
zip_file_rename.c -- rename file in zip archive
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include "zipint.h"
ZIP_EXTERN int
zip_file_rename(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
{
const char *old_name;
int old_is_dir, new_is_dir;
if (idx >= za->nentry || (name != NULL && strlen(name) > ZIP_UINT16_MAX)) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if ((old_name=zip_get_name(za, idx, 0)) == NULL)
return -1;
new_is_dir = (name != NULL && name[strlen(name)-1] == '/');
old_is_dir = (old_name[strlen(old_name)-1] == '/');
if (new_is_dir != old_is_dir) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
return _zip_set_name(za, idx, name, flags);
}

View File

@@ -0,0 +1,108 @@
/*
zip_file_replace.c -- replace file via callback function
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_file_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source, zip_flags_t flags)
{
if (idx >= za->nentry || source == NULL) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_file_replace(za, idx, NULL, source, flags) == -1)
return -1;
return 0;
}
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
zip_int64_t
_zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *source, zip_flags_t flags)
{
zip_uint64_t za_nentry_prev;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
za_nentry_prev = za->nentry;
if (idx == ZIP_UINT64_MAX) {
zip_int64_t i = -1;
if (flags & ZIP_FL_OVERWRITE)
i = _zip_name_locate(za, name, flags, NULL);
if (i == -1) {
/* create and use new entry, used by zip_add */
if ((i=_zip_add_entry(za)) < 0)
return -1;
}
idx = (zip_uint64_t)i;
}
if (name && _zip_set_name(za, idx, name, flags) != 0) {
if (za->nentry != za_nentry_prev) {
_zip_entry_finalize(za->entry+idx);
za->nentry = za_nentry_prev;
}
return -1;
}
/* does not change any name related data, so we can do it here;
* needed for a double add of the same file name */
_zip_unchange_data(za->entry+idx);
if (za->entry[idx].orig != NULL && (za->entry[idx].changes == NULL || (za->entry[idx].changes->changed & ZIP_DIRENT_COMP_METHOD) == 0)) {
if (za->entry[idx].changes == NULL) {
if ((za->entry[idx].changes=_zip_dirent_clone(za->entry[idx].orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
za->entry[idx].changes->comp_method = ZIP_CM_REPLACED_DEFAULT;
za->entry[idx].changes->changed |= ZIP_DIRENT_COMP_METHOD;
}
za->entry[idx].source = source;
return (zip_int64_t)idx;
}

View File

@@ -0,0 +1,103 @@
/*
zip_file_set_comment.c -- set comment for file in archive
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN int
zip_file_set_comment(zip_t *za, zip_uint64_t idx,
const char *comment, zip_uint16_t len, zip_flags_t flags)
{
zip_entry_t *e;
zip_string_t *cstr;
int changed;
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (len > 0 && comment == NULL) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (len > 0) {
if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL)
return -1;
if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
cstr->encoding = ZIP_ENCODING_UTF8_KNOWN;
}
else
cstr = NULL;
e = za->entry+idx;
if (e->changes) {
_zip_string_free(e->changes->comment);
e->changes->comment = NULL;
e->changes->changed &= ~ZIP_DIRENT_COMMENT;
}
if (e->orig && e->orig->comment)
changed = !_zip_string_equal(e->orig->comment, cstr);
else
changed = (cstr != NULL);
if (changed) {
if (e->changes == NULL) {
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
_zip_string_free(cstr);
return -1;
}
}
e->changes->comment = cstr;
e->changes->changed |= ZIP_DIRENT_COMMENT;
}
else {
_zip_string_free(cstr);
if (e->changes && e->changes->changed == 0) {
_zip_dirent_free(e->changes);
e->changes = NULL;
}
}
return 0;
}

View File

@@ -0,0 +1,83 @@
/*
zip_file_set_external_attributes.c -- set external attributes for entry
Copyright (C) 2013-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_file_set_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t opsys, zip_uint32_t attributes)
{
zip_entry_t *e;
int changed;
zip_uint8_t unchanged_opsys;
zip_uint32_t unchanged_attributes;
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
e = za->entry+idx;
unchanged_opsys = (e->orig ? (zip_uint8_t)(e->orig->version_madeby>>8) : (zip_uint8_t)ZIP_OPSYS_DEFAULT);
unchanged_attributes = e->orig ? e->orig->ext_attrib : ZIP_EXT_ATTRIB_DEFAULT;
changed = (opsys != unchanged_opsys || attributes != unchanged_attributes);
if (changed) {
if (e->changes == NULL) {
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
e->changes->version_madeby = (zip_uint16_t)((opsys << 8) | (e->changes->version_madeby & 0xff));
e->changes->ext_attrib = attributes;
e->changes->changed |= ZIP_DIRENT_ATTRIBUTES;
}
else if (e->changes) {
e->changes->changed &= ~ZIP_DIRENT_ATTRIBUTES;
if (e->changes->changed == 0) {
_zip_dirent_free(e->changes);
e->changes = NULL;
}
else {
e->changes->version_madeby = (zip_uint16_t)((unchanged_opsys << 8) | (e->changes->version_madeby & 0xff));
e->changes->ext_attrib = unchanged_attributes;
}
}
return 0;
}

View File

@@ -0,0 +1,74 @@
/*
zip_file_set_mtime.c -- set modification time of entry.
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags)
{
zip_entry_t *e;
int changed;
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
e = za->entry+idx;
changed = e->orig == NULL || mtime != e->orig->last_mod;
if (changed) {
if (e->changes == NULL) {
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
e->changes->last_mod = mtime;
e->changes->changed |= ZIP_DIRENT_LAST_MOD;
}
else {
if (e->changes) {
e->changes->changed &= ~ZIP_DIRENT_LAST_MOD;
if (e->changes->changed == 0) {
_zip_dirent_free(e->changes);
e->changes = NULL;
}
}
}
return 0;
}

View File

@@ -0,0 +1,42 @@
/*
zip_file_sterror.c -- get string representation of zip file error
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN const char *
zip_file_strerror(zip_file_t *zf)
{
return zip_error_strerror(&zf->error);
}

View File

@@ -0,0 +1,76 @@
/*
zip_filerange_crc.c -- compute CRC32 for a range of a file
Copyright (C) 2008-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "zipint.h"
int
_zip_filerange_crc(zip_source_t *src, zip_uint64_t start, zip_uint64_t len, uLong *crcp, zip_error_t *error)
{
Bytef buf[BUFSIZE];
zip_int64_t n;
*crcp = crc32(0L, Z_NULL, 0);
if (start > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return -1;
}
if (zip_source_seek(src, (zip_int64_t)start, SEEK_SET) != 0) {
_zip_error_set_from_source(error, src);
return -1;
}
while (len > 0) {
n = (zip_int64_t)(len > BUFSIZE ? BUFSIZE : len);
if ((n = zip_source_read(src, buf, (zip_uint64_t)n)) < 0) {
_zip_error_set_from_source(error, src);
return -1;
}
if (n == 0) {
zip_error_set(error, ZIP_ER_EOF, 0);
return -1;
}
*crcp = crc32(*crcp, buf, (uInt)n);
len -= (zip_uint64_t)n;
}
return 0;
}

View File

@@ -0,0 +1,47 @@
/*
zip_fopen.c -- open file in zip archive for reading
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN zip_file_t *
zip_fopen(zip_t *za, const char *fname, zip_flags_t flags)
{
zip_int64_t idx;
if ((idx=zip_name_locate(za, fname, flags)) < 0)
return NULL;
return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, za->default_password);
}

View File

@@ -0,0 +1,47 @@
/*
zip_fopen_encrypted.c -- open file for reading with password
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN zip_file_t *
zip_fopen_encrypted(zip_t *za, const char *fname, zip_flags_t flags, const char *password)
{
zip_int64_t idx;
if ((idx=zip_name_locate(za, fname, flags)) < 0)
return NULL;
return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, password);
}

View File

@@ -0,0 +1,45 @@
/*
zip_fopen_index.c -- open file in zip archive for reading by index
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN zip_file_t *
zip_fopen_index(zip_t *za, zip_uint64_t index, zip_flags_t flags)
{
return zip_fopen_index_encrypted(za, index, flags, za->default_password);
}

View File

@@ -0,0 +1,86 @@
/*
zip_fopen_index_encrypted.c -- open file for reading by index w/ password
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include "zipint.h"
static zip_file_t *_zip_file_new(zip_t *za);
ZIP_EXTERN zip_file_t *
zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags,
const char *password)
{
zip_file_t *zf;
zip_source_t *src;
if ((src=_zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL)
return NULL;
if (zip_source_open(src) < 0) {
_zip_error_set_from_source(&za->error, src);
zip_source_free(src);
return NULL;
}
if ((zf=_zip_file_new(za)) == NULL) {
zip_source_free(src);
return NULL;
}
zf->src = src;
return zf;
}
static zip_file_t *
_zip_file_new(zip_t *za)
{
zip_file_t *zf;
if ((zf=(zip_file_t *)malloc(sizeof(struct zip_file))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
zf->za = za;
zip_error_init(&zf->error);
zf->eof = 0;
zf->src = NULL;
return zf;
}

View File

@@ -0,0 +1,63 @@
/*
zip_fread.c -- read from file
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN zip_int64_t
zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread)
{
zip_int64_t n;
if (!zf)
return -1;
if (zf->error.zip_err != 0)
return -1;
if (toread > ZIP_INT64_MAX) {
zip_error_set(&zf->error, ZIP_ER_INVAL, 0);
return -1;
}
if ((zf->eof) || (toread == 0))
return 0;
if ((n=zip_source_read(zf->src, outbuf, toread)) < 0) {
_zip_error_set_from_source(&zf->error, zf->src);
return -1;
}
return n;
}

View File

@@ -0,0 +1,59 @@
/*
zip_get_archive_comment.c -- get archive comment
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include "zipint.h"
ZIP_EXTERN const char *
zip_get_archive_comment(zip_t *za, int *lenp, zip_flags_t flags)
{
zip_string_t *comment;
zip_uint32_t len;
const zip_uint8_t *str;
if ((flags & ZIP_FL_UNCHANGED) || (za->comment_changes == NULL))
comment = za->comment_orig;
else
comment = za->comment_changes;
if ((str=_zip_string_get(comment, &len, flags, &za->error)) == NULL)
return NULL;
if (lenp)
*lenp = (int)len;
return (const char *)str;
}

View File

@@ -0,0 +1,46 @@
/*
zip_get_archive_flag.c -- get archive global flag
Copyright (C) 2008-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_get_archive_flag(zip_t *za, zip_flags_t flag, zip_flags_t flags)
{
unsigned int fl;
fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags;
return (fl & flag) ? 1 : 0;
}

View File

@@ -0,0 +1,44 @@
/*
zip_get_compression_implementation.c -- get compression implementation
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
zip_compression_implementation
_zip_get_compression_implementation(zip_int32_t cm)
{
if (cm == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(cm))
return zip_source_deflate;
return NULL;
}

View File

@@ -0,0 +1,44 @@
/*
zip_get_encryption_implementation.c -- get encryption implementation
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
zip_encryption_implementation
_zip_get_encryption_implementation(zip_uint16_t em)
{
if (em == ZIP_EM_TRAD_PKWARE)
return zip_source_pkware;
return NULL;
}

View File

@@ -0,0 +1,51 @@
/*
zip_get_file_comment.c -- get file comment
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN const char *
zip_get_file_comment(zip_t *za, zip_uint64_t idx, int *lenp, int flags)
{
zip_uint32_t len;
const char *s;
if ((s=zip_file_get_comment(za, idx, &len, (zip_flags_t)flags)) != NULL) {
if (lenp)
*lenp = (int)len;
}
return s;
}

View File

@@ -0,0 +1,60 @@
/*
zip_get_name.c -- get filename for a file in zip file
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include "zipint.h"
ZIP_EXTERN const char *
zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags)
{
return _zip_get_name(za, idx, flags, &za->error);
}
const char *
_zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error)
{
zip_dirent_t *de;
const zip_uint8_t *str;
if ((de=_zip_get_dirent(za, idx, flags, error)) == NULL)
return NULL;
if ((str=_zip_string_get(de->filename, NULL, flags, error)) == NULL)
return NULL;
return (const char *)str;
}

View File

@@ -0,0 +1,53 @@
/*
zip_get_num_entries.c -- get number of entries in archive
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN zip_int64_t
zip_get_num_entries(zip_t *za, zip_flags_t flags)
{
zip_uint64_t n;
if (za == NULL)
return -1;
if (flags & ZIP_FL_UNCHANGED) {
n = za->nentry;
while (n>0 && za->entry[n-1].orig == NULL)
--n;
return (zip_int64_t)n;
}
return (zip_int64_t)za->nentry;
}

View File

@@ -0,0 +1,52 @@
/*
zip_get_num_files.c -- get number of files in archive
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
#include <limits.h>
ZIP_EXTERN int
zip_get_num_files(zip_t *za)
{
if (za == NULL)
return -1;
if (za->nentry > INT_MAX) {
zip_error_set(&za->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
return (int)za->nentry;
}

View File

@@ -0,0 +1,267 @@
/*
zip_hash.c -- hash table string -> uint64
Copyright (C) 2015-2016 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
struct zip_hash_entry {
const zip_uint8_t *name;
zip_int64_t orig_index;
zip_int64_t current_index;
struct zip_hash_entry *next;
};
typedef struct zip_hash_entry zip_hash_entry_t;
struct zip_hash {
zip_uint16_t table_size;
zip_hash_entry_t **table;
};
zip_hash_t *
_zip_hash_new(zip_uint16_t table_size, zip_error_t *error)
{
zip_hash_t *hash;
if (table_size == 0) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return NULL;
}
if ((hash=(zip_hash_t *)malloc(sizeof(zip_hash_t))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
hash->table_size = table_size;
if ((hash->table=(zip_hash_entry_t**)calloc(table_size, sizeof(zip_hash_entry_t *))) == NULL) {
free(hash);
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
return hash;
}
static void
_free_list(zip_hash_entry_t *entry)
{
zip_hash_entry_t *next;
do {
next = entry->next;
free(entry);
entry = next;
} while (entry != NULL);
}
void
_zip_hash_free(zip_hash_t *hash)
{
zip_uint16_t i;
if (hash == NULL) {
return;
}
for (i=0; i<hash->table_size; i++) {
if (hash->table[i] != NULL) {
_free_list(hash->table[i]);
}
}
free(hash->table);
free(hash);
}
static zip_uint16_t
_hash_string(const zip_uint8_t *name, zip_uint16_t size)
{
#define HASH_MULTIPLIER 33
zip_uint16_t value = 5381;
if (name == NULL)
return 0;
while (*name != 0) {
value = (zip_uint16_t)(((value * HASH_MULTIPLIER) + (zip_uint8_t)*name) % size);
name++;
}
return value;
}
/* insert into hash, return error on existence or memory issues */
bool
_zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip_flags_t flags, zip_error_t *error)
{
zip_uint16_t hash_value;
zip_hash_entry_t *entry;
if (hash == NULL || name == NULL || index > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return false;
}
hash_value = _hash_string(name, hash->table_size);
for (entry = hash->table[hash_value]; entry != NULL; entry = entry->next) {
if (strcmp((const char *)name, (const char *)entry->name) == 0) {
if (((flags & ZIP_FL_UNCHANGED) && entry->orig_index != -1) || entry->current_index != -1) {
zip_error_set(error, ZIP_ER_EXISTS, 0);
return false;
}
else {
break;
}
}
}
if (entry == NULL) {
if ((entry=(zip_hash_entry_t *)malloc(sizeof(zip_hash_entry_t))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return false;
}
entry->name = name;
entry->next = hash->table[hash_value];
hash->table[hash_value] = entry;
entry->orig_index = -1;
}
if (flags & ZIP_FL_UNCHANGED) {
entry->orig_index = (zip_int64_t)index;
}
entry->current_index = (zip_int64_t)index;
return true;
}
/* remove entry from hash, error if not found */
bool
_zip_hash_delete(zip_hash_t *hash, const zip_uint8_t *name, zip_error_t *error)
{
zip_uint16_t hash_value;
zip_hash_entry_t *entry, *previous;
if (hash == NULL || name == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return false;
}
hash_value = _hash_string(name, hash->table_size);
previous = NULL;
entry = hash->table[hash_value];
while (entry) {
if (strcmp((const char *)name, (const char *)entry->name) == 0) {
if (entry->orig_index == -1) {
if (previous) {
previous->next = entry->next;
}
else {
hash->table[hash_value] = entry->next;
}
free(entry);
}
else {
entry->current_index = -1;
}
return true;
}
previous = entry;
entry = entry->next;
};
zip_error_set(error, ZIP_ER_NOENT, 0);
return false;
}
/* find value for entry in hash, -1 if not found */
zip_int64_t
_zip_hash_lookup(zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, zip_error_t *error)
{
zip_uint16_t hash_value;
zip_hash_entry_t *entry;
if (hash == NULL || name == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return -1;
}
hash_value = _hash_string(name, hash->table_size);
for (entry = hash->table[hash_value]; entry != NULL; entry = entry->next) {
if (strcmp((const char *)name, (const char *)entry->name) == 0) {
if (flags & ZIP_FL_UNCHANGED) {
if (entry->orig_index != -1) {
return entry->orig_index;
}
}
else {
if (entry->current_index != -1) {
return entry->current_index;
}
}
break;
}
}
zip_error_set(error, ZIP_ER_NOENT, 0);
return -1;
}
void
_zip_hash_revert(zip_hash_t *hash)
{
zip_uint16_t i;
zip_hash_entry_t *entry, *previous;
for (i = 0; i < hash->table_size; i++) {
previous = NULL;
entry = hash->table[i];
while (entry) {
if (entry->orig_index == -1) {
zip_hash_entry_t *p;
if (previous) {
previous->next = entry->next;
}
else {
hash->table[i] = entry->next;
}
p = entry;
entry = entry->next;
/* previous does not change */
free(p);
}
else {
entry->current_index = entry->orig_index;
previous = entry;
entry = entry->next;
}
}
}
}

View File

@@ -0,0 +1,138 @@
/*
zip_io_util.c -- I/O helper functions
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
int
_zip_read(zip_source_t *src, zip_uint8_t *b, zip_uint64_t length, zip_error_t *error)
{
zip_int64_t n;
if (length > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return -1;
}
if ((n = zip_source_read(src, b, length)) < 0) {
_zip_error_set_from_source(error, src);
return -1;
}
if (n < (zip_int64_t)length) {
zip_error_set(error, ZIP_ER_EOF, 0);
return -1;
}
return 0;
}
zip_uint8_t *
_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error)
{
zip_uint8_t *r;
if (length == 0 && !nulp) {
return NULL;
}
r = (zip_uint8_t *)malloc(length + (nulp ? 1 : 0));
if (!r) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (buffer) {
zip_uint8_t *data = _zip_buffer_get(buffer, length);
if (data == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(r);
return NULL;
}
memcpy(r, data, length);
}
else {
if (_zip_read(src, r, length, error) < 0) {
free(r);
return NULL;
}
}
if (nulp) {
zip_uint8_t *o;
/* replace any in-string NUL characters with spaces */
r[length] = 0;
for (o=r; o<r+length; o++)
if (*o == '\0')
*o = ' ';
}
return r;
}
zip_string_t *
_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t len, bool nulp, zip_error_t *error)
{
zip_uint8_t *raw;
zip_string_t *s;
if ((raw=_zip_read_data(buffer, src, len, nulp, error)) == NULL)
return NULL;
s = _zip_string_new(raw, len, ZIP_FL_ENC_GUESS, error);
free(raw);
return s;
}
int
_zip_write(zip_t *za, const void *data, zip_uint64_t length)
{
zip_int64_t n;
if ((n = zip_source_write(za->src, data, length)) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
if ((zip_uint64_t)n != length) {
zip_error_set(&za->error, ZIP_ER_WRITE, EINTR);
return -1;
}
return 0;
}

View File

@@ -0,0 +1,57 @@
/*
zip_memdup.c -- internal zip function, "strdup" with len
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
void *
_zip_memdup(const void *mem, size_t len, zip_error_t *error)
{
void *ret;
if (len == 0)
return NULL;
ret = malloc(len);
if (!ret) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
memcpy(ret, mem, len);
return ret;
}

View File

@@ -0,0 +1,94 @@
/*
zip_name_locate.c -- get index by name
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include "zipint.h"
ZIP_EXTERN zip_int64_t
zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags)
{
return _zip_name_locate(za, fname, flags, &za->error);
}
zip_int64_t
_zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error)
{
int (*cmp)(const char *, const char *);
const char *fn, *p;
zip_uint64_t i;
if (za == NULL)
return -1;
if (fname == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return -1;
}
if (flags & (ZIP_FL_NOCASE|ZIP_FL_NODIR|ZIP_FL_ENC_CP437)) {
/* can't use hash table */
cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
for (i=0; i<za->nentry; i++) {
fn = _zip_get_name(za, i, flags, error);
/* newly added (partially filled) entry or error */
if (fn == NULL)
continue;
if (flags & ZIP_FL_NODIR) {
p = strrchr(fn, '/');
if (p)
fn = p+1;
}
if (cmp(fname, fn) == 0) {
_zip_error_clear(error);
return (zip_int64_t)i;
}
}
zip_error_set(error, ZIP_ER_NOENT, 0);
return -1;
}
else {
return _zip_hash_lookup(za->names, (const zip_uint8_t *)fname, flags, error);
}
}

View File

@@ -0,0 +1,74 @@
/*
zip_new.c -- create and init struct zip
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
/* _zip_new:
creates a new zipfile struct, and sets the contents to zero; returns
the new struct. */
zip_t *
_zip_new(zip_error_t *error)
{
zip_t *za;
za = (zip_t *)malloc(sizeof(struct zip));
if (!za) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if ((za->names = _zip_hash_new(ZIP_HASH_TABLE_SIZE, error)) == NULL) {
free(za);
return NULL;
}
za->src = NULL;
za->open_flags = 0;
zip_error_init(&za->error);
za->flags = za->ch_flags = 0;
za->default_password = NULL;
za->comment_orig = za->comment_changes = NULL;
za->comment_changed = 0;
za->nentry = za->nentry_alloc = 0;
za->entry = NULL;
za->nopen_source = za->nopen_source_alloc = 0;
za->open_source = NULL;
za->tempdir = NULL;
return za;
}

View File

@@ -0,0 +1,853 @@
/*
zip_open.c -- open zip archive by name
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
typedef enum {
EXISTS_ERROR = -1,
EXISTS_NOT = 0,
EXISTS_EMPTY,
EXISTS_NONEMPTY,
} exists_t;
static zip_t *_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error);
static zip_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error);
static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len);
static exists_t _zip_file_exists(zip_source_t *src, zip_error_t *error);
static int _zip_headercomp(const zip_dirent_t *, const zip_dirent_t *);
static unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t);
static zip_cdir_t *_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error);
static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
static zip_cdir_t *_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
ZIP_EXTERN zip_t *
zip_open(const char *fn, int _flags, int *zep)
{
zip_t *za;
zip_source_t *src;
struct zip_error error;
zip_error_init(&error);
if ((src = zip_source_file_create(fn, 0, -1, &error)) == NULL) {
_zip_set_open_error(zep, &error, 0);
zip_error_fini(&error);
return NULL;
}
if ((za = zip_open_from_source(src, _flags, &error)) == NULL) {
zip_source_free(src);
_zip_set_open_error(zep, &error, 0);
zip_error_fini(&error);
return NULL;
}
zip_error_fini(&error);
return za;
}
ZIP_EXTERN zip_t *
zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error)
{
static zip_int64_t needed_support_read = -1;
static zip_int64_t needed_support_write = -1;
unsigned int flags;
zip_int64_t supported;
exists_t exists;
if (_flags < 0 || src == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
flags = (unsigned int)_flags;
supported = zip_source_supports(src);
if (needed_support_read == -1) {
needed_support_read = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_STAT, -1);
needed_support_write = zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1);
}
if ((supported & needed_support_read) != needed_support_read) {
zip_error_set(error, ZIP_ER_OPNOTSUPP, 0);
return NULL;
}
if ((supported & needed_support_write) != needed_support_write) {
flags |= ZIP_RDONLY;
}
if ((flags & (ZIP_RDONLY|ZIP_TRUNCATE)) == (ZIP_RDONLY|ZIP_TRUNCATE)) {
zip_error_set(error, ZIP_ER_RDONLY, 0);
return NULL;
}
exists = _zip_file_exists(src, error);
switch (exists) {
case EXISTS_ERROR:
return NULL;
case EXISTS_NOT:
if ((flags & ZIP_CREATE) == 0) {
zip_error_set(error, ZIP_ER_NOENT, 0);
return NULL;
}
return _zip_allocate_new(src, flags, error);
default: {
zip_t *za;
if (flags & ZIP_EXCL) {
zip_error_set(error, ZIP_ER_EXISTS, 0);
return NULL;
}
if (zip_source_open(src) < 0) {
_zip_error_set_from_source(error, src);
return NULL;
}
if (flags & ZIP_TRUNCATE) {
za = _zip_allocate_new(src, flags, error);
}
else {
/* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, just like open() */
za = _zip_open(src, flags, error);
}
if (za == NULL) {
zip_source_close(src);
return NULL;
}
return za;
}
}
}
ZIP_EXTERN int
zip_archive_set_tempdir(zip_t *za, const char *tempdir)
{
char *new_tempdir;
if (tempdir) {
if ((new_tempdir = strdup(tempdir)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, errno);
return -1;
}
}
else
new_tempdir = NULL;
free(za->tempdir);
za->tempdir = new_tempdir;
return 0;
}
zip_t *
_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error)
{
zip_t *za;
zip_cdir_t *cdir;
struct zip_stat st;
zip_uint64_t len, idx;
zip_stat_init(&st);
if (zip_source_stat(src, &st) < 0) {
_zip_error_set_from_source(error, src);
return NULL;
}
if ((st.valid & ZIP_STAT_SIZE) == 0) {
zip_error_set(error, ZIP_ER_SEEK, EOPNOTSUPP);
return NULL;
}
len = st.size;
/* treat empty files as empty archives */
if (len == 0) {
if ((za=_zip_allocate_new(src, flags, error)) == NULL) {
zip_source_free(src);
return NULL;
}
return za;
}
if ((za=_zip_allocate_new(src, flags, error)) == NULL) {
return NULL;
}
if ((cdir = _zip_find_central_dir(za, len)) == NULL) {
_zip_error_copy(error, &za->error);
/* keep src so discard does not get rid of it */
zip_source_keep(src);
zip_discard(za);
return NULL;
}
za->entry = cdir->entry;
za->nentry = cdir->nentry;
za->nentry_alloc = cdir->nentry_alloc;
za->comment_orig = cdir->comment;
free(cdir);
for (idx = 0; idx < za->nentry; idx++) {
const zip_uint8_t *name = _zip_string_get(za->entry[idx].orig->filename, NULL, 0, error);
if (name == NULL) {
/* keep src so discard does not get rid of it */
zip_source_keep(src);
zip_discard(za);
return NULL;
}
if (_zip_hash_add(za->names, name, idx, ZIP_FL_UNCHANGED, &za->error) == false) {
if (za->error.zip_err != ZIP_ER_EXISTS || (flags & ZIP_CHECKCONS)) {
_zip_error_copy(error, &za->error);
/* keep src so discard does not get rid of it */
zip_source_keep(src);
zip_discard(za);
return NULL;
}
}
}
za->ch_flags = za->flags;
return za;
}
void
_zip_set_open_error(int *zep, const zip_error_t *err, int ze)
{
if (err) {
ze = zip_error_code_zip(err);
if (zip_error_system_type(err) == ZIP_ET_SYS) {
errno = zip_error_code_system(err);
}
}
if (zep)
*zep = ze;
}
/* _zip_readcdir:
tries to find a valid end-of-central-directory at the beginning of
buf, and then the corresponding central directory entries.
Returns a struct zip_cdir which contains the central directory
entries, or NULL if unsuccessful. */
static zip_cdir_t *
_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error)
{
zip_cdir_t *cd;
zip_uint16_t comment_len;
zip_uint64_t i, left;
zip_uint64_t eocd_offset = _zip_buffer_offset(buffer);
zip_buffer_t *cd_buffer;
if (_zip_buffer_left(buffer) < EOCDLEN) {
/* not enough bytes left for comment */
zip_error_set(error, ZIP_ER_NOZIP, 0);
return NULL;
}
/* check for end-of-central-dir magic */
if (memcmp(_zip_buffer_get(buffer, 4), EOCD_MAGIC, 4) != 0) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
return NULL;
}
if (eocd_offset >= EOCD64LOCLEN && memcmp(_zip_buffer_data(buffer) + eocd_offset - EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) {
_zip_buffer_set_offset(buffer, eocd_offset - EOCD64LOCLEN);
cd = _zip_read_eocd64(za->src, buffer, buf_offset, za->flags, error);
}
else {
_zip_buffer_set_offset(buffer, eocd_offset);
cd = _zip_read_eocd(buffer, buf_offset, za->flags, error);
}
if (cd == NULL)
return NULL;
_zip_buffer_set_offset(buffer, eocd_offset + 20);
comment_len = _zip_buffer_get_16(buffer);
if (cd->offset + cd->size > buf_offset + eocd_offset) {
/* cdir spans past EOCD record */
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_cdir_free(cd);
return NULL;
}
if (comment_len || (za->open_flags & ZIP_CHECKCONS)) {
zip_uint64_t tail_len;
_zip_buffer_set_offset(buffer, eocd_offset + EOCDLEN);
tail_len = _zip_buffer_left(buffer);
if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_cdir_free(cd);
return NULL;
}
if (comment_len) {
if ((cd->comment=_zip_string_new(_zip_buffer_get(buffer, comment_len), comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) {
_zip_cdir_free(cd);
return NULL;
}
}
}
if (cd->offset >= buf_offset) {
zip_uint8_t *data;
/* if buffer already read in, use it */
_zip_buffer_set_offset(buffer, cd->offset - buf_offset);
if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_cdir_free(cd);
return NULL;
}
if ((cd_buffer = _zip_buffer_new(data, cd->size)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
_zip_cdir_free(cd);
return NULL;
}
}
else {
cd_buffer = NULL;
if (zip_source_seek(za->src, (zip_int64_t)cd->offset, SEEK_SET) < 0) {
_zip_error_set_from_source(error, za->src);
_zip_cdir_free(cd);
return NULL;
}
/* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */
if (zip_source_tell(za->src) != (zip_int64_t)cd->offset) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
_zip_cdir_free(cd);
return NULL;
}
}
left = (zip_uint64_t)cd->size;
i=0;
while (i<cd->nentry && left > 0) {
zip_int64_t entry_size;
if ((cd->entry[i].orig=_zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, error)) < 0) {
_zip_cdir_free(cd);
_zip_buffer_free(cd_buffer);
return NULL;
}
i++;
left -= (zip_uint64_t)entry_size;
}
if (i != cd->nentry) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(cd_buffer);
_zip_cdir_free(cd);
return NULL;
}
if (za->open_flags & ZIP_CHECKCONS) {
bool ok;
if (cd_buffer) {
ok = _zip_buffer_eof(cd_buffer);
}
else {
zip_int64_t offset = zip_source_tell(za->src);
if (offset < 0) {
_zip_error_set_from_source(error, za->src);
_zip_buffer_free(cd_buffer);
_zip_cdir_free(cd);
return NULL;
}
ok = ((zip_uint64_t)offset == cd->offset + cd->size);
}
if (!ok) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(cd_buffer);
_zip_cdir_free(cd);
return NULL;
}
}
_zip_buffer_free(cd_buffer);
return cd;
}
/* _zip_checkcons:
Checks the consistency of the central directory by comparing central
directory entries with local headers and checking for plausible
file and header offsets. Returns -1 if not plausible, else the
difference between the lowest and the highest fileposition reached */
static zip_int64_t
_zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error)
{
zip_uint64_t i;
zip_uint64_t min, max, j;
struct zip_dirent temp;
_zip_dirent_init(&temp);
if (cd->nentry) {
max = cd->entry[0].orig->offset;
min = cd->entry[0].orig->offset;
}
else
min = max = 0;
for (i=0; i<cd->nentry; i++) {
if (cd->entry[i].orig->offset < min)
min = cd->entry[i].orig->offset;
if (min > (zip_uint64_t)cd->offset) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
return -1;
}
j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size
+ _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE;
if (j > max)
max = j;
if (max > (zip_uint64_t)cd->offset) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
return -1;
}
if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) {
_zip_error_set_from_source(error, za->src);
return -1;
}
if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) {
_zip_dirent_finalize(&temp);
return -1;
}
if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_dirent_finalize(&temp);
return -1;
}
cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields);
cd->entry[i].orig->local_extra_fields_read = 1;
temp.extra_fields = NULL;
_zip_dirent_finalize(&temp);
}
return (max-min) < ZIP_INT64_MAX ? (zip_int64_t)(max-min) : ZIP_INT64_MAX;
}
/* _zip_headercomp:
compares a central directory entry and a local file header
Return 0 if they are consistent, -1 if not. */
static int
_zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local)
{
if ((central->version_needed != local->version_needed)
#if 0
/* some zip-files have different values in local
and global headers for the bitflags */
|| (central->bitflags != local->bitflags)
#endif
|| (central->comp_method != local->comp_method)
|| (central->last_mod != local->last_mod)
|| !_zip_string_equal(central->filename, local->filename))
return -1;
if ((central->crc != local->crc) || (central->comp_size != local->comp_size)
|| (central->uncomp_size != local->uncomp_size)) {
/* InfoZip stores valid values in local header even when data descriptor is used.
This is in violation of the appnote. */
if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0
|| local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0))
return -1;
}
return 0;
}
static zip_t *
_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error)
{
zip_t *za;
if ((za = _zip_new(error)) == NULL) {
return NULL;
}
za->src = src;
za->open_flags = flags;
if (flags & ZIP_RDONLY) {
za->flags |= ZIP_AFL_RDONLY;
za->ch_flags |= ZIP_AFL_RDONLY;
}
return za;
}
/*
* tests for file existence
*/
static exists_t
_zip_file_exists(zip_source_t *src, zip_error_t *error)
{
struct zip_stat st;
zip_stat_init(&st);
if (zip_source_stat(src, &st) != 0) {
zip_error_t *src_error = zip_source_error(src);
if (zip_error_code_zip(src_error) == ZIP_ER_READ && zip_error_code_system(src_error) == ENOENT) {
return EXISTS_NOT;
}
_zip_error_copy(error, src_error);
return EXISTS_ERROR;
}
return (st.valid & ZIP_STAT_SIZE) && st.size == 0 ? EXISTS_EMPTY : EXISTS_NONEMPTY;
}
static zip_cdir_t *
_zip_find_central_dir(zip_t *za, zip_uint64_t len)
{
zip_cdir_t *cdir, *cdirnew;
zip_uint8_t *match;
zip_int64_t buf_offset;
zip_uint64_t buflen;
zip_int64_t a;
zip_int64_t best;
zip_error_t error;
zip_buffer_t *buffer;
if (len < EOCDLEN) {
zip_error_set(&za->error, ZIP_ER_NOZIP, 0);
return NULL;
}
buflen = (len < CDBUFSIZE ? len : CDBUFSIZE);
if (zip_source_seek(za->src, -(zip_int64_t)buflen, SEEK_END) < 0) {
zip_error_t *src_error = zip_source_error(za->src);
if (zip_error_code_zip(src_error) != ZIP_ER_SEEK || zip_error_code_system(src_error) != EFBIG) {
/* seek before start of file on my machine */
_zip_error_copy(&za->error, src_error);
return NULL;
}
}
if ((buf_offset = zip_source_tell(za->src)) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return NULL;
}
if ((buffer = _zip_buffer_new_from_source(za->src, buflen, NULL, &za->error)) == NULL) {
return NULL;
}
best = -1;
cdir = NULL;
if (buflen >= CDBUFSIZE) {
/* EOCD64 locator is before EOCD, so leave place for it */
_zip_buffer_set_offset(buffer, EOCD64LOCLEN);
}
zip_error_set(&error, ZIP_ER_NOZIP, 0);
match = _zip_buffer_get(buffer, 0);
while ((match=_zip_memmem(match, _zip_buffer_left(buffer)-(EOCDLEN-4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) {
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) {
if (cdir) {
if (best <= 0) {
best = _zip_checkcons(za, cdir, &error);
}
a = _zip_checkcons(za, cdirnew, &error);
if (best < a) {
_zip_cdir_free(cdir);
cdir = cdirnew;
best = a;
}
else {
_zip_cdir_free(cdirnew);
}
}
else {
cdir = cdirnew;
if (za->open_flags & ZIP_CHECKCONS)
best = _zip_checkcons(za, cdir, &error);
else {
best = 0;
}
}
cdirnew = NULL;
}
match++;
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
}
_zip_buffer_free(buffer);
if (best < 0) {
_zip_error_copy(&za->error, &error);
_zip_cdir_free(cdir);
return NULL;
}
return cdir;
}
static unsigned char *
_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen)
{
const unsigned char *p;
if ((biglen < littlelen) || (littlelen == 0))
return NULL;
p = big-1;
while ((p=(const unsigned char *)
memchr(p+1, little[0], (size_t)(big-(p+1))+(size_t)(biglen-littlelen)+1)) != NULL) {
if (memcmp(p+1, little+1, littlelen-1)==0)
return (unsigned char *)p;
}
return NULL;
}
static zip_cdir_t *
_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error)
{
zip_cdir_t *cd;
zip_uint64_t i, nentry, size, offset, eocd_offset;
if (_zip_buffer_left(buffer) < EOCDLEN) {
zip_error_set(error, ZIP_ER_INCONS, 0);
return NULL;
}
eocd_offset = _zip_buffer_offset(buffer);
_zip_buffer_get(buffer, 4); /* magic already verified */
if (_zip_buffer_get_32(buffer) != 0) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
return NULL;
}
/* number of cdir-entries on this disk */
i = _zip_buffer_get_16(buffer);
/* number of cdir-entries */
nentry = _zip_buffer_get_16(buffer);
if (nentry != i) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
return NULL;
}
size = _zip_buffer_get_32(buffer);
offset = _zip_buffer_get_32(buffer);
if (offset+size < offset) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return NULL;
}
if (offset+size > buf_offset + eocd_offset) {
/* cdir spans past EOCD record */
zip_error_set(error, ZIP_ER_INCONS, 0);
return NULL;
}
if ((flags & ZIP_CHECKCONS) && offset+size != buf_offset + eocd_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0);
return NULL;
}
if ((cd=_zip_cdir_new(nentry, error)) == NULL)
return NULL;
cd->size = size;
cd->offset = offset;
return cd;
}
static zip_cdir_t *
_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error)
{
zip_cdir_t *cd;
zip_uint64_t offset;
zip_uint8_t eocd[EOCD64LEN];
zip_uint64_t eocd_offset;
zip_uint64_t size, nentry, i, eocdloc_offset;
bool free_buffer;
zip_uint32_t num_disks, num_disks64, eocd_disk, eocd_disk64;
eocdloc_offset = _zip_buffer_offset(buffer);
_zip_buffer_get(buffer, 4); /* magic already verified */
num_disks = _zip_buffer_get_16(buffer);
eocd_disk = _zip_buffer_get_16(buffer);
eocd_offset = _zip_buffer_get_64(buffer);
if (eocd_offset > ZIP_INT64_MAX || eocd_offset + EOCD64LEN < eocd_offset) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return NULL;
}
if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0);
return NULL;
}
if (eocd_offset >= buf_offset && eocd_offset + EOCD64LEN <= buf_offset + _zip_buffer_size(buffer)) {
_zip_buffer_set_offset(buffer, eocd_offset - buf_offset);
free_buffer = false;
}
else {
if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) {
_zip_error_set_from_source(error, src);
return NULL;
}
if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) {
return NULL;
}
free_buffer = true;
}
if (memcmp(_zip_buffer_get(buffer, 4), EOCD64_MAGIC, 4) != 0) {
zip_error_set(error, ZIP_ER_INCONS, 0);
if (free_buffer) {
_zip_buffer_free(buffer);
}
return NULL;
}
size = _zip_buffer_get_64(buffer);
if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0);
if (free_buffer) {
_zip_buffer_free(buffer);
}
return NULL;
}
_zip_buffer_get(buffer, 4); /* skip version made by/needed */
num_disks64 = _zip_buffer_get_32(buffer);
eocd_disk64 = _zip_buffer_get_32(buffer);
/* if eocd values are 0xffff, we have to use eocd64 values.
otherwise, if the values are not the same, it's inconsistent;
in any case, if the value is not 0, we don't support it */
if (num_disks == 0xffff) {
num_disks = num_disks64;
}
if (eocd_disk == 0xffff) {
eocd_disk = eocd_disk64;
}
if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) {
zip_error_set(error, ZIP_ER_INCONS, 0);
return NULL;
}
if (num_disks != 0 || eocd_disk != 0) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
return NULL;
}
nentry = _zip_buffer_get_64(buffer);
i = _zip_buffer_get_64(buffer);
if (nentry != i) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
if (free_buffer) {
_zip_buffer_free(buffer);
}
return NULL;
}
size = _zip_buffer_get_64(buffer);
offset = _zip_buffer_get_64(buffer);
if (!_zip_buffer_ok(buffer)) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
if (free_buffer) {
_zip_buffer_free(buffer);
}
return NULL;
}
if (free_buffer) {
_zip_buffer_free(buffer);
}
if (offset > ZIP_INT64_MAX || offset+size < offset) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return NULL;
}
if ((flags & ZIP_CHECKCONS) && offset+size != eocd_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0);
return NULL;
}
if ((cd=_zip_cdir_new(nentry, error)) == NULL)
return NULL;
cd->size = size;
cd->offset = offset;
return cd;
}

View File

@@ -0,0 +1,45 @@
/*
zip_rename.c -- rename file in zip archive
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN int
zip_rename(zip_t *za, zip_uint64_t idx, const char *name)
{
return zip_file_rename(za, idx, name, 0);
}

View File

@@ -0,0 +1,43 @@
/*
zip_replace.c -- replace file via callback function
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN int
zip_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source)
{
return zip_file_replace(za, idx, source, 0);
}

View File

@@ -0,0 +1,82 @@
/*
zip_set_archive_comment.c -- set archive comment
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN int
zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len)
{
zip_string_t *cstr;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (len > 0 && comment == NULL) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (len > 0) {
if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL)
return -1;
if (_zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_CP437) {
_zip_string_free(cstr);
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
}
else
cstr = NULL;
_zip_string_free(za->comment_changes);
za->comment_changes = NULL;
if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr))
|| (za->comment_orig == NULL && cstr == NULL))) {
_zip_string_free(cstr);
za->comment_changed = 0;
}
else {
za->comment_changes = cstr;
za->comment_changed = 1;
}
return 0;
}

View File

@@ -0,0 +1,67 @@
/*
zip_get_archive_flag.c -- set archive global flag
Copyright (C) 2008-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value)
{
unsigned int new_flags;
if (value)
new_flags = za->ch_flags | flag;
else
new_flags = za->ch_flags & ~flag;
if (new_flags == za->ch_flags)
return 0;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if ((flag & ZIP_AFL_RDONLY) && value
&& (za->ch_flags & ZIP_AFL_RDONLY) == 0) {
if (_zip_changed(za, NULL)) {
zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
return -1;
}
}
za->ch_flags = new_flags;
return 0;
}

View File

@@ -0,0 +1,59 @@
/*
zip_set_default_password.c -- set default password for decryption
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
ZIP_EXTERN int
zip_set_default_password(zip_t *za, const char *passwd)
{
if (za == NULL)
return -1;
free(za->default_password);
if (passwd) {
if ((za->default_password=strdup(passwd)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
else
za->default_password = NULL;
return 0;
}

View File

@@ -0,0 +1,49 @@
/*
zip_set_file_comment.c -- set comment for file in archive
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN int
zip_set_file_comment(zip_t *za, zip_uint64_t idx, const char *comment, int len)
{
if (len < 0 || len > ZIP_UINT16_MAX) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
return zip_file_set_comment(za, idx, comment, (zip_uint16_t)len, 0);
}

View File

@@ -0,0 +1,87 @@
/*
zip_set_file_compression.c -- set compression for file in archive
Copyright (C) 2012-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_uint32_t flags)
{
zip_entry_t *e;
zip_int32_t old_method;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (method != ZIP_CM_DEFAULT && method != ZIP_CM_STORE && method != ZIP_CM_DEFLATE) {
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
return -1;
}
e = za->entry+idx;
old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method);
/* TODO: revisit this when flags are supported, since they may require a recompression */
if (method == old_method) {
if (e->changes) {
e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD;
if (e->changes->changed == 0) {
_zip_dirent_free(e->changes);
e->changes = NULL;
}
}
}
else {
if (e->changes == NULL) {
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
e->changes->comp_method = method;
e->changes->changed |= ZIP_DIRENT_COMP_METHOD;
}
return 0;
}

View File

@@ -0,0 +1,158 @@
/*
zip_set_name.c -- rename helper function
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
int
_zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
{
zip_entry_t *e;
zip_string_t *str;
bool same_as_orig;
zip_int64_t i;
const zip_uint8_t *old_name, *new_name;
zip_string_t *old_str;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (name && name[0] != '\0') {
/* TODO: check for string too long */
if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL)
return -1;
if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
str->encoding = ZIP_ENCODING_UTF8_KNOWN;
}
else
str = NULL;
/* TODO: encoding flags needed for CP437? */
if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) {
_zip_string_free(str);
zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
return -1;
}
/* no effective name change */
if (i>=0 && (zip_uint64_t)i == idx) {
_zip_string_free(str);
return 0;
}
e = za->entry+idx;
if (e->orig)
same_as_orig = _zip_string_equal(e->orig->filename, str);
else
same_as_orig = false;
if (!same_as_orig && e->changes == NULL) {
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
_zip_string_free(str);
return -1;
}
}
if ((new_name = _zip_string_get(same_as_orig ? e->orig->filename : str, NULL, 0, &za->error)) == NULL) {
_zip_string_free(str);
return -1;
}
if (e->changes) {
old_str = e->changes->filename;
}
else if (e->orig) {
old_str = e->orig->filename;
}
else {
old_str = NULL;
}
if (old_str) {
if ((old_name = _zip_string_get(old_str, NULL, 0, &za->error)) == NULL) {
_zip_string_free(str);
return -1;
}
}
else {
old_name = NULL;
}
if (_zip_hash_add(za->names, new_name, idx, 0, &za->error) == false) {
_zip_string_free(str);
return -1;
}
if (old_name) {
_zip_hash_delete(za->names, old_name, NULL);
}
if (same_as_orig) {
if (e->changes) {
if (e->changes->changed & ZIP_DIRENT_FILENAME) {
_zip_string_free(e->changes->filename);
e->changes->changed &= ~ZIP_DIRENT_FILENAME;
if (e->changes->changed == 0) {
_zip_dirent_free(e->changes);
e->changes = NULL;
}
else {
/* TODO: what if not cloned? can that happen? */
e->changes->filename = e->orig->filename;
}
}
}
_zip_string_free(str);
}
else {
if (e->changes->changed & ZIP_DIRENT_FILENAME) {
_zip_string_free(e->changes->filename);
}
e->changes->changed |= ZIP_DIRENT_FILENAME;
e->changes->filename = str;
}
return 0;
}

View File

@@ -0,0 +1,53 @@
/*
zip_source_begin_write.c -- start a new file for writing
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_source_begin_write(zip_source_t *src)
{
if (ZIP_SOURCE_IS_OPEN_WRITING(src)) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_BEGIN_WRITE) < 0) {
return -1;
}
src->write_state = ZIP_SOURCE_WRITE_OPEN;
return 0;
}

View File

@@ -0,0 +1,435 @@
/*
zip_source_buffer.c -- create zip data source from buffer
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
#ifndef WRITE_FRAGMENT_SIZE
#define WRITE_FRAGMENT_SIZE 64*1024
#endif
struct buffer {
zip_uint64_t fragment_size; /* size of each fragment */
zip_uint8_t **fragments; /* pointers to fragments */
zip_uint64_t nfragments; /* number of allocated fragments */
zip_uint64_t fragments_capacity; /* size of fragments (number of pointers) */
zip_uint64_t size; /* size of data in bytes */
zip_uint64_t offset; /* current offset */
int free_data;
};
typedef struct buffer buffer_t;
struct read_data {
zip_error_t error;
time_t mtime;
buffer_t *in;
buffer_t *out;
};
static void buffer_free(buffer_t *buffer);
static buffer_t *buffer_new(zip_uint64_t fragment_size);
static buffer_t *buffer_new_read(const void *data, zip_uint64_t length, int free_data);
static buffer_t *buffer_new_write(zip_uint64_t fragment_size);
static zip_int64_t buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length);
static int buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error);
static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *);
static zip_int64_t read_data(void *, void *, zip_uint64_t, zip_source_cmd_t);
ZIP_EXTERN zip_source_t *
zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, int freep)
{
if (za == NULL)
return NULL;
return zip_source_buffer_create(data, len, freep, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error)
{
struct read_data *ctx;
zip_source_t *zs;
if (data == NULL && len > 0) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx=(struct read_data *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if ((ctx->in = buffer_new_read(data, len, freep)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(ctx);
return NULL;
}
ctx->out = NULL;
ctx->mtime = time(NULL);
zip_error_init(&ctx->error);
if ((zs=zip_source_function_create(read_data, ctx, error)) == NULL) {
buffer_free(ctx->in);
free(ctx);
return NULL;
}
return zs;
}
static zip_int64_t
read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
{
struct read_data *ctx = (struct read_data *)state;
switch (cmd) {
case ZIP_SOURCE_BEGIN_WRITE:
if ((ctx->out = buffer_new_write(WRITE_FRAGMENT_SIZE)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
}
return 0;
case ZIP_SOURCE_CLOSE:
return 0;
case ZIP_SOURCE_COMMIT_WRITE:
buffer_free(ctx->in);
ctx->in = ctx->out;
ctx->out = NULL;
return 0;
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
buffer_free(ctx->in);
buffer_free(ctx->out);
free(ctx);
return 0;
case ZIP_SOURCE_OPEN:
ctx->in->offset = 0;
return 0;
case ZIP_SOURCE_READ:
if (len > ZIP_INT64_MAX) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
return buffer_read(ctx->in, data, len);
case ZIP_SOURCE_REMOVE:
{
buffer_t *empty = buffer_new_read(NULL, 0, 0);
if (empty == 0) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
}
buffer_free(ctx->in);
ctx->in = empty;
return 0;
}
case ZIP_SOURCE_ROLLBACK_WRITE:
buffer_free(ctx->out);
ctx->out = NULL;
return 0;
case ZIP_SOURCE_SEEK:
return buffer_seek(ctx->in, data, len, &ctx->error);
case ZIP_SOURCE_SEEK_WRITE:
return buffer_seek(ctx->out, data, len, &ctx->error);
case ZIP_SOURCE_STAT:
{
zip_stat_t *st;
if (len < sizeof(*st)) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
st = (zip_stat_t *)data;
zip_stat_init(st);
st->mtime = ctx->mtime;
st->size = ctx->in->size;
st->comp_size = st->size;
st->comp_method = ZIP_CM_STORE;
st->encryption_method = ZIP_EM_NONE;
st->valid = ZIP_STAT_MTIME|ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
return sizeof(*st);
}
case ZIP_SOURCE_SUPPORTS:
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1);
case ZIP_SOURCE_TELL:
if (ctx->in->offset > ZIP_INT64_MAX) {
zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW);
return -1;
}
return (zip_int64_t)ctx->in->offset;
case ZIP_SOURCE_TELL_WRITE:
if (ctx->out->offset > ZIP_INT64_MAX) {
zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW);
return -1;
}
return (zip_int64_t)ctx->out->offset;
case ZIP_SOURCE_WRITE:
if (len > ZIP_INT64_MAX) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
return buffer_write(ctx->out, data, len, &ctx->error);
default:
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
}
static void
buffer_free(buffer_t *buffer)
{
if (buffer == NULL) {
return;
}
if (buffer->free_data) {
zip_uint64_t i;
for (i=0; i < buffer->nfragments; i++) {
free(buffer->fragments[i]);
}
}
free(buffer->fragments);
free(buffer);
}
static buffer_t *
buffer_new(zip_uint64_t fragment_size)
{
buffer_t *buffer;
if ((buffer = malloc(sizeof(*buffer))) == NULL) {
return NULL;
}
buffer->fragment_size = fragment_size;
buffer->offset = 0;
buffer->free_data = 0;
buffer->nfragments = 0;
buffer->fragments_capacity = 0;
buffer->fragments = NULL;
buffer->size = 0;
return buffer;
}
static buffer_t *
buffer_new_read(const void *data, zip_uint64_t length, int free_data)
{
buffer_t *buffer;
if ((buffer = buffer_new(length)) == NULL) {
return NULL;
}
buffer->size = length;
if (length > 0) {
if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) {
buffer_free(buffer);
return NULL;
}
buffer->fragments_capacity = 1;
buffer->nfragments = 1;
buffer->fragments[0] = (zip_uint8_t *)data;
buffer->free_data = free_data;
}
return buffer;
}
static buffer_t *
buffer_new_write(zip_uint64_t fragment_size)
{
buffer_t *buffer;
if ((buffer = buffer_new(fragment_size)) == NULL) {
return NULL;
}
if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) {
buffer_free(buffer);
return NULL;
}
buffer->fragments_capacity = 1;
buffer->nfragments = 0;
buffer->free_data = 1;
return buffer;
}
static zip_int64_t
buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length)
{
zip_uint64_t n, i, fragment_offset;
length = ZIP_MIN(length, buffer->size - buffer->offset);
if (length == 0) {
return 0;
}
if (length > ZIP_INT64_MAX) {
return -1;
}
i = buffer->offset / buffer->fragment_size;
fragment_offset = buffer->offset % buffer->fragment_size;
n = 0;
while (n < length) {
zip_uint64_t left = ZIP_MIN(length - n, buffer->fragment_size - fragment_offset);
memcpy(data + n, buffer->fragments[i] + fragment_offset, left);
n += left;
i++;
fragment_offset = 0;
}
buffer->offset += n;
return (zip_int64_t)n;
}
static int
buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error)
{
zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, len, error);
if (new_offset < 0) {
return -1;
}
buffer->offset = (zip_uint64_t)new_offset;
return 0;
}
static zip_int64_t
buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error)
{
zip_uint64_t n, i, fragment_offset;
zip_uint8_t **fragments;
if (buffer->offset + length + buffer->fragment_size - 1 < length) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return -1;
}
/* grow buffer if needed */
if (buffer->offset + length > buffer->nfragments * buffer->fragment_size) {
zip_uint64_t needed_fragments = (buffer->offset + length + buffer->fragment_size - 1) / buffer->fragment_size;
if (needed_fragments > buffer->fragments_capacity) {
zip_uint64_t new_capacity = buffer->fragments_capacity;
while (new_capacity < needed_fragments) {
new_capacity *= 2;
}
fragments = realloc(buffer->fragments, new_capacity * sizeof(*fragments));
if (fragments == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return -1;
}
buffer->fragments = fragments;
buffer->fragments_capacity = new_capacity;
}
while (buffer->nfragments < needed_fragments) {
if ((buffer->fragments[buffer->nfragments] = malloc(buffer->fragment_size)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return -1;
}
buffer->nfragments++;
}
}
i = buffer->offset / buffer->fragment_size;
fragment_offset = buffer->offset % buffer->fragment_size;
n = 0;
while (n < length) {
zip_uint64_t left = ZIP_MIN(length - n, buffer->fragment_size - fragment_offset);
memcpy(buffer->fragments[i] + fragment_offset, data + n, left);
n += left;
i++;
fragment_offset = 0;
}
buffer->offset += n;
if (buffer->offset > buffer->size) {
buffer->size = buffer->offset;
}
return (zip_int64_t)n;
}

View File

@@ -0,0 +1,69 @@
/*
zip_source_call.c -- invoke callback command on zip_source
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
zip_int64_t
_zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command)
{
zip_int64_t ret;
if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(command)) == 0) {
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
if (src->src == NULL) {
ret = src->cb.f(src->ud, data, length, command);
}
else {
ret = src->cb.l(src->src, src->ud, data, length, command);
}
if (ret < 0) {
if (command != ZIP_SOURCE_ERROR && command != ZIP_SOURCE_SUPPORTS) {
int e[2];
if (_zip_source_call(src, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
}
else {
zip_error_set(&src->error, e[0], e[1]);
}
}
}
return ret;
}

View File

@@ -0,0 +1,58 @@
/*
zip_source_close.c -- close zip_source (stop reading)
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
int
zip_source_close(zip_source_t *src)
{
if (!ZIP_SOURCE_IS_OPEN_READING(src)) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
src->open_count--;
if (src->open_count == 0) {
_zip_source_call(src, NULL, 0, ZIP_SOURCE_CLOSE);
if (ZIP_SOURCE_IS_LAYERED(src)) {
if (zip_source_close(src->src) < 0) {
zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
}
}
}
return 0;
}

View File

@@ -0,0 +1,64 @@
/*
zip_source_commit_write.c -- commit changes to file
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_source_commit_write(zip_source_t *src)
{
if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
if (src->open_count > 1) {
zip_error_set(&src->error, ZIP_ER_INUSE, 0);
return -1;
}
else if (ZIP_SOURCE_IS_OPEN_READING(src)) {
if (zip_source_close(src) < 0) {
return -1;
}
}
if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_COMMIT_WRITE) < 0) {
src->write_state = ZIP_SOURCE_WRITE_FAILED;
return -1;
}
src->write_state = ZIP_SOURCE_WRITE_CLOSED;
return 0;
}

View File

@@ -0,0 +1,202 @@
/*
zip_source_crc.c -- pass-through source that calculates CRC32 and size
Copyright (C) 2009-2016 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "zipint.h"
struct crc_context {
int validate; /* whether to check CRC on EOF and return error on mismatch */
int crc_complete; /* whether CRC was computed for complete file */
zip_error_t error;
zip_uint64_t size;
zip_uint64_t position; /* current reading position */
zip_uint64_t crc_position; /* how far we've computed the CRC */
zip_uint32_t crc;
};
static zip_int64_t crc_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
zip_source_t *
zip_source_crc(zip_t *za, zip_source_t *src, int validate)
{
struct crc_context *ctx;
if (src == NULL) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx=(struct crc_context *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
zip_error_init(&ctx->error);
ctx->validate = validate;
ctx->crc_complete = 0;
ctx->crc_position = 0;
ctx->crc = (zip_uint32_t)crc32(0, NULL, 0);
ctx->size = 0;
return zip_source_layered(za, src, crc_read, ctx);
}
static zip_int64_t
crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
{
struct crc_context *ctx;
zip_int64_t n;
ctx = (struct crc_context *)_ctx;
switch (cmd) {
case ZIP_SOURCE_OPEN:
ctx->position = 0;
return 0;
case ZIP_SOURCE_READ:
if ((n = zip_source_read(src, data, len)) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
if (n == 0) {
if (ctx->crc_position == ctx->position) {
ctx->crc_complete = 1;
ctx->size = ctx->position;
if (ctx->validate) {
struct zip_stat st;
if (zip_source_stat(src, &st) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) {
zip_error_set(&ctx->error, ZIP_ER_CRC, 0);
return -1;
}
if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
zip_error_set(&ctx->error, ZIP_ER_INCONS, 0);
return -1;
}
}
}
}
else if (!ctx->crc_complete && ctx->position <= ctx->crc_position) {
zip_uint64_t i, nn;
for (i = ctx->crc_position - ctx->position; i < (zip_uint64_t)n; i += nn) {
nn = ZIP_MIN(UINT_MAX, (zip_uint64_t)n-i);
ctx->crc = (zip_uint32_t)crc32(ctx->crc, (const Bytef *)data+i, (uInt)nn);
ctx->crc_position += nn;
}
}
ctx->position += (zip_uint64_t)n;
return n;
case ZIP_SOURCE_CLOSE:
return 0;
case ZIP_SOURCE_STAT:
{
zip_stat_t *st;
st = (zip_stat_t *)data;
if (ctx->crc_complete) {
/* TODO: Set comp_size, comp_method, encryption_method?
After all, this only works for uncompressed data. */
st->size = ctx->size;
st->crc = ctx->crc;
st->comp_size = ctx->size;
st->comp_method = ZIP_CM_STORE;
st->encryption_method = ZIP_EM_NONE;
st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;;
}
return 0;
}
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
free(ctx);
return 0;
case ZIP_SOURCE_SUPPORTS:
{
zip_int64_t mask = zip_source_supports(src);
if (mask < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1);
}
case ZIP_SOURCE_SEEK:
{
zip_int64_t new_position;
zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
if (args == NULL) {
return -1;
}
if (zip_source_seek(src, args->offset, args->whence) < 0 || (new_position = zip_source_tell(src)) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
ctx->position = (zip_uint64_t)new_position;
return 0;
}
case ZIP_SOURCE_TELL:
return (zip_int64_t)ctx->position;
default:
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
}

View File

@@ -0,0 +1,415 @@
/*
zip_source_deflate.c -- deflate (de)compressoin routines
Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "zipint.h"
struct deflate {
zip_error_t error;
bool eof;
bool can_store;
bool is_stored;
int mem_level;
zip_uint64_t size;
zip_uint8_t buffer[BUFSIZE];
z_stream zstr;
};
static zip_int64_t compress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
static zip_int64_t decompress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
static zip_int64_t deflate_compress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
static zip_int64_t deflate_decompress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
static void deflate_free(struct deflate *);
zip_source_t *
zip_source_deflate(zip_t *za, zip_source_t *src, zip_int32_t cm, int flags)
{
struct deflate *ctx;
zip_source_t *s2;
if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
zip_error_init(&ctx->error);
ctx->eof = false;
ctx->is_stored = false;
ctx->can_store = ZIP_CM_IS_DEFAULT(cm);
if (flags & ZIP_CODEC_ENCODE) {
ctx->mem_level = MAX_MEM_LEVEL;
}
if ((s2=zip_source_layered(za, src,
((flags & ZIP_CODEC_ENCODE)
? deflate_compress : deflate_decompress),
ctx)) == NULL) {
deflate_free(ctx);
return NULL;
}
return s2;
}
static zip_int64_t
compress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
{
int end, ret;
zip_int64_t n;
zip_uint64_t out_offset;
uInt out_len;
if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
return -1;
if (len == 0 || ctx->is_stored) {
return 0;
}
out_offset = 0;
out_len = (uInt)ZIP_MIN(UINT_MAX, len);
ctx->zstr.next_out = (Bytef *)data;
ctx->zstr.avail_out = out_len;
end = 0;
while (!end) {
ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
switch (ret) {
case Z_STREAM_END:
if (ctx->can_store && ctx->zstr.total_in <= ctx->zstr.total_out) {
ctx->is_stored = true;
ctx->size = ctx->zstr.total_in;
memcpy(data, ctx->buffer, ctx->size);
return (zip_int64_t)ctx->size;
}
/* fallthrough */
case Z_OK:
/* all ok */
if (ctx->zstr.avail_out == 0) {
out_offset += out_len;
if (out_offset < len) {
out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
ctx->zstr.next_out = (Bytef *)data+out_offset;
ctx->zstr.avail_out = out_len;
}
else {
ctx->can_store = false;
end = 1;
}
}
else if (ctx->eof && ctx->zstr.avail_in == 0)
end = 1;
break;
case Z_BUF_ERROR:
if (ctx->zstr.avail_in == 0) {
if (ctx->eof) {
end = 1;
break;
}
if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
_zip_error_set_from_source(&ctx->error, src);
end = 1;
break;
}
else if (n == 0) {
ctx->eof = true;
/* TODO: check against stat of src? */
ctx->size = ctx->zstr.total_in;
}
else {
if (ctx->zstr.total_in > 0) {
/* we overwrote a previously filled ctx->buffer */
ctx->can_store = false;
}
ctx->zstr.next_in = (Bytef *)ctx->buffer;
ctx->zstr.avail_in = (uInt)n;
}
continue;
}
/* fallthrough */
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_STREAM_ERROR:
case Z_MEM_ERROR:
zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
end = 1;
break;
}
}
if (ctx->zstr.avail_out < len) {
ctx->can_store = false;
return (zip_int64_t)(len - ctx->zstr.avail_out);
}
return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
}
static zip_int64_t
decompress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
{
int end, ret;
zip_int64_t n;
zip_uint64_t out_offset;
uInt out_len;
if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
return -1;
if (len == 0)
return 0;
out_offset = 0;
out_len = (uInt)ZIP_MIN(UINT_MAX, len);
ctx->zstr.next_out = (Bytef *)data;
ctx->zstr.avail_out = out_len;
end = 0;
while (!end) {
ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
switch (ret) {
case Z_OK:
if (ctx->zstr.avail_out == 0) {
out_offset += out_len;
if (out_offset < len) {
out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
ctx->zstr.next_out = (Bytef *)data+out_offset;
ctx->zstr.avail_out = out_len;
}
else {
end = 1;
}
}
break;
case Z_STREAM_END:
ctx->eof = 1;
end = 1;
break;
case Z_BUF_ERROR:
if (ctx->zstr.avail_in == 0) {
if (ctx->eof) {
end = 1;
break;
}
if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
_zip_error_set_from_source(&ctx->error, src);
end = 1;
break;
}
else if (n == 0) {
ctx->eof = 1;
}
else {
ctx->zstr.next_in = (Bytef *)ctx->buffer;
ctx->zstr.avail_in = (uInt)n;
}
continue;
}
/* fallthrough */
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_STREAM_ERROR:
case Z_MEM_ERROR:
zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
end = 1;
break;
}
}
if (ctx->zstr.avail_out < len)
return (zip_int64_t)(len - ctx->zstr.avail_out);
return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
}
static zip_int64_t
deflate_compress(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
{
struct deflate *ctx;
int ret;
ctx = (struct deflate *)ud;
switch (cmd) {
case ZIP_SOURCE_OPEN:
ctx->zstr.zalloc = Z_NULL;
ctx->zstr.zfree = Z_NULL;
ctx->zstr.opaque = NULL;
ctx->zstr.avail_in = 0;
ctx->zstr.next_in = NULL;
ctx->zstr.avail_out = 0;
ctx->zstr.next_out = NULL;
/* negative value to tell zlib not to write a header */
if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, ctx->mem_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
return -1;
}
return 0;
case ZIP_SOURCE_READ:
return compress_read(src, ctx, data, len);
case ZIP_SOURCE_CLOSE:
deflateEnd(&ctx->zstr);
return 0;
case ZIP_SOURCE_STAT:
{
zip_stat_t *st;
st = (zip_stat_t *)data;
st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_DEFLATE;
st->valid |= ZIP_STAT_COMP_METHOD;
if (ctx->eof) {
st->comp_size = ctx->size;
st->valid |= ZIP_STAT_COMP_SIZE;
}
else
st->valid &= ~ZIP_STAT_COMP_SIZE;
}
return 0;
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
deflate_free(ctx);
return 0;
case ZIP_SOURCE_SUPPORTS:
return ZIP_SOURCE_SUPPORTS_READABLE;
default:
zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
return -1;
}
}
static zip_int64_t
deflate_decompress(zip_source_t *src, void *ud, void *data,
zip_uint64_t len, zip_source_cmd_t cmd)
{
struct deflate *ctx;
zip_int64_t n;
int ret;
ctx = (struct deflate *)ud;
switch (cmd) {
case ZIP_SOURCE_OPEN:
if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
ctx->zstr.zalloc = Z_NULL;
ctx->zstr.zfree = Z_NULL;
ctx->zstr.opaque = NULL;
ctx->zstr.next_in = (Bytef *)ctx->buffer;
ctx->zstr.avail_in = (uInt)n;
/* negative value to tell zlib that there is no header */
if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
return -1;
}
return 0;
case ZIP_SOURCE_READ:
return decompress_read(src, ctx, data, len);
case ZIP_SOURCE_CLOSE:
inflateEnd(&ctx->zstr);
return 0;
case ZIP_SOURCE_STAT:
{
zip_stat_t *st;
st = (zip_stat_t *)data;
st->comp_method = ZIP_CM_STORE;
if (st->comp_size > 0 && st->size > 0)
st->comp_size = st->size;
return 0;
}
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
free(ctx);
return 0;
case ZIP_SOURCE_SUPPORTS:
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
default:
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
}
static void
deflate_free(struct deflate *ctx)
{
free(ctx);
}

View File

@@ -0,0 +1,42 @@
/*
zip_source_error.c -- get last error from zip_source
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
zip_error_t *
zip_source_error(zip_source_t *src)
{
return &src->error;
}

View File

@@ -0,0 +1,63 @@
/*
zip_source_file.c -- create data source from file
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "zipint.h"
#ifdef _WIN32
#error This file is incompatible with Windows, use zip_source_win32utf8.c instead.
#error Something probably went wrong with configure/cmake.
#endif
ZIP_EXTERN zip_source_t *
zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len)
{
if (za == NULL)
return NULL;
return zip_source_file_create(fname, start, len, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
{
if (fname == NULL || length < -1) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
return _zip_source_file_or_p(fname, NULL, start, length, NULL, error);
}

View File

@@ -0,0 +1,503 @@
/*
zip_source_filep.c -- create data source from FILE *
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef _WIN32
/* WIN32 needs <fcntl.h> for _O_BINARY */
#include <fcntl.h>
#endif
/* Windows sys/types.h does not provide these */
#ifndef S_ISREG
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#if defined(S_IXUSR) && defined(S_IRWXG) && defined(S_IRWXO)
#define _SAFE_MASK (S_IXUSR | S_IRWXG | S_IRWXO)
#elif defined(_S_IWRITE)
#define _SAFE_MASK (_S_IWRITE)
#else
#error do not know safe values for umask, please report this
#endif
#ifdef _MSC_VER
/* MSVC doesn't have mode_t */
typedef int mode_t;
#endif
struct read_file {
zip_error_t error; /* last error information */
zip_int64_t supports;
/* reading */
char *fname; /* name of file to read from */
FILE *f; /* file to read from */
struct zip_stat st; /* stat information passed in */
zip_uint64_t start; /* start offset of data to read */
zip_uint64_t end; /* end offset of data to read, 0 for up to EOF */
zip_uint64_t current; /* current offset */
/* writing */
char *tmpname;
FILE *fout;
};
static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
static int create_temp_output(struct read_file *ctx);
static int _zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error);
static int _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error);
ZIP_EXTERN zip_source_t *
zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len)
{
if (za == NULL)
return NULL;
return zip_source_filep_create(file, start, len, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
{
if (file == NULL || length < -1) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
return _zip_source_file_or_p(NULL, file, start, length, NULL, error);
}
zip_source_t *
_zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_error_t *error)
{
struct read_file *ctx;
zip_source_t *zs;
if (file == NULL && fname == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
ctx->fname = NULL;
if (fname) {
if ((ctx->fname=strdup(fname)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(ctx);
return NULL;
}
}
ctx->f = file;
ctx->start = start;
ctx->end = (len < 0 ? 0 : start+(zip_uint64_t)len);
if (st) {
memcpy(&ctx->st, st, sizeof(ctx->st));
ctx->st.name = NULL;
ctx->st.valid &= ~ZIP_STAT_NAME;
}
else {
zip_stat_init(&ctx->st);
}
ctx->tmpname = NULL;
ctx->fout = NULL;
zip_error_init(&ctx->error);
ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
if (ctx->fname) {
struct stat sb;
if (stat(ctx->fname, &sb) < 0 || S_ISREG(sb.st_mode)) {
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
}
}
else if (fseeko(ctx->f, 0, SEEK_CUR) == 0) {
ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
}
if ((zs=zip_source_function_create(read_file, ctx, error)) == NULL) {
free(ctx->fname);
free(ctx);
return NULL;
}
return zs;
}
static int
create_temp_output(struct read_file *ctx)
{
char *temp;
int tfd;
mode_t mask;
FILE *tfp;
if ((temp=(char *)malloc(strlen(ctx->fname)+8)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
}
sprintf(temp, "%s.XXXXXX", ctx->fname);
mask = umask(_SAFE_MASK);
if ((tfd=mkstemp(temp)) == -1) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
umask(mask);
free(temp);
return -1;
}
umask(mask);
if ((tfp=fdopen(tfd, "r+b")) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
close(tfd);
(void)remove(temp);
free(temp);
return -1;
}
#ifdef _WIN32
/*
According to Pierre Joye, Windows in some environments per
default creates text files, so force binary mode.
*/
_setmode(_fileno(tfp), _O_BINARY );
#endif
ctx->fout = tfp;
ctx->tmpname = temp;
return 0;
}
static zip_int64_t
read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
{
struct read_file *ctx;
char *buf;
zip_uint64_t n;
size_t i;
ctx = (struct read_file *)state;
buf = (char *)data;
switch (cmd) {
case ZIP_SOURCE_BEGIN_WRITE:
if (ctx->fname == NULL) {
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
return create_temp_output(ctx);
case ZIP_SOURCE_COMMIT_WRITE: {
mode_t mask;
if (fclose(ctx->fout) < 0) {
ctx->fout = NULL;
zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
}
ctx->fout = NULL;
if (rename(ctx->tmpname, ctx->fname) < 0) {
zip_error_set(&ctx->error, ZIP_ER_RENAME, errno);
return -1;
}
mask = umask(022);
umask(mask);
/* not much we can do if chmod fails except make the whole commit fail */
(void)chmod(ctx->fname, 0666&~mask);
free(ctx->tmpname);
ctx->tmpname = NULL;
return 0;
}
case ZIP_SOURCE_CLOSE:
if (ctx->fname) {
fclose(ctx->f);
ctx->f = NULL;
}
return 0;
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
free(ctx->fname);
free(ctx->tmpname);
if (ctx->f)
fclose(ctx->f);
free(ctx);
return 0;
case ZIP_SOURCE_OPEN:
if (ctx->fname) {
if ((ctx->f=fopen(ctx->fname, "rb")) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_OPEN, errno);
return -1;
}
}
if (ctx->start > 0) {
if (_zip_fseek_u(ctx->f, ctx->start, SEEK_SET, &ctx->error) < 0) {
return -1;
}
}
ctx->current = ctx->start;
return 0;
case ZIP_SOURCE_READ:
if (ctx->end > 0) {
n = ctx->end-ctx->current;
if (n > len) {
n = len;
}
}
else {
n = len;
}
if (n > SIZE_MAX)
n = SIZE_MAX;
if ((i=fread(buf, 1, (size_t)n, ctx->f)) == 0) {
if (ferror(ctx->f)) {
zip_error_set(&ctx->error, ZIP_ER_READ, errno);
return -1;
}
}
ctx->current += i;
return (zip_int64_t)i;
case ZIP_SOURCE_REMOVE:
if (remove(ctx->fname) < 0) {
zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno);
return -1;
}
return 0;
case ZIP_SOURCE_ROLLBACK_WRITE:
if (ctx->fout) {
fclose(ctx->fout);
ctx->fout = NULL;
}
(void)remove(ctx->tmpname);
free(ctx->tmpname);
ctx->tmpname = NULL;
return 0;
case ZIP_SOURCE_SEEK: {
zip_int64_t new_current;
int need_seek;
zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
if (args == NULL)
return -1;
need_seek = 1;
switch (args->whence) {
case SEEK_SET:
new_current = args->offset;
break;
case SEEK_END:
if (ctx->end == 0) {
if (_zip_fseek(ctx->f, args->offset, SEEK_END, &ctx->error) < 0) {
return -1;
}
if ((new_current = ftello(ctx->f)) < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
return -1;
}
need_seek = 0;
}
else {
new_current = (zip_int64_t)ctx->end + args->offset;
}
break;
case SEEK_CUR:
new_current = (zip_int64_t)ctx->current + args->offset;
break;
default:
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
if (new_current < 0 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
ctx->current = (zip_uint64_t)new_current;
if (need_seek) {
if (_zip_fseek_u(ctx->f, ctx->current, SEEK_SET, &ctx->error) < 0) {
return -1;
}
}
return 0;
}
case ZIP_SOURCE_SEEK_WRITE: {
zip_source_args_seek_t *args;
args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
if (args == NULL) {
return -1;
}
if (_zip_fseek(ctx->fout, args->offset, args->whence, &ctx->error) < 0) {
return -1;
}
return 0;
}
case ZIP_SOURCE_STAT: {
if (len < sizeof(ctx->st))
return -1;
if (ctx->st.valid != 0)
memcpy(data, &ctx->st, sizeof(ctx->st));
else {
zip_stat_t *st;
struct stat fst;
int err;
if (ctx->f)
err = fstat(fileno(ctx->f), &fst);
else
err = stat(ctx->fname, &fst);
if (err != 0) {
zip_error_set(&ctx->error, ZIP_ER_READ, errno);
return -1;
}
st = (zip_stat_t *)data;
zip_stat_init(st);
st->mtime = fst.st_mtime;
st->valid |= ZIP_STAT_MTIME;
if (ctx->end != 0) {
st->size = ctx->end - ctx->start;
st->valid |= ZIP_STAT_SIZE;
}
else if ((fst.st_mode&S_IFMT) == S_IFREG) {
st->size = (zip_uint64_t)fst.st_size;
st->valid |= ZIP_STAT_SIZE;
}
}
return sizeof(ctx->st);
}
case ZIP_SOURCE_SUPPORTS:
return ctx->supports;
case ZIP_SOURCE_TELL:
return (zip_int64_t)ctx->current;
case ZIP_SOURCE_TELL_WRITE:
{
off_t ret = ftello(ctx->fout);
if (ret < 0) {
zip_error_set(&ctx->error, ZIP_ER_TELL, errno);
return -1;
}
return ret;
}
case ZIP_SOURCE_WRITE:
{
size_t ret;
clearerr(ctx->fout);
ret = fwrite(data, 1, len, ctx->fout);
if (ret != len || ferror(ctx->fout)) {
zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
return -1;
}
return (zip_int64_t)ret;
}
default:
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
}
static int
_zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error)
{
if (offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
return -1;
}
return _zip_fseek(f, (zip_int64_t)offset, whence, error);
}
static int
_zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error)
{
if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) {
zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
return -1;
}
if (fseeko(f, (off_t)offset, whence) < 0) {
zip_error_set(error, ZIP_ER_SEEK, errno);
return -1;
}
return 0;
}

View File

@@ -0,0 +1,72 @@
/*
zip_source_free.c -- free zip data source
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN void
zip_source_free(zip_source_t *src)
{
if (src == NULL)
return;
if (src->refcount > 0) {
src->refcount--;
}
if (src->refcount > 0) {
return;
}
if (ZIP_SOURCE_IS_OPEN_READING(src)) {
src->open_count = 1; /* force close */
zip_source_close(src);
}
if (ZIP_SOURCE_IS_OPEN_WRITING(src)) {
zip_source_rollback_write(src);
}
if (src->source_archive && !src->source_closed) {
_zip_deregister_source(src->source_archive, src);
}
(void)_zip_source_call(src, NULL, 0, ZIP_SOURCE_FREE);
if (src->src) {
zip_source_free(src->src);
}
free(src);
}

View File

@@ -0,0 +1,99 @@
/*
zip_source_function.c -- create zip data source from callback function
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN zip_source_t *
zip_source_function(zip_t *za, zip_source_callback zcb, void *ud)
{
if (za == NULL) {
return NULL;
}
return zip_source_function_create(zcb, ud, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_function_create(zip_source_callback zcb, void *ud, zip_error_t *error)
{
zip_source_t *zs;
if ((zs=_zip_source_new(error)) == NULL)
return NULL;
zs->cb.f = zcb;
zs->ud = ud;
zs->supports = zcb(ud, NULL, 0, ZIP_SOURCE_SUPPORTS);
if (zs->supports < 0) {
zs->supports = ZIP_SOURCE_SUPPORTS_READABLE;
}
return zs;
}
ZIP_EXTERN void
zip_source_keep(zip_source_t *src)
{
src->refcount++;
}
zip_source_t *
_zip_source_new(zip_error_t *error)
{
zip_source_t *src;
if ((src=(zip_source_t *)malloc(sizeof(*src))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
src->src = NULL;
src->cb.f = NULL;
src->ud = NULL;
src->open_count = 0;
src->write_state = ZIP_SOURCE_WRITE_CLOSED;
src->source_closed = false;
src->source_archive = NULL;
src->refcount = 1;
zip_error_init(&src->error);
return src;
}

View File

@@ -0,0 +1,42 @@
/*
zip_source_is_deleted.c -- was archive was removed?
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_source_is_deleted(zip_source_t *src)
{
return src->write_state == ZIP_SOURCE_WRITE_REMOVED;
}

View File

@@ -0,0 +1,69 @@
/*
zip_source_layered.c -- create layered source
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
zip_source_t *
zip_source_layered(zip_t *za, zip_source_t *src, zip_source_layered_callback cb, void *ud)
{
if (za == NULL)
return NULL;
return zip_source_layered_create(src, cb, ud, &za->error);
}
zip_source_t *
zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error)
{
zip_source_t *zs;
if ((zs=_zip_source_new(error)) == NULL)
return NULL;
zip_source_keep(src);
zs->src = src;
zs->cb.l = cb;
zs->ud = ud;
zs->supports = cb(src, ud, NULL, 0, ZIP_SOURCE_SUPPORTS);
if (zs->supports < 0) {
zs->supports = ZIP_SOURCE_SUPPORTS_READABLE;
}
return zs;
}

View File

@@ -0,0 +1,73 @@
/*
zip_source_open.c -- open zip_source (prepare for reading)
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_source_open(zip_source_t *src)
{
if (src->source_closed) {
return -1;
}
if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
zip_error_set(&src->error, ZIP_ER_DELETED, 0);
return -1;
}
if (ZIP_SOURCE_IS_OPEN_READING(src)) {
if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) == 0) {
zip_error_set(&src->error, ZIP_ER_INUSE, 0);
return -1;
}
}
else {
if (ZIP_SOURCE_IS_LAYERED(src)) {
if (zip_source_open(src->src) < 0) {
_zip_error_set_from_source(&src->error, src->src);
return -1;
}
}
if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_OPEN) < 0) {
if (ZIP_SOURCE_IS_LAYERED(src)) {
zip_source_close(src->src);
}
return -1;
}
}
src->open_count++;
return 0;
}

View File

@@ -0,0 +1,226 @@
/*
zip_source_pkware.c -- Traditional PKWARE de/encryption routines
Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
struct trad_pkware {
zip_error_t error;
zip_uint32_t key[3];
};
#define HEADERLEN 12
#define KEY0 305419896
#define KEY1 591751049
#define KEY2 878082192
static void decrypt(struct trad_pkware *, zip_uint8_t *,
const zip_uint8_t *, zip_uint64_t, int);
static int decrypt_header(zip_source_t *, struct trad_pkware *);
static zip_int64_t pkware_decrypt(zip_source_t *, void *, void *,
zip_uint64_t, zip_source_cmd_t);
static void pkware_free(struct trad_pkware *);
zip_source_t *
zip_source_pkware(zip_t *za, zip_source_t *src,
zip_uint16_t em, int flags, const char *password)
{
struct trad_pkware *ctx;
zip_source_t *s2;
if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if (flags & ZIP_CODEC_ENCODE) {
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
return NULL;
}
if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
zip_error_init(&ctx->error);
ctx->key[0] = KEY0;
ctx->key[1] = KEY1;
ctx->key[2] = KEY2;
decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
pkware_free(ctx);
return NULL;
}
return s2;
}
static void
decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
zip_uint64_t len, int update_only)
{
zip_uint16_t tmp;
zip_uint64_t i;
Bytef b;
for (i=0; i<len; i++) {
b = in[i];
if (!update_only) {
/* decrypt next byte */
tmp = (zip_uint16_t)(ctx->key[2] | 2);
tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8);
b ^= (Bytef)tmp;
}
/* store cleartext */
if (out)
out[i] = b;
/* update keys */
ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
b = (Bytef)(ctx->key[1] >> 24);
ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
}
}
static int
decrypt_header(zip_source_t *src, struct trad_pkware *ctx)
{
zip_uint8_t header[HEADERLEN];
struct zip_stat st;
zip_int64_t n;
unsigned short dostime, dosdate;
if ((n=zip_source_read(src, header, HEADERLEN)) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
if (n != HEADERLEN) {
zip_error_set(&ctx->error, ZIP_ER_EOF, 0);
return -1;
}
decrypt(ctx, header, header, HEADERLEN, 0);
if (zip_source_stat(src, &st) < 0) {
/* stat failed, skip password validation */
return 0;
}
_zip_u2d_time(st.mtime, &dostime, &dosdate);
if (header[HEADERLEN-1] != st.crc>>24 && header[HEADERLEN-1] != dostime>>8) {
zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0);
return -1;
}
return 0;
}
static zip_int64_t
pkware_decrypt(zip_source_t *src, void *ud, void *data,
zip_uint64_t len, zip_source_cmd_t cmd)
{
struct trad_pkware *ctx;
zip_int64_t n;
ctx = (struct trad_pkware *)ud;
switch (cmd) {
case ZIP_SOURCE_OPEN:
if (decrypt_header(src, ctx) < 0)
return -1;
return 0;
case ZIP_SOURCE_READ:
if ((n=zip_source_read(src, data, len)) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0);
return n;
case ZIP_SOURCE_CLOSE:
return 0;
case ZIP_SOURCE_STAT:
{
zip_stat_t *st;
st = (zip_stat_t *)data;
st->encryption_method = ZIP_EM_NONE;
st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
/* TODO: deduce HEADERLEN from size for uncompressed */
if (st->valid & ZIP_STAT_COMP_SIZE)
st->comp_size -= HEADERLEN;
return 0;
}
case ZIP_SOURCE_SUPPORTS:
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
pkware_free(ctx);
return 0;
default:
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
}
static void
pkware_free(struct trad_pkware *ctx)
{
free(ctx);
}

View File

@@ -0,0 +1,50 @@
/*
zip_source_read.c -- read data from zip_source
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
zip_int64_t
zip_source_read(zip_source_t *src, void *data, zip_uint64_t len)
{
if (src->source_closed) {
return -1;
}
if (!ZIP_SOURCE_IS_OPEN_READING(src) || len > ZIP_INT64_MAX || (len > 0 && data == NULL)) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
return _zip_source_call(src, data, len, ZIP_SOURCE_READ);
}

View File

@@ -0,0 +1,61 @@
/*
zip_source_remove.c -- remove empty archive
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
int
zip_source_remove(zip_source_t *src)
{
if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
return 0;
}
if (ZIP_SOURCE_IS_OPEN_READING(src)) {
if (zip_source_close(src) < 0) {
return -1;
}
}
if (src->write_state != ZIP_SOURCE_WRITE_CLOSED) {
zip_source_rollback_write(src);
}
if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_REMOVE) < 0) {
return -1;
}
src->write_state = ZIP_SOURCE_WRITE_REMOVED;
return 0;
}

View File

@@ -0,0 +1,47 @@
/*
zip_source_rollback_write.c -- discard changes
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN void
zip_source_rollback_write(zip_source_t *src)
{
if (src->write_state != ZIP_SOURCE_WRITE_OPEN && src->write_state != ZIP_SOURCE_WRITE_FAILED) {
return;
}
_zip_source_call(src, NULL, 0, ZIP_SOURCE_ROLLBACK_WRITE);
src->write_state = ZIP_SOURCE_WRITE_CLOSED;
}

View File

@@ -0,0 +1,92 @@
/*
zip_source_seek.c -- seek to offset
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_source_seek(zip_source_t *src, zip_int64_t offset, int whence)
{
zip_source_args_seek_t args;
if (src->source_closed) {
return -1;
}
if (!ZIP_SOURCE_IS_OPEN_READING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
args.offset = offset;
args.whence = whence;
return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK) < 0 ? -1 : 0);
}
zip_int64_t
zip_source_seek_compute_offset(zip_uint64_t offset, zip_uint64_t length, void *data, zip_uint64_t data_length, zip_error_t *error)
{
zip_int64_t new_offset;
zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, data_length, error);
if (args == NULL) {
return -1;
}
switch (args->whence) {
case SEEK_CUR:
new_offset = (zip_int64_t)offset + args->offset;
break;
case SEEK_END:
new_offset = (zip_int64_t)length + args->offset;
break;
case SEEK_SET:
new_offset = args->offset;
break;
default:
zip_error_set(error, ZIP_ER_INVAL, 0);
return -1;
}
if (new_offset < 0 || (zip_uint64_t)new_offset > length) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return -1;
}
return new_offset;
}

View File

@@ -0,0 +1,52 @@
/*
zip_source_seek_write.c -- seek to offset for writing
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_source_seek_write(zip_source_t *src, zip_int64_t offset, int whence)
{
zip_source_args_seek_t args;
if (!ZIP_SOURCE_IS_OPEN_WRITING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
args.offset = offset;
args.whence = whence;
return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK_WRITE) < 0 ? -1 : 0);
}

View File

@@ -0,0 +1,63 @@
/*
zip_source_stat.c -- get meta information from zip_source
Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_source_stat(zip_source_t *src, zip_stat_t *st)
{
if (src->source_closed) {
return -1;
}
if (st == NULL) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
zip_stat_init(st);
if (ZIP_SOURCE_IS_LAYERED(src)) {
if (zip_source_stat(src->src, st) < 0) {
_zip_error_set_from_source(&src->error, src->src);
return -1;
}
}
if (_zip_source_call(src, st, sizeof(*st), ZIP_SOURCE_STAT) < 0) {
return -1;
}
return 0;
}

View File

@@ -0,0 +1,68 @@
/*
zip_source_supports.c -- check for supported functions
Copyright (C) 2014-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdarg.h>
#include "zipint.h"
zip_int64_t
zip_source_supports(zip_source_t *src)
{
return src->supports;
}
ZIP_EXTERN zip_int64_t
zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...)
{
zip_int64_t bitmap;
va_list ap;
bitmap = ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd0);
va_start(ap, cmd0);
for (;;) {
int cmd = va_arg(ap, int);
if (cmd < 0) {
break;
}
bitmap |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd);
}
va_end(ap);
return bitmap;
}

View File

@@ -0,0 +1,50 @@
/*
zip_source_tell.c -- report current offset
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN zip_int64_t
zip_source_tell(zip_source_t *src)
{
if (src->source_closed) {
return -1;
}
if (!ZIP_SOURCE_IS_OPEN_READING(src)) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
return _zip_source_call(src, NULL, 0, ZIP_SOURCE_TELL);
}

View File

@@ -0,0 +1,47 @@
/*
zip_source_tell_write.c -- report current offset for writing
Copyright (C) 2014 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN zip_int64_t
zip_source_tell_write(zip_source_t *src)
{
if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
return _zip_source_call(src, NULL, 0, ZIP_SOURCE_TELL_WRITE);
}

View File

@@ -0,0 +1,124 @@
/*
zip_source_win32a.c -- create data source from Windows file (ANSI)
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "zipint.h"
#include "zipwin32.h"
static void * _win32_strdup_a(const void *str);
static HANDLE _win32_open_a(_zip_source_win32_read_file_t *ctx);
static HANDLE _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
static int _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx);
static int _win32_remove_a(const void *fname);
static _zip_source_win32_file_ops_t win32_ops_a = {
_win32_strdup_a,
_win32_open_a,
_win32_create_temp_a,
_win32_rename_temp_a,
_win32_remove_a
};
ZIP_EXTERN zip_source_t *
zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len)
{
if (za == NULL)
return NULL;
return zip_source_win32a_create(fname, start, len, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
{
if (fname == NULL || length < -1) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_a, error);
}
static void *
_win32_strdup_a(const void *str)
{
return strdup((const char *)str);
}
static HANDLE
_win32_open_a(_zip_source_win32_read_file_t *ctx)
{
return CreateFileA(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
static HANDLE
_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
{
int len;
len = strlen((const char *)ctx->fname) + 10;
if (*temp == NULL) {
if ((*temp = malloc(sizeof(char) * len)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return INVALID_HANDLE_VALUE;
}
}
if (sprintf((char *)*temp, "%s.%08x", (const char *)ctx->fname, value) != len - 1) {
return INVALID_HANDLE_VALUE;
}
return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
}
static int
_win32_rename_temp_a(_zip_source_win32_read_file_t *ctx)
{
if (!MoveFileExA(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
return -1;
return 0;
}
static int
_win32_remove_a(const void *fname)
{
DeleteFileA((const char *)fname);
return 0;
}

View File

@@ -0,0 +1,607 @@
/*
zip_source_win32file.c -- create data source from HANDLE (Win32)
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <wchar.h>
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
#include "zipwin32.h"
static zip_int64_t _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
static int _win32_create_temp_file(_zip_source_win32_read_file_t *ctx);
static int _zip_filetime_to_time_t(FILETIME ft, time_t *t);
static int _zip_seek_win32_u(void *h, zip_uint64_t offset, int whence, zip_error_t *error);
static int _zip_seek_win32(void *h, zip_int64_t offset, int whence, zip_error_t *error);
static int _zip_win32_error_to_errno(unsigned long win32err);
static int _zip_stat_win32(void *h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx);
ZIP_EXTERN zip_source_t *
zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len)
{
if (za == NULL)
return NULL;
return zip_source_win32handle_create(h, start, len, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
{
if (h == INVALID_HANDLE_VALUE || length < -1) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
return _zip_source_win32_handle_or_name(NULL, h, start, length, 1, NULL, NULL, error);
}
zip_source_t *
_zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start, zip_int64_t len, int closep, const zip_stat_t *st, _zip_source_win32_file_ops_t *ops, zip_error_t *error)
{
_zip_source_win32_read_file_t *ctx;
zip_source_t *zs;
if (h == INVALID_HANDLE_VALUE && fname == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx = (_zip_source_win32_read_file_t *)malloc(sizeof(_zip_source_win32_read_file_t))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
ctx->fname = NULL;
if (fname) {
if ((ctx->fname = ops->op_strdup(fname)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(ctx);
return NULL;
}
}
ctx->ops = ops;
ctx->h = h;
ctx->start = start;
ctx->end = (len < 0 ? 0 : start + (zip_uint64_t)len);
ctx->closep = ctx->fname ? 1 : closep;
if (st) {
memcpy(&ctx->st, st, sizeof(ctx->st));
ctx->st.name = NULL;
ctx->st.valid &= ~ZIP_STAT_NAME;
}
else {
zip_stat_init(&ctx->st);
}
ctx->tmpname = NULL;
ctx->hout = INVALID_HANDLE_VALUE;
zip_error_init(&ctx->error);
ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
if (ctx->fname) {
HANDLE th;
th = ops->op_open(ctx);
if (th == INVALID_HANDLE_VALUE || GetFileType(th) == FILE_TYPE_DISK) {
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
}
if (th != INVALID_HANDLE_VALUE) {
CloseHandle(th);
}
}
else if (GetFileType(ctx->h) == FILE_TYPE_DISK) {
ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
}
if ((zs = zip_source_function_create(_win32_read_file, ctx, error)) == NULL) {
free(ctx->fname);
free(ctx);
return NULL;
}
return zs;
}
static zip_int64_t
_win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
{
_zip_source_win32_read_file_t *ctx;
char *buf;
zip_uint64_t n;
DWORD i;
ctx = (_zip_source_win32_read_file_t *)state;
buf = (char *)data;
switch (cmd) {
case ZIP_SOURCE_BEGIN_WRITE:
if (ctx->fname == NULL) {
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
return _win32_create_temp_file(ctx);
case ZIP_SOURCE_COMMIT_WRITE: {
if (!CloseHandle(ctx->hout)) {
ctx->hout = INVALID_HANDLE_VALUE;
zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
}
ctx->hout = INVALID_HANDLE_VALUE;
if (ctx->ops->op_rename_temp(ctx) < 0) {
zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
free(ctx->tmpname);
ctx->tmpname = NULL;
return 0;
}
case ZIP_SOURCE_CLOSE:
if (ctx->fname) {
CloseHandle(ctx->h);
ctx->h = INVALID_HANDLE_VALUE;
}
return 0;
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
free(ctx->fname);
free(ctx->tmpname);
if (ctx->closep && ctx->h != INVALID_HANDLE_VALUE)
CloseHandle(ctx->h);
free(ctx);
return 0;
case ZIP_SOURCE_OPEN:
if (ctx->fname) {
if ((ctx->h = ctx->ops->op_open(ctx)) == INVALID_HANDLE_VALUE) {
zip_error_set(&ctx->error, ZIP_ER_OPEN, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
}
if (ctx->closep && ctx->start > 0) {
if (_zip_seek_win32_u(ctx->h, ctx->start, SEEK_SET, &ctx->error) < 0) {
return -1;
}
}
ctx->current = ctx->start;
return 0;
case ZIP_SOURCE_READ:
if (ctx->end > 0) {
n = ctx->end - ctx->current;
if (n > len) {
n = len;
}
}
else {
n = len;
}
if (n > SIZE_MAX)
n = SIZE_MAX;
if (!ctx->closep) {
if (_zip_seek_win32_u(ctx->h, ctx->current, SEEK_SET, &ctx->error) < 0) {
return -1;
}
}
if (!ReadFile(ctx->h, buf, (DWORD)n, &i, NULL)) {
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
ctx->current += i;
return (zip_int64_t)i;
case ZIP_SOURCE_REMOVE:
if (ctx->ops->op_remove(ctx->fname) < 0) {
zip_error_set(&ctx->error, ZIP_ER_REMOVE, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
return 0;
case ZIP_SOURCE_ROLLBACK_WRITE:
if (ctx->hout) {
CloseHandle(ctx->hout);
ctx->hout = INVALID_HANDLE_VALUE;
}
ctx->ops->op_remove(ctx->tmpname);
free(ctx->tmpname);
ctx->tmpname = NULL;
return 0;
case ZIP_SOURCE_SEEK: {
zip_int64_t new_current;
int need_seek;
zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
if (args == NULL)
return -1;
need_seek = ctx->closep;
switch (args->whence) {
case SEEK_SET:
new_current = args->offset;
break;
case SEEK_END:
if (ctx->end == 0) {
LARGE_INTEGER zero;
LARGE_INTEGER new_offset;
if (_zip_seek_win32(ctx->h, args->offset, SEEK_END, &ctx->error) < 0) {
return -1;
}
zero.QuadPart = 0;
if (!SetFilePointerEx(ctx->h, zero, &new_offset, FILE_CURRENT)) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
new_current = new_offset.QuadPart;
need_seek = 0;
}
else {
new_current = (zip_int64_t)ctx->end + args->offset;
}
break;
case SEEK_CUR:
new_current = (zip_int64_t)ctx->current + args->offset;
break;
default:
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
if (new_current < 0 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
ctx->current = (zip_uint64_t)new_current;
if (need_seek) {
if (_zip_seek_win32_u(ctx->h, ctx->current, SEEK_SET, &ctx->error) < 0) {
return -1;
}
}
return 0;
}
case ZIP_SOURCE_SEEK_WRITE: {
zip_source_args_seek_t *args;
args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
if (args == NULL) {
return -1;
}
if (_zip_seek_win32(ctx->hout, args->offset, args->whence, &ctx->error) < 0) {
return -1;
}
return 0;
}
case ZIP_SOURCE_STAT: {
if (len < sizeof(ctx->st))
return -1;
if (ctx->st.valid != 0)
memcpy(data, &ctx->st, sizeof(ctx->st));
else {
DWORD win32err;
zip_stat_t *st;
HANDLE h;
int success;
st = (zip_stat_t *)data;
if (ctx->h != INVALID_HANDLE_VALUE) {
h = ctx->h;
}
else {
h = ctx->ops->op_open(ctx);
if (h == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) {
zip_error_set(&ctx->error, ZIP_ER_READ, ENOENT);
return -1;
}
}
success = _zip_stat_win32(h, st, ctx);
win32err = GetLastError();
/* We're done with the handle, so close it if we just opened it. */
if (h != ctx->h) {
CloseHandle(h);
}
if (success < 0) {
/* TODO: Is this the correct error to return in all cases? */
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(win32err));
return -1;
}
}
return sizeof(ctx->st);
}
case ZIP_SOURCE_SUPPORTS:
return ctx->supports;
case ZIP_SOURCE_TELL:
return (zip_int64_t)ctx->current;
case ZIP_SOURCE_TELL_WRITE:
{
LARGE_INTEGER zero;
LARGE_INTEGER offset;
zero.QuadPart = 0;
if (!SetFilePointerEx(ctx->hout, zero, &offset, FILE_CURRENT)) {
zip_error_set(&ctx->error, ZIP_ER_TELL, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
return offset.QuadPart;
}
case ZIP_SOURCE_WRITE:
{
DWORD ret;
if (!WriteFile(ctx->hout, data, (DWORD)len, &ret, NULL) || ret != len) {
zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
return (zip_int64_t)ret;
}
default:
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
}
static int
_win32_create_temp_file(_zip_source_win32_read_file_t *ctx)
{
zip_uint32_t value;
/*
Windows has GetTempFileName(), but it closes the file after
creation, leaving it open to a horrible race condition. So
we reinvent the wheel.
*/
int i;
HANDLE th = INVALID_HANDLE_VALUE;
void *temp = NULL;
SECURITY_INFORMATION si;
SECURITY_ATTRIBUTES sa;
PSECURITY_DESCRIPTOR psd = NULL;
PSECURITY_ATTRIBUTES psa = NULL;
DWORD len;
BOOL success;
/*
Read the DACL from the original file, so we can copy it to the temp file.
If there is no original file, or if we can't read the DACL, we'll use the
default security descriptor.
*/
if (ctx->h != INVALID_HANDLE_VALUE && GetFileType(ctx->h) == FILE_TYPE_DISK) {
si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
len = 0;
success = GetUserObjectSecurity(ctx->h, &si, NULL, len, &len);
if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
if ((psd = (PSECURITY_DESCRIPTOR)malloc(len)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
}
success = GetUserObjectSecurity(ctx->h, &si, psd, len, &len);
}
if (success) {
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = psd;
psa = &sa;
}
}
value = GetTickCount();
for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) {
th = ctx->ops->op_create_temp(ctx, &temp, value + i, psa);
if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS)
break;
}
if (th == INVALID_HANDLE_VALUE) {
free(temp);
free(psd);
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
free(psd);
ctx->hout = th;
ctx->tmpname = temp;
return 0;
}
static int
_zip_seek_win32_u(HANDLE h, zip_uint64_t offset, int whence, zip_error_t *error)
{
if (offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
return -1;
}
return _zip_seek_win32(h, (zip_int64_t)offset, whence, error);
}
static int
_zip_seek_win32(HANDLE h, zip_int64_t offset, int whence, zip_error_t *error)
{
LARGE_INTEGER li;
DWORD method;
switch (whence) {
case SEEK_SET:
method = FILE_BEGIN;
break;
case SEEK_END:
method = FILE_END;
break;
case SEEK_CUR:
method = FILE_CURRENT;
break;
default:
zip_error_set(error, ZIP_ER_SEEK, EINVAL);
return -1;
}
li.QuadPart = (LONGLONG)offset;
if (!SetFilePointerEx(h, li, NULL, method)) {
zip_error_set(error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
return 0;
}
static int
_zip_win32_error_to_errno(DWORD win32err)
{
/*
Note: This list isn't exhaustive, but should cover common cases.
*/
switch (win32err) {
case ERROR_INVALID_PARAMETER:
return EINVAL;
case ERROR_FILE_NOT_FOUND:
return ENOENT;
case ERROR_INVALID_HANDLE:
return EBADF;
case ERROR_ACCESS_DENIED:
return EACCES;
case ERROR_FILE_EXISTS:
return EEXIST;
case ERROR_TOO_MANY_OPEN_FILES:
return EMFILE;
case ERROR_DISK_FULL:
return ENOSPC;
default:
return 0;
}
}
static int
_zip_stat_win32(HANDLE h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx)
{
FILETIME mtimeft;
time_t mtime;
LARGE_INTEGER size;
int regularp;
if (!GetFileTime(h, NULL, NULL, &mtimeft)) {
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
if (_zip_filetime_to_time_t(mtimeft, &mtime) < 0) {
zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE);
return -1;
}
regularp = 0;
if (GetFileType(h) == FILE_TYPE_DISK) {
regularp = 1;
}
if (!GetFileSizeEx(h, &size)) {
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
zip_stat_init(st);
st->mtime = mtime;
st->valid |= ZIP_STAT_MTIME;
if (ctx->end != 0) {
st->size = ctx->end - ctx->start;
st->valid |= ZIP_STAT_SIZE;
}
else if (regularp) {
st->size = (zip_uint64_t)size.QuadPart;
st->valid |= ZIP_STAT_SIZE;
}
return 0;
}
static int
_zip_filetime_to_time_t(FILETIME ft, time_t *t)
{
/*
Inspired by http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux
*/
const zip_int64_t WINDOWS_TICK = 10000000LL;
const zip_int64_t SEC_TO_UNIX_EPOCH = 11644473600LL;
ULARGE_INTEGER li;
zip_int64_t secs;
time_t temp;
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
secs = (li.QuadPart / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
temp = (time_t)secs;
if (secs != (zip_int64_t)temp)
return -1;
*t = temp;
return 0;
}

Some files were not shown because too many files have changed in this diff Show More