diff --git a/configure.ac b/configure.ac index b3ec4dc74..0066bc389 100644 --- a/configure.ac +++ b/configure.ac @@ -182,9 +182,6 @@ if test "$shared" != yes; then LIBARCHIVE_LIBS+=' -lz' fi -# Look for libzip. -PKG_CHECK_MODULES([LIBZIP], [libzip]) - # Look for SQLite, a required dependency. PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19], [CXXFLAGS="$SQLITE3_CFLAGS $CXXFLAGS"]) diff --git a/flake.nix b/flake.nix index 38cbc24cc..81e6ca3ca 100644 --- a/flake.nix +++ b/flake.nix @@ -115,11 +115,6 @@ bzip2 xz brotli editline openssl sqlite 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 boost lowdown-nix diff --git a/src/libfetchers/local.mk b/src/libfetchers/local.mk index 4b27fd443..f21651d77 100644 --- a/src/libfetchers/local.mk +++ b/src/libfetchers/local.mk @@ -8,6 +8,6 @@ libfetchers_SOURCES := $(wildcard $(d)/*.cc) libfetchers_CXXFLAGS += -I src/libutil -I src/libstore -libfetchers_LDFLAGS += -pthread -lzip -lgit2 -larchive +libfetchers_LDFLAGS += -pthread -lgit2 -larchive libfetchers_LIBS = libutil libstore diff --git a/src/libfetchers/zip-input-accessor.cc b/src/libfetchers/zip-input-accessor.cc deleted file mode 100644 index 8da601b77..000000000 --- a/src/libfetchers/zip-input-accessor.cc +++ /dev/null @@ -1,196 +0,0 @@ -#include "input-accessor.hh" - -#include -#include - -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 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((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 getLastModified() override - { - return lastModified; - } -}; - -ref makeZipInputAccessor(const CanonPath & path) -{ - return make_ref(path); -} - -}