aboutsummaryrefslogtreecommitdiff
path: root/paludis/repositories/e/vdb_id.cc
diff options
context:
space:
mode:
Diffstat (limited to 'paludis/repositories/e/vdb_id.cc')
-rw-r--r--paludis/repositories/e/vdb_id.cc72
1 files changed, 69 insertions, 3 deletions
diff --git a/paludis/repositories/e/vdb_id.cc b/paludis/repositories/e/vdb_id.cc
index 79eb554..23efddb 100644
--- a/paludis/repositories/e/vdb_id.cc
+++ b/paludis/repositories/e/vdb_id.cc
@@ -19,7 +19,18 @@
#include <paludis/repositories/e/vdb_id.hh>
#include <paludis/repositories/e/e_key.hh>
+#include <paludis/repositories/e/vdb_contents_tokeniser.hh>
#include <paludis/util/fs_path.hh>
+#include <paludis/util/fs_stat.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/safe_ifstream.hh>
+#include <paludis/util/destringify.hh>
+#include <paludis/util/timestamp.hh>
+#include <paludis/contents.hh>
+#include <paludis/literal_metadata_key.hh>
+
+#include <vector>
using namespace paludis;
using namespace paludis::erepository;
@@ -50,9 +61,64 @@ VDBID::contents_filename() const
return "CONTENTS";
}
-std::shared_ptr<MetadataValueKey<std::shared_ptr<const Contents> > >
-VDBID::make_contents_key() const
+const std::shared_ptr<const Contents>
+VDBID::contents() const
{
- return std::make_shared<EContentsKey>("CONTENTS", "Contents", fs_location_key()->parse_value() / "CONTENTS", mkt_internal);
+ FSPath contents_location(fs_location_key()->parse_value() / "CONTENTS");
+ Context context("When creating contents from '" + stringify(contents_location) + "':");
+
+ auto value(std::make_shared<Contents>());
+
+ if (! contents_location.stat().is_regular_file_or_symlink_to_regular_file())
+ {
+ Log::get_instance()->message("e.contents.not_a_file", ll_warning, lc_context) << "Could not read CONTENTS file '" <<
+ contents_location << "'";
+ return value;
+ }
+
+ SafeIFStream ff(contents_location);
+
+ std::string line;
+ unsigned line_number(0);
+ while (std::getline(ff, line))
+ {
+ ++line_number;
+
+ std::vector<std::string> tokens;
+ if (! VDBContentsTokeniser::tokenise(line, std::back_inserter(tokens)))
+ {
+ Log::get_instance()->message("e.contents.broken", ll_warning, lc_context) << "CONTENTS has broken line '" <<
+ line_number << "', skipping";
+ continue;
+ }
+
+ if ("obj" == tokens.at(0))
+ {
+ std::shared_ptr<ContentsEntry> e(std::make_shared<ContentsFileEntry>(FSPath(tokens.at(1))));
+ e->add_metadata_key(std::make_shared<LiteralMetadataTimeKey>("mtime", "mtime", mkt_normal,
+ Timestamp(destringify<time_t>(tokens.at(3)), 0)));
+ e->add_metadata_key(std::make_shared<LiteralMetadataValueKey<std::string>>("md5", "md5", mkt_normal, tokens.at(2)));
+ value->add(e);
+ }
+ else if ("dir" == tokens.at(0))
+ {
+ std::shared_ptr<ContentsEntry> e(std::make_shared<ContentsDirEntry>(FSPath(tokens.at(1))));
+ value->add(e);
+ }
+ else if ("sym" == tokens.at(0))
+ {
+ std::shared_ptr<ContentsEntry> e(std::make_shared<ContentsSymEntry>(FSPath(tokens.at(1)), tokens.at(2)));
+ e->add_metadata_key(std::make_shared<LiteralMetadataTimeKey>("mtime", "mtime", mkt_normal,
+ Timestamp(destringify<time_t>(tokens.at(3)), 0)));
+ value->add(e);
+ }
+ else if ("misc" == tokens.at(0) || "fif" == tokens.at(0) || "dev" == tokens.at(0))
+ value->add(std::shared_ptr<ContentsEntry>(std::make_shared<ContentsOtherEntry>(FSPath(tokens.at(1)))));
+ else
+ Log::get_instance()->message("e.contents.unknown", ll_warning, lc_context) << "CONTENTS has unsupported entry type '" <<
+ tokens.at(0) << "', skipping";
+ }
+
+ return value;
}