Add some logging to the KDM creator.
[dcpomatic.git] / src / tools / dcpomatic_disk_writer.cc
index 7ed64d52c7a308285d201e72dc5149076fe71ea2..ef3bf2f776c86936b6ad443e26b3d717eca1d26b 100644 (file)
 #include "lib/exceptions.h"
 #include "lib/ext.h"
 #include "lib/file_log.h"
+#include "lib/state.h"
 #include "lib/nanomsg.h"
+#include "lib/util.h"
 #include "lib/version.h"
-#include "lib/warnings.h"
+#include <dcp/warnings.h>
 
 #ifdef DCPOMATIC_POSIX
 #include <sys/ioctl.h>
@@ -43,6 +45,7 @@
 extern "C" {
 #include <lwext4/file_dev.h>
 }
+#include <unistd.h>
 #include <xpc/xpc.h>
 #endif
 
@@ -57,9 +60,9 @@ extern "C" {
 }
 #endif
 
-DCPOMATIC_DISABLE_WARNINGS
+LIBDCP_DISABLE_WARNINGS
 #include <glibmm.h>
-DCPOMATIC_ENABLE_WARNINGS
+LIBDCP_ENABLE_WARNINGS
 
 #include <unistd.h>
 #include <sys/types.h>
@@ -174,28 +177,45 @@ try
                        "com.dcpomatic.write-drive",
                        [xml]() {
                                bool const success = Drive(xml).unmount();
-                               if (!nanomsg->send(success ? (DISK_WRITER_OK "\n") : (DISK_WRITER_ERROR "\n"), LONG_TIMEOUT)) {
+                               bool sent_reply = false;
+                               if (success) {
+                                       sent_reply = nanomsg->send(DISK_WRITER_OK "\n", LONG_TIMEOUT);
+                               } else {
+                                       sent_reply = nanomsg->send(DISK_WRITER_ERROR "\nCould not unmount drive\n1\n", LONG_TIMEOUT);
+                               }
+                               if (!sent_reply) {
                                        LOG_DISK_NC("CommunicationFailedError in unmount_finished");
                                        throw CommunicationFailedError ();
                                }
                        },
                        []() {
-                               if (!nanomsg->send(DISK_WRITER_ERROR "\n", LONG_TIMEOUT)) {
+                               if (!nanomsg->send(DISK_WRITER_ERROR "\nCould not get permission to unmount drive\n1\n", LONG_TIMEOUT)) {
                                        LOG_DISK_NC("CommunicationFailedError in unmount_finished");
                                        throw CommunicationFailedError ();
                                }
                        });
        } else if (*s == DISK_WRITER_WRITE) {
-               auto dcp_path_opt = nanomsg->receive (LONG_TIMEOUT);
                auto device_opt = nanomsg->receive (LONG_TIMEOUT);
-               if (!dcp_path_opt || !device_opt) {
+               if (!device_opt) {
                        LOG_DISK_NC("Failed to receive write request");
                        throw CommunicationFailedError();
                }
-
-               auto dcp_path = *dcp_path_opt;
                auto device = *device_opt;
 
+               vector<boost::filesystem::path> dcp_paths;
+               while (true) {
+                       auto dcp_path_opt = nanomsg->receive (LONG_TIMEOUT);
+                       if (!dcp_path_opt) {
+                               LOG_DISK_NC("Failed to receive write request");
+                               throw CommunicationFailedError();
+                       }
+                       if (*dcp_path_opt != "") {
+                               dcp_paths.push_back(*dcp_path_opt);
+                       } else {
+                               break;
+                       }
+               }
+
                /* Do some basic sanity checks; this is a bit belt-and-braces but it can't hurt... */
 
 #ifdef DCPOMATIC_OSX
@@ -240,11 +260,14 @@ try
                        return true;
                }
 
-               LOG_DISK ("Here we go writing %1 to %2", dcp_path, device);
+               LOG_DISK("Here we go writing these to %1", device);
+               for (auto dcp: dcp_paths) {
+                       LOG_DISK("  %1", dcp);
+               }
 
                request_privileges (
                        "com.dcpomatic.write-drive",
-                       [dcp_path, device]() {
+                       [dcp_paths, device]() {
 #if defined(DCPOMATIC_LINUX)
                                auto posix_partition = device;
                                /* XXX: don't know if this logic is sensible */
@@ -253,17 +276,17 @@ try
                                } else {
                                        posix_partition += "1";
                                }
-                               dcpomatic::write (dcp_path, device, posix_partition, nanomsg);
+                               dcpomatic::write (dcp_paths, device, posix_partition, nanomsg);
 #elif defined(DCPOMATIC_OSX)
                                auto fast_device = boost::algorithm::replace_first_copy (device, "/dev/disk", "/dev/rdisk");
-                               dcpomatic::write (dcp_path, fast_device, fast_device + "s1", nanomsg);
+                               dcpomatic::write (dcp_paths, fast_device, fast_device + "s1", nanomsg);
 #elif defined(DCPOMATIC_WINDOWS)
-                               dcpomatic::write (dcp_path, device, "", nanomsg);
+                               dcpomatic::write (dcp_paths, device, "", nanomsg);
 #endif
                        },
                        []() {
                                if (nanomsg) {
-                                       nanomsg->send(DISK_WRITER_ERROR "\nCould not obtain authorization to write to the drive\n", LONG_TIMEOUT);
+                                       nanomsg->send(DISK_WRITER_ERROR "\nCould not obtain authorization to write to the drive\n1\n", LONG_TIMEOUT);
                                }
                        });
        }
@@ -283,12 +306,12 @@ main ()
         * redirect this to a file in /var/log
         */
        dcpomatic_log.reset(new StdoutLog(LogEntry::TYPE_DISK));
-       LOG_DISK("dcpomatic_disk_writer %1 started", dcpomatic_git_commit);
+       LOG_DISK("dcpomatic_disk_writer %1 started uid=%2 euid=%3", dcpomatic_git_commit, getuid(), geteuid());
 #else
        /* XXX: this is a hack, but I expect we'll need logs and I'm not sure if there's
         * a better place to put them.
         */
-       dcpomatic_log.reset(new FileLog(config_path() / "disk_writer.log", LogEntry::TYPE_DISK));
+       dcpomatic_log.reset(new FileLog(State::write_path("disk_writer.log"), LogEntry::TYPE_DISK));
        LOG_DISK_NC("dcpomatic_disk_writer started");
 #endif
 
@@ -306,6 +329,7 @@ main ()
                exit (EXIT_FAILURE);
        }
 
+       LOG_DISK_NC("Entering main loop");
        auto ml = Glib::MainLoop::create ();
        Glib::signal_timeout().connect(sigc::ptr_fun(&idle), 500);
        ml->run ();