#include <openssl/pkcs12.h>
#include <openssl/sha.h>
-#include <plist/plist++.h>
+#include <plist/plist.h>
#include "ldid.hpp"
static void mkdir_p(const std::string &path) {
if (path.empty())
return;
+#ifdef __WIN32__
+ if (_syscall(mkdir(path.c_str()), EEXIST) == -EEXIST)
+ return;
+#else
if (_syscall(mkdir(path.c_str(), 0755), EEXIST) == -EEXIST)
return;
+#endif
auto slash(path.rfind('/', path.size() - 1));
if (slash == std::string::npos)
return;
if (Starts(name, ".ldid."))
continue;
+ bool directory;
+
+#ifdef __WIN32__
+ struct stat info;
+ _syscall(stat(path.c_str(), &info));
+ if (false);
+ else if (S_ISDIR(info.st_mode))
+ directory = true;
+ else if (S_ISREG(info.st_mode))
+ directory = false;
+ else
+ _assert_(false, "st_mode=%x", info.st_mode);
+#else
switch (child->d_type) {
case DT_DIR:
- Find(root, base + name + "/", code);
- break;
-
+ directory = true;
+ break;
case DT_REG:
- code(base + name, fun([&](const Functor<void (std::streambuf &, std::streambuf &)> &code) {
- std::string access(root + base + name);
- _assert_(Open(access, fun([&](std::streambuf &data) {
- NullBuffer save;
- code(data, save);
- })), "open(): %s", access.c_str());
- }));
- break;
-
+ directory = false;
+ break;
default:
_assert_(false, "d_type=%u", child->d_type);
- break;
}
+#endif
+
+ if (directory)
+ Find(root, base + name + "/", code);
+ else
+ code(base + name, fun([&](const Functor<void (std::streambuf &, std::streambuf &)> &code) {
+ std::string access(root + base + name);
+ _assert_(Open(access, fun([&](std::streambuf &data) {
+ NullBuffer save;
+ code(data, save);
+ })), "open(): %s", access.c_str());
+ }));
}
}
Find(path, "", code);
}
-SubFolder::SubFolder(Folder *parent, const std::string &path) :
+SubFolder::SubFolder(Folder &parent, const std::string &path) :
parent_(parent),
path_(path)
{
}
void SubFolder::Save(const std::string &path, const Functor<void (std::streambuf &)> &code) {
- return parent_->Save(path_ + path, code);
+ return parent_.Save(path_ + path, code);
}
bool SubFolder::Open(const std::string &path, const Functor<void (std::streambuf &)> &code) {
- return parent_->Open(path_ + path, code);
+ return parent_.Open(path_ + path, code);
}
void SubFolder::Find(const std::string &path, const Functor<void (const std::string &, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &)> &code) {
- return parent_->Find(path_ + path, code);
+ return parent_.Find(path_ + path, code);
+}
+
+UnionFolder::UnionFolder(Folder &parent) :
+ parent_(parent)
+{
+}
+
+void UnionFolder::Save(const std::string &path, const Functor<void (std::streambuf &)> &code) {
+ return parent_.Save(path, code);
+}
+
+bool UnionFolder::Open(const std::string &path, const Functor<void (std::streambuf &)> &code) {
+ auto file(files_.find(path));
+ if (file == files_.end())
+ return parent_.Open(path, code);
+
+ auto &data(file->second);
+ data.pubseekpos(0, std::ios::in);
+ code(data);
+ return true;
+}
+
+void UnionFolder::Find(const std::string &path, const Functor<void (const std::string &, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &)> &code) {
+ parent_.Find(path, fun([&](const std::string &name, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &save) {
+ if (files_.find(name) == files_.end())
+ code(name, save);
+ }));
+
+ for (auto &file : files_)
+ code(file.first, fun([&](const Functor<void (std::streambuf &, std::streambuf &)> &code) {
+ parent_.Save(file.first, fun([&](std::streambuf &save) {
+ file.second.pubseekpos(0, std::ios::in);
+ code(file.second, save);
+ }));
+ }));
}
static size_t copy(std::streambuf &source, std::streambuf &target) {
return total;
}
-static PList::Structure *plist(const std::string &data) {
- if (!Starts(data, "bplist00"))
- return PList::Structure::FromXml(data);
- std::vector<char> bytes(data.data(), data.data() + data.size());
- return PList::Structure::FromBin(bytes);
+static plist_t plist(const std::string &data) {
+ plist_t plist(NULL);
+ if (Starts(data, "bplist00"))
+ plist_from_bin(data.data(), data.size(), &plist);
+ else
+ plist_from_xml(data.data(), data.size(), &plist);
+ _assert(plist != NULL);
+ return plist;
}
-static void plist_d(std::streambuf &buffer, const Functor<void (PList::Dictionary *)> &code) {
+static void plist_d(std::streambuf &buffer, const Functor<void (plist_t)> &code) {
std::stringbuf data;
copy(buffer, data);
- PList::Structure *structure(plist(data.str()));
- _scope({ delete structure; });
- auto dictionary(dynamic_cast<PList::Dictionary *>(structure));
- _assert(dictionary != NULL);
- code(dictionary);
+ auto node(plist(data.str()));
+ _scope({ plist_free(node); });
+ _assert(plist_get_node_type(node) == PLIST_DICT);
+ code(node);
}
-static std::string plist_s(PList::Node *node) {
- auto value(dynamic_cast<PList::String *>(node));
- _assert(value != NULL);
- return value->GetValue();
+static std::string plist_s(plist_t node) {
+ _assert(node != NULL);
+ _assert(plist_get_node_type(node) == PLIST_STRING);
+ char *data;
+ plist_get_string_val(node, &data);
+ _scope({ free(data); });
+ return data;
}
enum Mode {
static const std::string info("Info.plist");
_assert_(folder.Open(info, fun([&](std::streambuf &buffer) {
- plist_d(buffer, fun([&](PList::Dictionary *dictionary) {
- executable = plist_s(((*dictionary)["CFBundleExecutable"]));
- identifier = plist_s(((*dictionary)["CFBundleIdentifier"]));
+ plist_d(buffer, fun([&](plist_t node) {
+ executable = plist_s(plist_dict_get_item(node, "CFBundleExecutable"));
+ identifier = plist_s(plist_dict_get_item(node, "CFBundleIdentifier"));
}));
})), "open(): Info.plist");
static const std::string signature("_CodeSignature/CodeResources");
folder.Open(signature, fun([&](std::streambuf &buffer) {
- plist_d(buffer, fun([&](PList::Dictionary *dictionary) {
+ plist_d(buffer, fun([&](plist_t node) {
// XXX: maybe attempt to preserve existing rules
}));
}));
if (!nested(name))
return;
auto bundle(root + Split(name).dir);
- SubFolder subfolder(&folder, bundle);
+ SubFolder subfolder(folder, bundle);
Bundle(bundle, subfolder, key, local);
}));
_assert(hash.size() == SHA_DIGEST_LENGTH);
}));
- PList::Dictionary plist;
+ auto plist(plist_new_dict());
+ _scope({ plist_free(plist); });
for (const auto &version : versions) {
- PList::Dictionary files;
+ auto files(plist_new_dict());
+ plist_dict_set_item(plist, ("files" + version.first).c_str(), files);
for (const auto &rule : version.second)
rule.Compile();
for (const auto &rule : version.second)
if (rule(hash.first)) {
if (rule.mode_ == NoMode)
- files.Set(hash.first, PList::Data(hash.second));
+ plist_dict_set_item(files, hash.first.c_str(), plist_new_data(hash.second.data(), hash.second.size()));
else if (rule.mode_ == OptionalMode) {
- PList::Dictionary entry;
- entry.Set("hash", PList::Data(hash.second));
- entry.Set("optional", PList::Boolean(true));
- files.Set(hash.first, entry);
+ auto entry(plist_new_dict());
+ plist_dict_set_item(entry, "hash", plist_new_data(hash.second.data(), hash.second.size()));
+ plist_dict_set_item(entry, "optional", plist_new_bool(true));
+ plist_dict_set_item(files, hash.first.c_str(), entry);
}
break;
}
-
- plist.Set("files" + version.first, files);
}
for (const auto &version : versions) {
- PList::Dictionary rules;
+ auto rules(plist_new_dict());
+ plist_dict_set_item(plist, ("rules" + version.first).c_str(), rules);
std::multiset<const Rule *, RuleCode> ordered;
for (const auto &rule : version.second)
for (const auto &rule : ordered)
if (rule->weight_ == 1 && rule->mode_ == NoMode)
- rules.Set(rule->code_, PList::Boolean(true));
+ plist_dict_set_item(rules, rule->code_.c_str(), plist_new_bool(true));
else {
- PList::Dictionary entry;
+ auto entry(plist_new_dict());
+ plist_dict_set_item(rules, rule->code_.c_str(), entry);
switch (rule->mode_) {
case NoMode:
break;
case OmitMode:
- entry.Set("omit", PList::Boolean(true));
+ plist_dict_set_item(entry, "omit", plist_new_bool(true));
break;
case OptionalMode:
- entry.Set("optional", PList::Boolean(true));
+ plist_dict_set_item(entry, "optional", plist_new_bool(true));
break;
case NestedMode:
- entry.Set("nested", PList::Boolean(true));
+ plist_dict_set_item(entry, "nested", plist_new_bool(true));
break;
case TopMode:
- entry.Set("top", PList::Boolean(true));
+ plist_dict_set_item(entry, "top", plist_new_bool(true));
break;
}
if (rule->weight_ >= 10000)
- entry.Set("weight", PList::Integer(rule->weight_));
+ plist_dict_set_item(entry, "weight", plist_new_uint(rule->weight_));
else if (rule->weight_ != 1)
- entry.Set("weight", PList::Real(rule->weight_));
-
- rules.Set(rule->code_, entry);
+ plist_dict_set_item(entry, "weight", plist_new_real(rule->weight_));
}
-
- plist.Set("rules" + version.first, rules);
}
folder.Save(signature, fun([&](std::streambuf &save) {
HashProxy proxy(local[signature], save);
- auto xml(plist.ToXml());
- put(proxy, xml.data(), xml.size());
+ char *xml(NULL);
+ uint32_t size;
+ plist_to_xml(plist, &xml, &size);
+ _scope({ free(xml); });
+ put(proxy, xml, size);
}));
folder.Open(executable, fun([&](std::streambuf &buffer) {