namespace libdcp -> dcp.
[libdcp.git] / src / signer_chain.cc
index ba9ef33522cef27aa2ab8b9ec2151f74c9ab164a..5f9941f973493533bb61fbac56a422ead00c6508 100644 (file)
@@ -37,16 +37,46 @@ using std::cout;
 
 static void command (string cmd)
 {
-       int const r = system (cmd.c_str ());
-#ifdef LIBDCP_WINDOWS  
-       int const code = r;
+#ifdef LIBDCP_WINDOWS
+       /* We need to use CreateProcessW on Windows so that the UTF-8/16 mess
+          is handled correctly.
+       */
+       int const wn = MultiByteToWideChar (CP_UTF8, 0, cmd.c_str(), -1, 0, 0);
+       wchar_t* buffer = new wchar_t[wn];
+       if (MultiByteToWideChar (CP_UTF8, 0, cmd.c_str(), -1, buffer, wn) == 0) {
+               delete[] buffer;
+               return;
+       }
+
+       int code = 1;
+
+       STARTUPINFOW startup_info;
+       memset (&startup_info, 0, sizeof (startup_info));
+       startup_info.cb = sizeof (startup_info);
+       PROCESS_INFORMATION process_info;
+
+       /* XXX: this doesn't actually seem to work; failing commands end up with
+          a return code of 0
+       */
+       if (CreateProcessW (0, buffer, 0, 0, FALSE, CREATE_NO_WINDOW, 0, 0, &startup_info, &process_info)) {
+               WaitForSingleObject (process_info.hProcess, INFINITE);
+               DWORD c;
+               if (GetExitCodeProcess (process_info.hProcess, &c)) {
+                       code = c;
+               }
+               CloseHandle (process_info.hProcess);
+               CloseHandle (process_info.hThread);
+       }
+
+       delete[] buffer;
 #else
+       int const r = system (cmd.c_str ());
        int const code = WEXITSTATUS (r);
 #endif
        if (code) {
                stringstream s;
                s << "error " << code << " in " << cmd << " within " << boost::filesystem::current_path();
-               throw libdcp::MiscError (s.str());
+               throw dcp::MiscError (s.str());
        }
 }
 
@@ -60,19 +90,22 @@ static string
 public_key_digest (boost::filesystem::path private_key, boost::filesystem::path openssl)
 {
        boost::filesystem::path public_name = private_key.string() + ".public";
-       
+
        /* Create the public key from the private key */
        stringstream s;
-       s << "\"" << openssl.string() << "\" rsa -outform PEM -pubout -in " << private_key.string() << " > " << public_name.string ();
+       s << "\"" << openssl.string() << "\" rsa -outform PEM -pubout -in " << private_key.string() << " -out " << public_name.string ();
        command (s.str().c_str ());
 
        /* Read in the public key from the file */
 
        string pub;
        ifstream f (public_name.string().c_str ());
+       if (!f.good ()) {
+               throw dcp::MiscError ("public key not found");
+       }
 
        bool read = false;
-       while (1) {
+       while (f.good ()) {
                string line;
                getline (f, line);
                if (line.length() >= 10 && line.substr(0, 10) == "-----BEGIN") {
@@ -87,22 +120,22 @@ public_key_digest (boost::filesystem::path private_key, boost::filesystem::path
        /* Decode the base64 of the public key */
                
        unsigned char buffer[512];
-       int const N = libdcp::base64_decode (pub, buffer, 1024);
+       int const N = dcp::base64_decode (pub, buffer, 1024);
 
        /* Hash it with SHA1 (without the first 24 bytes, for reasons that are not entirely clear) */
 
        SHA_CTX context;
        if (!SHA1_Init (&context)) {
-               throw libdcp::MiscError ("could not init SHA1 context");
+               throw dcp::MiscError ("could not init SHA1 context");
        }
 
        if (!SHA1_Update (&context, buffer + 24, N - 24)) {
-               throw libdcp::MiscError ("could not update SHA1 digest");
+               throw dcp::MiscError ("could not update SHA1 digest");
        }
 
        unsigned char digest[SHA_DIGEST_LENGTH];
        if (!SHA1_Final (digest, &context)) {
-               throw libdcp::MiscError ("could not finish SHA1 digest");
+               throw dcp::MiscError ("could not finish SHA1 digest");
        }
 
        char digest_base64[64];
@@ -116,7 +149,7 @@ public_key_digest (boost::filesystem::path private_key, boost::filesystem::path
 }
 
 void
-libdcp::make_signer_chain (boost::filesystem::path directory, boost::filesystem::path openssl)
+dcp::make_signer_chain (boost::filesystem::path directory, boost::filesystem::path openssl)
 {
        boost::filesystem::path const cwd = boost::filesystem::current_path ();