summaryrefslogtreecommitdiff
path: root/src/archive
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-01-24 00:09:37 +0100
committerMax Kellermann <max@duempel.org>2014-01-24 00:09:37 +0100
commit4aa6d39fd8dfbb822db2f156ba371c1a5000f35c (patch)
tree4075b83e9da4a196e0f84d8fdcbaed8177f2dce1 /src/archive
parent51adaf2c47761e3f2095a52a7037cd8458b77990 (diff)
archive/*: move to archive/plugins/
Diffstat (limited to 'src/archive')
-rw-r--r--src/archive/ArchiveDomain.cxx23
-rw-r--r--src/archive/ArchiveDomain.hxx25
-rw-r--r--src/archive/ArchiveFile.hxx60
-rw-r--r--src/archive/ArchiveList.cxx90
-rw-r--r--src/archive/ArchiveList.hxx47
-rw-r--r--src/archive/ArchiveLookup.cxx103
-rw-r--r--src/archive/ArchiveLookup.hxx45
-rw-r--r--src/archive/ArchivePlugin.cxx39
-rw-r--r--src/archive/ArchivePlugin.hxx60
-rw-r--r--src/archive/ArchiveVisitor.hxx28
-rw-r--r--src/archive/plugins/Bzip2ArchivePlugin.cxx (renamed from src/archive/Bzip2ArchivePlugin.cxx)6
-rw-r--r--src/archive/plugins/Bzip2ArchivePlugin.hxx (renamed from src/archive/Bzip2ArchivePlugin.hxx)0
-rw-r--r--src/archive/plugins/Iso9660ArchivePlugin.cxx (renamed from src/archive/Iso9660ArchivePlugin.cxx)6
-rw-r--r--src/archive/plugins/Iso9660ArchivePlugin.hxx (renamed from src/archive/Iso9660ArchivePlugin.hxx)0
-rw-r--r--src/archive/plugins/ZzipArchivePlugin.cxx (renamed from src/archive/ZzipArchivePlugin.cxx)6
-rw-r--r--src/archive/plugins/ZzipArchivePlugin.hxx (renamed from src/archive/ZzipArchivePlugin.hxx)0
16 files changed, 529 insertions, 9 deletions
diff --git a/src/archive/ArchiveDomain.cxx b/src/archive/ArchiveDomain.cxx
new file mode 100644
index 000000000..4adf4a886
--- /dev/null
+++ b/src/archive/ArchiveDomain.cxx
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "ArchiveDomain.hxx"
+#include "util/Domain.hxx"
+
+const Domain archive_domain("archive");
diff --git a/src/archive/ArchiveDomain.hxx b/src/archive/ArchiveDomain.hxx
new file mode 100644
index 000000000..817ae5835
--- /dev/null
+++ b/src/archive/ArchiveDomain.hxx
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_ARCHIVE_DOMAIN_HXX
+#define MPD_ARCHIVE_DOMAIN_HXX
+
+extern const class Domain archive_domain;
+
+#endif
diff --git a/src/archive/ArchiveFile.hxx b/src/archive/ArchiveFile.hxx
new file mode 100644
index 000000000..b95edcc8d
--- /dev/null
+++ b/src/archive/ArchiveFile.hxx
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_ARCHIVE_FILE_HXX
+#define MPD_ARCHIVE_FILE_HXX
+
+class Mutex;
+class Cond;
+class Error;
+class ArchiveVisitor;
+struct InputStream;
+
+class ArchiveFile {
+public:
+ const struct archive_plugin &plugin;
+
+ ArchiveFile(const struct archive_plugin &_plugin)
+ :plugin(_plugin) {}
+
+protected:
+ /**
+ * Use Close() instead of delete.
+ */
+ ~ArchiveFile() {}
+
+public:
+ virtual void Close() = 0;
+
+ /**
+ * Visit all entries inside this archive.
+ */
+ virtual void Visit(ArchiveVisitor &visitor) = 0;
+
+ /**
+ * Opens an InputStream of a file within the archive.
+ *
+ * @param path the path within the archive
+ */
+ virtual InputStream *OpenStream(const char *path,
+ Mutex &mutex, Cond &cond,
+ Error &error) = 0;
+};
+
+#endif
diff --git a/src/archive/ArchiveList.cxx b/src/archive/ArchiveList.cxx
new file mode 100644
index 000000000..bf6493588
--- /dev/null
+++ b/src/archive/ArchiveList.cxx
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "ArchiveList.hxx"
+#include "ArchivePlugin.hxx"
+#include "util/StringUtil.hxx"
+#include "plugins/Bzip2ArchivePlugin.hxx"
+#include "plugins/Iso9660ArchivePlugin.hxx"
+#include "plugins/ZzipArchivePlugin.hxx"
+#include "util/Macros.hxx"
+
+#include <string.h>
+
+const struct archive_plugin *const archive_plugins[] = {
+#ifdef HAVE_BZ2
+ &bz2_archive_plugin,
+#endif
+#ifdef HAVE_ZZIP
+ &zzip_archive_plugin,
+#endif
+#ifdef HAVE_ISO9660
+ &iso9660_archive_plugin,
+#endif
+ nullptr
+};
+
+/** which plugins have been initialized successfully? */
+static bool archive_plugins_enabled[ARRAY_SIZE(archive_plugins) - 1];
+
+#define archive_plugins_for_each_enabled(plugin) \
+ archive_plugins_for_each(plugin) \
+ if (archive_plugins_enabled[archive_plugin_iterator - archive_plugins])
+
+const struct archive_plugin *
+archive_plugin_from_suffix(const char *suffix)
+{
+ if (suffix == nullptr)
+ return nullptr;
+
+ archive_plugins_for_each_enabled(plugin)
+ if (plugin->suffixes != nullptr &&
+ string_array_contains(plugin->suffixes, suffix))
+ return plugin;
+
+ return nullptr;
+}
+
+const struct archive_plugin *
+archive_plugin_from_name(const char *name)
+{
+ archive_plugins_for_each_enabled(plugin)
+ if (strcmp(plugin->name, name) == 0)
+ return plugin;
+
+ return nullptr;
+}
+
+void archive_plugin_init_all(void)
+{
+ for (unsigned i = 0; archive_plugins[i] != nullptr; ++i) {
+ const struct archive_plugin *plugin = archive_plugins[i];
+ if (plugin->init == nullptr || archive_plugins[i]->init())
+ archive_plugins_enabled[i] = true;
+ }
+}
+
+void archive_plugin_deinit_all(void)
+{
+ archive_plugins_for_each_enabled(plugin)
+ if (plugin->finish != nullptr)
+ plugin->finish();
+}
+
diff --git a/src/archive/ArchiveList.hxx b/src/archive/ArchiveList.hxx
new file mode 100644
index 000000000..49798a93e
--- /dev/null
+++ b/src/archive/ArchiveList.hxx
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_ARCHIVE_LIST_HXX
+#define MPD_ARCHIVE_LIST_HXX
+
+struct archive_plugin;
+
+extern const struct archive_plugin *const archive_plugins[];
+
+#define archive_plugins_for_each(plugin) \
+ for (const struct archive_plugin *plugin, \
+ *const*archive_plugin_iterator = &archive_plugins[0]; \
+ (plugin = *archive_plugin_iterator) != nullptr; \
+ ++archive_plugin_iterator)
+
+/* interface for using plugins */
+
+const struct archive_plugin *
+archive_plugin_from_suffix(const char *suffix);
+
+const struct archive_plugin *
+archive_plugin_from_name(const char *name);
+
+/* this is where we "load" all the "plugins" ;-) */
+void archive_plugin_init_all(void);
+
+/* this is where we "unload" all the "plugins" */
+void archive_plugin_deinit_all(void);
+
+#endif
diff --git a/src/archive/ArchiveLookup.cxx b/src/archive/ArchiveLookup.cxx
new file mode 100644
index 000000000..53730c504
--- /dev/null
+++ b/src/archive/ArchiveLookup.cxx
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h" /* must be first for large file support */
+#include "ArchiveLookup.hxx"
+#include "ArchiveDomain.hxx"
+#include "Log.hxx"
+
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+gcc_pure
+static char *
+FindSlash(char *p, size_t i)
+{
+ for (; i > 0; --i)
+ if (p[i] == '/')
+ return p + i;
+
+ return nullptr;
+}
+
+gcc_pure
+static const char *
+FindSuffix(const char *p, const char *i)
+{
+ for (; i > p; --i) {
+ if (*i == '.')
+ return i + 1;
+ }
+
+ return nullptr;
+}
+
+bool
+archive_lookup(char *pathname, const char **archive,
+ const char **inpath, const char **suffix)
+{
+ size_t idx = strlen(pathname);
+
+ char *slash = nullptr;
+
+ while (true) {
+ //try to stat if its real directory
+ struct stat st_info;
+ if (stat(pathname, &st_info) == -1) {
+ if (errno != ENOTDIR) {
+ FormatErrno(archive_domain,
+ "Failed to stat %s", pathname);
+ return false;
+ }
+ } else {
+ //is something found ins original path (is not an archive)
+ if (slash == nullptr)
+ return false;
+
+ //its a file ?
+ if (S_ISREG(st_info.st_mode)) {
+ //so the upper should be file
+ *archive = pathname;
+ *inpath = slash + 1;
+
+ //try to get suffix
+ *suffix = FindSuffix(pathname, slash - 1);
+ return true;
+ } else {
+ FormatError(archive_domain,
+ "Not a regular file: %s",
+ pathname);
+ return false;
+ }
+ }
+
+ //find one dir up
+ if (slash != nullptr)
+ *slash = '/';
+
+ slash = FindSlash(pathname, idx - 1);
+ if (slash == nullptr)
+ return false;
+
+ *slash = 0;
+ idx = slash - pathname;
+ }
+}
+
diff --git a/src/archive/ArchiveLookup.hxx b/src/archive/ArchiveLookup.hxx
new file mode 100644
index 000000000..0c08951a9
--- /dev/null
+++ b/src/archive/ArchiveLookup.hxx
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_ARCHIVE_LOOKUP_HXX
+#define MPD_ARCHIVE_LOOKUP_HXX
+
+/**
+ *
+ * archive_lookup is used to determine if part of pathname refers to an regular
+ * file (archive). If so then its also used to split pathname into archive file
+ * and path used to locate file in archive. It also returns suffix of the file.
+ * How it works:
+ * We do stat of the parent of input pathname as long as we find an regular file
+ * Normally this should never happen. When routine returns true pathname modified
+ * and split into archive, inpath and suffix. Otherwise nothing happens
+ *
+ * For example:
+ *
+ * /music/path/Talco.zip/Talco - Combat Circus/12 - A la pachenka.mp3
+ * is split into archive: /music/path/Talco.zip
+ * inarchive pathname: Talco - Combat Circus/12 - A la pachenka.mp3
+ * and suffix: zip
+ */
+bool
+archive_lookup(char *pathname, const char **archive,
+ const char **inpath, const char **suffix);
+
+#endif
+
diff --git a/src/archive/ArchivePlugin.cxx b/src/archive/ArchivePlugin.cxx
new file mode 100644
index 000000000..f8025a121
--- /dev/null
+++ b/src/archive/ArchivePlugin.cxx
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "ArchivePlugin.hxx"
+#include "ArchiveFile.hxx"
+#include "util/Error.hxx"
+
+#include <assert.h>
+
+ArchiveFile *
+archive_file_open(const struct archive_plugin *plugin, const char *path,
+ Error &error)
+{
+ assert(plugin != nullptr);
+ assert(plugin->open != nullptr);
+ assert(path != nullptr);
+
+ ArchiveFile *file = plugin->open(path, error);
+ assert((file == nullptr) == error.IsDefined());
+
+ return file;
+}
diff --git a/src/archive/ArchivePlugin.hxx b/src/archive/ArchivePlugin.hxx
new file mode 100644
index 000000000..602de240a
--- /dev/null
+++ b/src/archive/ArchivePlugin.hxx
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_ARCHIVE_PLUGIN_HXX
+#define MPD_ARCHIVE_PLUGIN_HXX
+
+class ArchiveFile;
+class Error;
+
+struct archive_plugin {
+ const char *name;
+
+ /**
+ * optional, set this to nullptr if the archive plugin doesn't
+ * have/need one this must false if there is an error and
+ * true otherwise
+ */
+ bool (*init)(void);
+
+ /**
+ * optional, set this to nullptr if the archive plugin doesn't
+ * have/need one
+ */
+ void (*finish)(void);
+
+ /**
+ * tryes to open archive file and associates handle with archive
+ * returns pointer to handle used is all operations with this archive
+ * or nullptr when opening fails
+ */
+ ArchiveFile *(*open)(const char *path_fs, Error &error);
+
+ /**
+ * suffixes handled by this plugin.
+ * last element in these arrays must always be a nullptr
+ */
+ const char *const*suffixes;
+};
+
+ArchiveFile *
+archive_file_open(const struct archive_plugin *plugin, const char *path,
+ Error &error);
+
+#endif
diff --git a/src/archive/ArchiveVisitor.hxx b/src/archive/ArchiveVisitor.hxx
new file mode 100644
index 000000000..6759695ca
--- /dev/null
+++ b/src/archive/ArchiveVisitor.hxx
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_ARCHIVE_VISITOR_HXX
+#define MPD_ARCHIVE_VISITOR_HXX
+
+class ArchiveVisitor {
+public:
+ virtual void VisitArchiveEntry(const char *path_utf8) = 0;
+};
+
+#endif
diff --git a/src/archive/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx
index 643892917..0e75dd77f 100644
--- a/src/archive/Bzip2ArchivePlugin.cxx
+++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx
@@ -23,9 +23,9 @@
#include "config.h"
#include "Bzip2ArchivePlugin.hxx"
-#include "ArchivePlugin.hxx"
-#include "ArchiveFile.hxx"
-#include "ArchiveVisitor.hxx"
+#include "../ArchivePlugin.hxx"
+#include "../ArchiveFile.hxx"
+#include "../ArchiveVisitor.hxx"
#include "InputStream.hxx"
#include "InputPlugin.hxx"
#include "util/RefCount.hxx"
diff --git a/src/archive/Bzip2ArchivePlugin.hxx b/src/archive/plugins/Bzip2ArchivePlugin.hxx
index 060780633..060780633 100644
--- a/src/archive/Bzip2ArchivePlugin.hxx
+++ b/src/archive/plugins/Bzip2ArchivePlugin.hxx
diff --git a/src/archive/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx
index 120070cc1..8f3300b3e 100644
--- a/src/archive/Iso9660ArchivePlugin.cxx
+++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx
@@ -23,9 +23,9 @@
#include "config.h"
#include "Iso9660ArchivePlugin.hxx"
-#include "ArchivePlugin.hxx"
-#include "ArchiveFile.hxx"
-#include "ArchiveVisitor.hxx"
+#include "../ArchivePlugin.hxx"
+#include "../ArchiveFile.hxx"
+#include "../ArchiveVisitor.hxx"
#include "InputStream.hxx"
#include "InputPlugin.hxx"
#include "util/RefCount.hxx"
diff --git a/src/archive/Iso9660ArchivePlugin.hxx b/src/archive/plugins/Iso9660ArchivePlugin.hxx
index e92d5962b..e92d5962b 100644
--- a/src/archive/Iso9660ArchivePlugin.hxx
+++ b/src/archive/plugins/Iso9660ArchivePlugin.hxx
diff --git a/src/archive/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx
index 6b21d6ed4..c1446da74 100644
--- a/src/archive/ZzipArchivePlugin.cxx
+++ b/src/archive/plugins/ZzipArchivePlugin.cxx
@@ -23,9 +23,9 @@
#include "config.h"
#include "ZzipArchivePlugin.hxx"
-#include "ArchivePlugin.hxx"
-#include "ArchiveFile.hxx"
-#include "ArchiveVisitor.hxx"
+#include "../ArchivePlugin.hxx"
+#include "../ArchiveFile.hxx"
+#include "../ArchiveVisitor.hxx"
#include "InputStream.hxx"
#include "InputPlugin.hxx"
#include "util/RefCount.hxx"
diff --git a/src/archive/ZzipArchivePlugin.hxx b/src/archive/plugins/ZzipArchivePlugin.hxx
index f82f62eb6..f82f62eb6 100644
--- a/src/archive/ZzipArchivePlugin.hxx
+++ b/src/archive/plugins/ZzipArchivePlugin.hxx