Supporters update.
[dcpomatic.git] / src / tools / dcpomatic_disk_writer.cc
index dca09f729ad0ee37bbd4e12906ceac98d4fe146a..3bb6fcd3ffe78780484a5af80d46bfd6134d5c91 100644 (file)
@@ -164,7 +164,7 @@ try
        if (*s == DISK_WRITER_QUIT) {
                exit (EXIT_SUCCESS);
        } else if (*s == DISK_WRITER_PING) {
-               nanomsg->send(DISK_WRITER_PONG "\n", LONG_TIMEOUT);
+               DiskWriterBackEndResponse::pong().write_to_nanomsg(*nanomsg, LONG_TIMEOUT);
        } else if (*s == DISK_WRITER_UNMOUNT) {
                auto xml_head = nanomsg->receive (LONG_TIMEOUT);
                auto xml_body = nanomsg->receive (LONG_TIMEOUT);
@@ -179,9 +179,9 @@ try
                                bool const success = Drive(xml).unmount();
                                bool sent_reply = false;
                                if (success) {
-                                       sent_reply = nanomsg->send(DISK_WRITER_OK "\n", LONG_TIMEOUT);
+                                       sent_reply = DiskWriterBackEndResponse::ok().write_to_nanomsg(*nanomsg, LONG_TIMEOUT);
                                } else {
-                                       sent_reply = nanomsg->send(DISK_WRITER_ERROR "\nCould not unmount drive\n1\n", LONG_TIMEOUT);
+                                       sent_reply = DiskWriterBackEndResponse::error("Could not unmount drive", 1, 0).write_to_nanomsg(*nanomsg, LONG_TIMEOUT);
                                }
                                if (!sent_reply) {
                                        LOG_DISK_NC("CommunicationFailedError in unmount_finished");
@@ -189,42 +189,53 @@ try
                                }
                        },
                        []() {
-                               if (!nanomsg->send(DISK_WRITER_ERROR "\nCould not get permission to unmount drive\n1\n", LONG_TIMEOUT)) {
+                               if (!DiskWriterBackEndResponse::error("Could not get permission to unmount drive", 1, 0).write_to_nanomsg(*nanomsg, 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
                if (!starts_with(device, "/dev/disk")) {
                        LOG_DISK ("Will not write to %1", device);
-                       nanomsg->send(DISK_WRITER_ERROR "\nRefusing to write to this drive\n1\n", LONG_TIMEOUT);
+                       DiskWriterBackEndResponse::error("Refusing to write to this drive", 1, 0).write_to_nanomsg(*nanomsg, LONG_TIMEOUT);
                        return true;
                }
 #endif
 #ifdef DCPOMATIC_LINUX
                if (!starts_with(device, "/dev/sd") && !starts_with(device, "/dev/hd")) {
                        LOG_DISK ("Will not write to %1", device);
-                       nanomsg->send(DISK_WRITER_ERROR "\nRefusing to write to this drive\n1\n", LONG_TIMEOUT);
+                       DiskWriterBackEndResponse::error("Refusing to write to this drive", 1, 0).write_to_nanomsg(*nanomsg, LONG_TIMEOUT);
                        return true;
                }
 #endif
 #ifdef DCPOMATIC_WINDOWS
                if (!starts_with(device, "\\\\.\\PHYSICALDRIVE")) {
                        LOG_DISK ("Will not write to %1", device);
-                       nanomsg->send(DISK_WRITER_ERROR "\nRefusing to write to this drive\n1\n", LONG_TIMEOUT);
+                       DiskWriterBackEndResponse::error("Refusing to write to this drive", 1, 0).write_to_nanomsg(*nanomsg, LONG_TIMEOUT);
                        return true;
                }
 #endif
@@ -240,20 +251,23 @@ try
 
                if (!on_drive_list) {
                        LOG_DISK ("Will not write to %1 as it's not recognised as a drive", device);
-                       nanomsg->send(DISK_WRITER_ERROR "\nRefusing to write to this drive\n1\n", LONG_TIMEOUT);
+                       DiskWriterBackEndResponse::error("Refusing to write to this drive", 1, 0).write_to_nanomsg(*nanomsg, LONG_TIMEOUT);
                        return true;
                }
                if (mounted) {
                        LOG_DISK ("Will not write to %1 as it's mounted", device);
-                       nanomsg->send(DISK_WRITER_ERROR "\nRefusing to write to this drive\n1\n", LONG_TIMEOUT);
+                       DiskWriterBackEndResponse::error("Refusing to write to this drive", 1, 0).write_to_nanomsg(*nanomsg, LONG_TIMEOUT);
                        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 */
@@ -262,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\n1\n", LONG_TIMEOUT);
+                                       DiskWriterBackEndResponse::error("Could not obtain authorization to write to the drive", 1, 0).write_to_nanomsg(*nanomsg, LONG_TIMEOUT);
                                }
                        });
        }
@@ -286,6 +300,8 @@ try
 int
 main ()
 {
+       dcpomatic_setup_path_encoding();
+
 #ifdef DCPOMATIC_OSX
        /* On macOS this is running as root, so config_path() will be somewhere in root's
         * home.  Instead, just write to stdout as the macOS process control stuff will