1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-07 06:01:48 +02:00

Remove ZipInputAccessor

This commit is contained in:
Eelco Dolstra 2023-02-01 00:10:58 +01:00
parent 5c29abc5bd
commit 4142982140
4 changed files with 1 additions and 205 deletions

View file

@ -182,9 +182,6 @@ if test "$shared" != yes; then
LIBARCHIVE_LIBS+=' -lz' LIBARCHIVE_LIBS+=' -lz'
fi fi
# Look for libzip.
PKG_CHECK_MODULES([LIBZIP], [libzip])
# Look for SQLite, a required dependency. # Look for SQLite, a required dependency.
PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19], [CXXFLAGS="$SQLITE3_CFLAGS $CXXFLAGS"]) PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19], [CXXFLAGS="$SQLITE3_CFLAGS $CXXFLAGS"])

View file

@ -115,11 +115,6 @@
bzip2 xz brotli editline bzip2 xz brotli editline
openssl sqlite openssl sqlite
libarchive libarchive
(libzip.overrideDerivation (old: {
# Temporary workaround for https://github.com/NixOS/nixpkgs/pull/178755
cmakeFlags = old.cmakeFlags or [] ++ [ "-DBUILD_REGRESS=0" ];
patches = [ ./libzip-unix-time.patch ];
}))
libgit2 libgit2
boost boost
lowdown-nix lowdown-nix

View file

@ -8,6 +8,6 @@ libfetchers_SOURCES := $(wildcard $(d)/*.cc)
libfetchers_CXXFLAGS += -I src/libutil -I src/libstore libfetchers_CXXFLAGS += -I src/libutil -I src/libstore
libfetchers_LDFLAGS += -pthread -lzip -lgit2 -larchive libfetchers_LDFLAGS += -pthread -lgit2 -larchive
libfetchers_LIBS = libutil libstore libfetchers_LIBS = libutil libstore

View file

@ -1,196 +0,0 @@
#include "input-accessor.hh"
#include <zip.h>
#include <arpa/inet.h>
namespace nix {
struct cmp_str
{
bool operator ()(const char * a, const char * b) const
{
return std::strcmp(a, b) < 0;
}
};
struct ZipMember
{
struct zip_file * p = nullptr;
ZipMember(struct zip_file * p) : p(p) { }
~ZipMember() { if (p) zip_fclose(p); }
operator zip_file *() { return p; }
};
struct ZipInputAccessor : InputAccessor
{
CanonPath zipPath;
struct zip * zipFile = nullptr;
typedef std::map<const char *, struct zip_stat, cmp_str> Members;
Members members;
time_t lastModified = 0;
ZipInputAccessor(const CanonPath & _zipPath)
: zipPath(_zipPath)
{
int error;
zipFile = zip_open(zipPath.c_str(), ZIP_RDONLY, &error);
if (!zipFile) {
char errorMsg[1024];
zip_error_to_str(errorMsg, sizeof errorMsg, error, errno);
throw Error("couldn't open '%s': %s", zipPath, errorMsg);
}
/* Read the index of the zip file and put it in a map. This
is unfortunately necessary because libzip's lookup
functions are O(n) time. */
struct zip_stat sb;
zip_uint64_t nrEntries = zip_get_num_entries(zipFile, 0);
for (zip_uint64_t n = 0; n < nrEntries; ++n) {
if (zip_stat_index(zipFile, n, 0, &sb))
throw Error("couldn't stat archive member #%d in '%s': %s", n, zipPath, zip_strerror(zipFile));
/* Get the timestamp of this file. */
#if 0
if (sb.valid & ZIP_STAT_MTIME)
lastModified = std::max(lastModified, sb.mtime);
#endif
auto nExtra = zip_file_extra_fields_count(zipFile, n, ZIP_FL_CENTRAL);
for (auto i = 0; i < nExtra; ++i) {
zip_uint16_t id, len;
auto extra = zip_file_extra_field_get(zipFile, i, 0, &id, &len, ZIP_FL_CENTRAL);
if (id == 0x5455 && len >= 5)
lastModified = std::max(lastModified, (time_t) readLittleEndian<uint32_t>((unsigned char *) extra + 1));
}
auto slash = strchr(sb.name, '/');
if (!slash) continue;
members.emplace(slash, sb);
}
}
~ZipInputAccessor()
{
if (zipFile) zip_close(zipFile);
}
std::string _readFile(const CanonPath & path)
{
auto i = members.find(((std::string) path.abs()).c_str());
if (i == members.end())
throw Error("file '%s' does not exist", showPath(path));
ZipMember member(zip_fopen_index(zipFile, i->second.index, 0));
if (!member)
throw Error("couldn't open archive member '%s': %s",
showPath(path), zip_strerror(zipFile));
std::string buf(i->second.size, 0);
if (zip_fread(member, buf.data(), i->second.size) != (zip_int64_t) i->second.size)
throw Error("couldn't read archive member '%s' in '%s'", path, zipPath);
return buf;
}
std::string readFile(const CanonPath & path) override
{
if (lstat(path).type != tRegular)
throw Error("file '%s' is not a regular file", path);
return _readFile(path);
}
bool pathExists(const CanonPath & path) override
{
return
members.find(path.c_str()) != members.end()
|| members.find(((std::string) path.abs() + "/").c_str()) != members.end();
}
Stat lstat(const CanonPath & path) override
{
if (path.isRoot())
return Stat { .type = tDirectory };
Type type = tRegular;
bool isExecutable = false;
auto i = members.find(path.c_str());
if (i == members.end()) {
i = members.find(((std::string) path.abs() + "/").c_str());
type = tDirectory;
}
if (i == members.end())
throw Error("file '%s' does not exist", showPath(path));
// FIXME: cache this
zip_uint8_t opsys;
zip_uint32_t attributes;
if (zip_file_get_external_attributes(zipFile, i->second.index, ZIP_FL_UNCHANGED, &opsys, &attributes) == -1)
throw Error("couldn't get external attributes of '%s': %s",
showPath(path), zip_strerror(zipFile));
switch (opsys) {
case ZIP_OPSYS_UNIX:
auto t = (attributes >> 16) & 0770000;
switch (t) {
case 0040000: type = tDirectory; break;
case 0100000:
type = tRegular;
isExecutable = (attributes >> 16) & 0000100;
break;
case 0120000: type = tSymlink; break;
default:
throw Error("file '%s' has unsupported type %o", showPath(path), t);
}
break;
}
return Stat { .type = type, .isExecutable = isExecutable };
}
DirEntries readDirectory(const CanonPath & _path) override
{
std::string path(_path.abs());
if (path != "/") path += "/";
auto i = members.find(path.c_str());
if (i == members.end())
throw Error("directory '%s' does not exist", showPath(_path));
++i;
DirEntries entries;
for (; i != members.end() && strncmp(i->first, path.c_str(), path.size()) == 0; ++i) {
auto start = i->first + path.size();
auto slash = strchr(start, '/');
if (slash && strcmp(slash, "/") != 0) continue;
auto name = slash ? std::string(start, slash - start) : std::string(start);
entries.emplace(name, std::nullopt);
}
return entries;
}
std::string readLink(const CanonPath & path) override
{
if (lstat(path).type != tSymlink)
throw Error("file '%s' is not a symlink", showPath(path));
return _readFile(path);
}
std::optional<time_t> getLastModified() override
{
return lastModified;
}
};
ref<InputAccessor> makeZipInputAccessor(const CanonPath & path)
{
return make_ref<ZipInputAccessor>(path);
}
}