+void dvd_remove_empty_part(DCR *dcr)
+{
+ DEVICE *dev = dcr->dev;
+
+ /* Remove the last part file if it is empty */
+ if (dev->is_dvd() && dev->num_dvd_parts > 0) {
+ struct stat statp;
+ uint32_t part_save = dev->part;
+ POOL_MEM archive_name(PM_FNAME);
+ int status;
+
+ dev->part = dev->num_dvd_parts;
+ make_spooled_dvd_filename(dev, archive_name);
+ /* Check that the part file is empty */
+ status = stat(archive_name.c_str(), &statp);
+ if (status == 0 && statp.st_size == 0) {
+ Dmsg3(100, "Unlink empty part in close call make_dvd_filename. part=%d num=%d vol=%s\n",
+ part_save, dev->num_dvd_parts, dev->VolCatInfo.VolCatName);
+ Dmsg1(100, "unlink(%s)\n", archive_name.c_str());
+ unlink(archive_name.c_str());
+ if (part_save == dev->part) {
+ dev->set_part_spooled(false); /* no spooled part left */
+ }
+ } else if (status < 0) {
+ if (part_save == dev->part) {
+ dev->set_part_spooled(false); /* spool doesn't exit */
+ }
+ }
+ dev->part = part_save; /* restore part number */
+ }
+}
+
+bool truncate_dvd(DCR *dcr)
+{
+ DEVICE* dev = dcr->dev;
+
+ dev->clear_freespace_ok(); /* need to update freespace */
+ dev->close_part(dcr);
+
+ if (!unmount_dvd(dev, 1)) {
+ Dmsg0(400, "truncate_dvd: Failed to unmount DVD\n");
+ return false;
+ }
+
+ /* If necessary, delete its spool file. */
+ if (dev->is_part_spooled()) {
+ POOL_MEM archive_name(PM_FNAME);
+ /* Delete spool file */
+ make_spooled_dvd_filename(dev, archive_name);
+ unlink(archive_name.c_str());
+ dev->set_part_spooled(false);
+ }
+
+ /* Set num_dvd_parts to zero (on disk) */
+ dev->part = 0;
+ dev->num_dvd_parts = 0;
+ dcr->VolCatInfo.VolCatParts = 0;
+ dev->VolCatInfo.VolCatParts = 0;
+
+ Dmsg0(400, "truncate_dvd: Opening first part (1)...\n");
+
+ dev->truncating = true;
+ /* This creates a zero length spool file and sets part=1 */
+ if (!dvd_open_first_part(dcr, CREATE_READ_WRITE)) {
+ Dmsg0(400, "truncate_dvd: Error while opening first part (1).\n");
+ dev->truncating = false;
+ return false;
+ }
+
+ dev->close_part(dcr);
+
+ Dmsg0(400, "truncate_dvd: Opening first part (2)...\n");
+
+ /*
+ * Now actually truncate the DVD which is done by writing
+ * a zero length part to the DVD/
+ */
+ if (!dvd_write_part(dcr)) {
+ Dmsg0(400, "truncate_dvd: Error while writing to DVD.\n");
+ dev->truncating = false;
+ return false;
+ }
+ dev->truncating = false;
+
+ /* Set num_dvd_parts to zero (on disk) */
+ dev->part = 0;
+ dev->num_dvd_parts = 0;
+ dcr->VolCatInfo.VolCatParts = 0;
+ dev->VolCatInfo.VolCatParts = 0;
+ /* Clear the size of the volume */
+ dev->VolCatInfo.VolCatBytes = 0;
+ dcr->VolCatInfo.VolCatBytes = 0;
+
+ /* Update catalog */
+ if (!dir_update_volume_info(dcr, false)) {
+ return false;
+ }
+
+ return true;
+}