예제 #1
0
파일: dvd.c 프로젝트: anarexia/bacula
/* 
 * Mount a DVD device, then scan to find out how many parts
 *  there are.
 */
int find_num_dvd_parts(DCR *dcr)
{
   DEVICE *dev = dcr->dev;
   int num_parts = 0;

   if (!dev->is_dvd()) {
      return 0;
   }
   
   if (dev->mount(1)) {
      DIR* dp;
      struct dirent *entry, *result;
      int name_max;
      int len = strlen(dcr->getVolCatName());

      /* Now count the number of parts */
      name_max = pathconf(".", _PC_NAME_MAX);
      if (name_max < 1024) {
         name_max = 1024;
      }
         
      if (!(dp = opendir(dev->device->mount_point))) {
         berrno be;
         dev->dev_errno = errno;
         Dmsg3(29, "find_num_dvd_parts: failed to open dir %s (dev=%s), ERR=%s\n", 
               dev->device->mount_point, dev->print_name(), be.bstrerror());
         goto get_out;
      }
      
      entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);

      Dmsg1(100, "Looking for Vol=%s\n", dcr->getVolCatName());
      for ( ;; ) {
         int flen;
         bool ignore;
         if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
            dev->dev_errno = EIO;
            Dmsg2(129, "find_num_dvd_parts: failed to find suitable file in dir %s (dev=%s)\n", 
                  dev->device->mount_point, dev->print_name());
            break;
         }
         flen = strlen(result->d_name);
         ignore = true;
         if (flen >= len) {
            result->d_name[len] = 0;
            if (strcmp(dcr->getVolCatName(), result->d_name) == 0) {
               num_parts++;
               Dmsg1(100, "find_num_dvd_parts: found part: %s\n", result->d_name);
               ignore = false;
            }
         }
         if (ignore) {
            Dmsg2(129, "find_num_dvd_parts: ignoring %s in %s\n", 
                  result->d_name, dev->device->mount_point);
         }
      }
      free(entry);
      closedir(dp);
      Dmsg1(29, "find_num_dvd_parts = %d\n", num_parts);
   }
   
get_out:
   dev->set_freespace_ok();
   if (dev->is_mounted()) {
      dev->unmount(0);
   }
   return num_parts;
}
예제 #2
0
파일: dvd.c 프로젝트: anarexia/bacula
bool truncate_dvd(DCR *dcr) 
{
   DEVICE* dev = dcr->dev;

   dev->clear_freespace_ok();             /* need to update freespace */
   dev->close_part(dcr);

   if (!dev->unmount(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, true)) {
      return false;
   }
   
   return true;
}