]> git.cameronkatri.com Git - ldid.git/blobdiff - ldid.cpp
Link libplist and switch to their C++ wrapper API.
[ldid.git] / ldid.cpp
index 0cb8dd2f74108237a60b317768601ca7be143d92..d95be4effb2925d37904f7fca36443b53564fe57 100644 (file)
--- a/ldid.cpp
+++ b/ldid.cpp
@@ -43,7 +43,7 @@
 #include <openssl/pkcs12.h>
 #include <openssl/sha.h>
 
-#include <plist/plist.h>
+#include <plist/plist++.h>
 
 #include "ldid.hpp"
 
     #line
 #define _assert__(line) \
     _assert___(line)
-#define _assert_(e) \
-    throw __FILE__ "(" _assert__(__LINE__) "): _assert(" e ")"
 
-#define _assert(expr) \
+#define _assert_(expr, format, ...) \
     do if (!(expr)) { \
-        fprintf(stderr, "%s(%u): _assert(%s); errno=%u\n", __FILE__, __LINE__, #expr, errno); \
-        _assert_(#expr); \
+        fprintf(stderr, "%s(%u): _assert(): " format "\n", __FILE__, __LINE__, ## __VA_ARGS__); \
+        throw __FILE__ "(" _assert__(__LINE__) "): _assert(" #expr ")"; \
     } while (false)
 
+#define _assert(expr) \
+    _assert_(expr, "%s", #expr)
+
 #define _syscall(expr) ({ \
     __typeof__(expr) _value; \
     do if ((long) (_value = (expr)) != -1) \
@@ -68,7 +69,7 @@
         case EINTR: \
             continue; \
         default: \
-            _assert(false); \
+            _assert_(false, "errno=%u", errno); \
     } while (true); \
     _value; \
 })
@@ -841,7 +842,7 @@ class File {
 
     void open(const char *path, int flags) {
         _assert(file_ == -1);
-        _syscall(file_ = ::open(path, flags));
+        file_ = _syscall(::open(path, flags));
     }
 
     int file() const {
@@ -870,13 +871,13 @@ class Map {
     {
     }
 
-    Map(const char *path, int oflag, int pflag, int mflag) :
+    Map(const std::string &path, int oflag, int pflag, int mflag) :
         Map()
     {
         open(path, oflag, pflag, mflag);
     }
 
-    Map(const char *path, bool edit) :
+    Map(const std::string &path, bool edit) :
         Map()
     {
         open(path, edit);
@@ -890,20 +891,20 @@ class Map {
         return data_ == NULL;
     }
 
-    void open(const char *path, int oflag, int pflag, int mflag) {
+    void open(const std::string &path, int oflag, int pflag, int mflag) {
         clear();
 
-        file_.open(path, oflag);
+        file_.open(path.c_str(), oflag);
         int file(file_.file());
 
         struct stat stat;
         _syscall(fstat(file, &stat));
         size_ = stat.st_size;
 
-        _syscall(data_ = mmap(NULL, size_, pflag, mflag, file, 0));
+        data_ = _syscall(mmap(NULL, size_, pflag, mflag, file, 0));
     }
 
-    void open(const char *path, bool edit) {
+    void open(const std::string &path, bool edit) {
         if (edit)
             open(path, O_RDWR, PROT_READ | PROT_WRITE, MAP_SHARED);
         else
@@ -925,8 +926,8 @@ class Map {
 
 namespace ldid {
 
-static void Allocate(void *idata, size_t isize, std::streambuf &output, const Functor<size_t (size_t)> &allocate, const Functor<size_t (std::streambuf &output, size_t, const std::string &, const char *)> &save) {
-    FatHeader source(idata, isize);
+static void Allocate(const void *idata, size_t isize, std::streambuf &output, const Functor<size_t (size_t)> &allocate, const Functor<size_t (std::streambuf &output, size_t, const std::string &, const char *)> &save) {
+    FatHeader source(const_cast<void *>(idata), isize);
 
     size_t offset(0);
     if (source.IsFat())
@@ -1258,9 +1259,20 @@ class Signature {
     }
 };
 
+static void Commit(const std::string &path, const std::string &temp) {
+    struct stat info;
+    _syscall(stat(path.c_str(), &info));
+#ifndef __WIN32__
+    _syscall(chown(temp.c_str(), info.st_uid, info.st_gid));
+#endif
+    _syscall(chmod(temp.c_str(), info.st_mode));
+    _syscall(unlink(path.c_str()));
+    _syscall(rename(temp.c_str(), path.c_str()));
+}
+
 namespace ldid {
 
-void Sign(void *idata, size_t isize, std::streambuf &output, const std::string &name, const std::string &entitlements, const std::string &key, const Slots &slots) {
+void Sign(const void *idata, size_t isize, std::streambuf &output, const std::string &identifier, const std::string &entitlements, const std::string &key, const Slots &slots) {
     Allocate(idata, isize, output, fun([&](size_t size) -> size_t {
         size_t alloc(sizeof(struct SuperBlob));
 
@@ -1281,7 +1293,7 @@ void Sign(void *idata, size_t isize, std::streambuf &output, const std::string &
         alloc += sizeof(struct BlobIndex);
         alloc += sizeof(struct Blob);
         alloc += sizeof(struct CodeDirectory);
-        alloc += name.size() + 1;
+        alloc += identifier.size() + 1;
 
         if (!key.empty()) {
             alloc += sizeof(struct BlobIndex);
@@ -1327,7 +1339,7 @@ void Sign(void *idata, size_t isize, std::streambuf &output, const std::string &
             CodeDirectory directory;
             directory.version = Swap(uint32_t(0x00020001));
             directory.flags = Swap(uint32_t(0));
-            directory.hashOffset = Swap(uint32_t(sizeof(Blob) + sizeof(CodeDirectory) + name.size() + 1 + SHA_DIGEST_LENGTH * special));
+            directory.hashOffset = Swap(uint32_t(sizeof(Blob) + sizeof(CodeDirectory) + identifier.size() + 1 + SHA_DIGEST_LENGTH * special));
             directory.identOffset = Swap(uint32_t(sizeof(Blob) + sizeof(CodeDirectory)));
             directory.nSpecialSlots = Swap(special);
             directory.codeLimit = Swap(uint32_t(limit));
@@ -1339,7 +1351,7 @@ void Sign(void *idata, size_t isize, std::streambuf &output, const std::string &
             directory.spare2 = Swap(uint32_t(0));
             put(data, &directory, sizeof(directory));
 
-            put(data, name.c_str(), name.size() + 1);
+            put(data, identifier.c_str(), identifier.size() + 1);
 
             uint8_t storage[special + normal][SHA_DIGEST_LENGTH];
             uint8_t (*hashes)[SHA_DIGEST_LENGTH] = storage + special;
@@ -1534,18 +1546,21 @@ int main(int argc, char *argv[]) {
 
     size_t filei(0), filee(0);
     _foreach (file, files) try {
-        const char *path(file.c_str());
+        std::string path(file);
 
         if (flag_S || flag_r) {
             Map input(path, O_RDONLY, PROT_READ, MAP_PRIVATE);
 
             std::string dir;
-            const char *base = strrchr(path, '/');
+            std::string base;
 
-            if (base != NULL)
-                dir.assign(path, base++ - path + 1);
-            else
+            size_t slash(path.rfind('/'));
+            if (slash == std::string::npos)
                 base = path;
+            else {
+                dir = path.substr(0, slash + 1);
+                base = path.substr(slash + 1);
+            }
 
             std::string temp(dir + "." + base + ".cs");
             std::filebuf output;
@@ -1554,18 +1569,11 @@ int main(int argc, char *argv[]) {
             if (flag_r)
                 ldid::Unsign(input.data(), input.size(), output);
             else {
-                const char *name(flag_I ?: base);
-                ldid::Sign(input.data(), input.size(), output, name, entitlements, key, slots);
+                std::string identifier(flag_I ?: base.c_str());
+                ldid::Sign(input.data(), input.size(), output, identifier, entitlements, key, slots);
             }
 
-            struct stat info;
-            _syscall(stat(path, &info));
-#ifndef __WIN32__
-            _syscall(chown(temp.c_str(), info.st_uid, info.st_gid));
-#endif
-            _syscall(chmod(temp.c_str(), info.st_mode));
-            _syscall(unlink(path));
-            _syscall(rename(temp.c_str(), path));
+            Commit(path, temp);
         }
 
         Map mapping(path, flag_T || flag_s);