src/stored/ansi_label.c
int read_ansi_ibm_label(DCR *dcr)
{
   DEVICE * volatile dev = dcr->dev;
   JCR *jcr = dcr->jcr;
   char label[80];                    /* tape label */
   int stat, i;
   char *VolName = dcr->VolumeName;
   bool ok = false;

   /*
    * Read VOL1, HDR1, HDR2 labels, but ignore the data
    *  If tape read the following EOF mark, on disk do
    *  not read.
    */
   Dmsg0(100, "Read ansi label.\n");
   if (!dev->is_tape()) {
      return VOL_OK;
   }

   dev->label_type = B_BACULA_LABEL;  /* assume Bacula label */

   /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */
   for (i=0; i < 6; i++) {
      do {
         stat = dev->read(label, sizeof(label));
      } while (stat == -1 && errno == EINTR);
      if (stat < 0) {
         berrno be;
         dev->clrerror(-1);
         Dmsg1(100, "Read device got: ERR=%s\n", be.bstrerror());
         Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
            dev->dev_name, be.bstrerror());
         Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
         dev->VolCatInfo.VolCatErrors++;
         return VOL_IO_ERROR;
      }
      if (stat == 0) {
         if (dev->at_eof()) {
            dev->set_eot();           /* second eof, set eot bit */
            Dmsg0(100, "EOM on ANSI label\n");
            Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n"));
            return VOL_LABEL_ERROR;   /* at EOM this shouldn't happen */
         } else {
            dev->set_ateof();        /* set eof state */
         }
      }
      switch (i) {
      case 0:                         /* Want VOL1 label */
         if (stat == 80) {
            if (strncmp("VOL1", label, 4) == 0) {
               ok = true;
               dev->label_type = B_ANSI_LABEL;
               Dmsg0(100, "Got ANSI VOL1 label\n");
            } else {
               /* Try EBCDIC */
               ebcdic_to_ascii(label, label, sizeof(label));
               if (strncmp("VOL1", label, 4) == 0) {
                  ok = true;;
                  dev->label_type = B_IBM_LABEL;
                  Dmsg0(100, "Found IBM label.\n");
                  Dmsg0(100, "Got IBM VOL1 label\n");
               }
            }
         }
         if (!ok) {
            Dmsg0(100, "No VOL1 label\n");
            Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
            return VOL_NO_LABEL;   /* No ANSI label */
         }


         /* Compare Volume Names allow special wild card */
         if (VolName && *VolName && *VolName != '*') {
            if (!same_label_names(VolName, &label[4])) {
               char *p = &label[4];
               char *q;

               free_volume(dev);
               /* Store new Volume name */
               q = dev->VolHdr.VolumeName;
               for (int i=0; *p != ' ' && i < 6; i++) {
                  *q++ = *p++;
               }
               *q = 0;
               Dmsg0(100, "Call reserve_volume\n");
               /* ***FIXME***  why is this reserve_volume() needed???? KES */
               reserve_volume(dcr, dev->VolHdr.VolumeName);
               dev = dcr->dev;            /* may have changed in reserve_volume */
               Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
               Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName);
               return VOL_NAME_ERROR;
            }
         }
         break;
      case 1:
         if (dev->label_type == B_IBM_LABEL) {
            ebcdic_to_ascii(label, label, sizeof(label));
         }
         if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
            Dmsg0(100, "No HDR1 label\n");
            Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
            return VOL_LABEL_ERROR;
         }
         if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
            Dmsg1(100, "HD1 not Bacula label. Wanted  BACULA.DATA got %11s\n",
               &label[4]);
            Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
               dev->VolHdr.VolumeName);
            return VOL_NAME_ERROR;     /* Not a Bacula label */
         }
         Dmsg0(100, "Got HDR1 label\n");
         break;
      case 2:
         if (dev->label_type == B_IBM_LABEL) {
            ebcdic_to_ascii(label, label, sizeof(label));
         }
         if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
            Dmsg0(100, "No HDR2 label\n");
            Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
            return VOL_LABEL_ERROR;
         }
         Dmsg0(100, "Got ANSI HDR2 label\n");
         break;
      default:
         if (stat == 0) {
            Dmsg0(100, "ANSI label OK\n");
            return VOL_OK;
         }
         if (dev->label_type == B_IBM_LABEL) {
            ebcdic_to_ascii(label, label, sizeof(label));
         }
         if (stat != 80 || strncmp("HDR", label, 3) != 0) {
            Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
            Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
            return VOL_LABEL_ERROR;
         }
         Dmsg0(100, "Got HDR label\n");
         break;
      }
   }
   Dmsg0(100, "Too many records in ANSI/IBM label.\n");
   Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
   return VOL_LABEL_ERROR;
}
/*
 * We read an ANSI label and compare the Volume name. We require
 * a VOL1 record of 80 characters followed by a HDR1 record containing
 * BACULA.DATA in the filename field. We then read up to 3 more
 * header records (they are not required) and an EOF, at which
 * point, all is good.
 *
 * Returns:
 *    VOL_OK            Volume name OK
 *    VOL_NO_LABEL      No ANSI label on Volume
 *    VOL_IO_ERROR      I/O error on read
 *    VOL_NAME_ERROR    Wrong name in VOL1 record
 *    VOL_LABEL_ERROR   Probably an ANSI label, but something wrong
 *
 */
We read an ANSI label and compare the Volume name. We require
a VOL1 record of 80 characters followed by a HDR1 record containing
BACULA.DATA in the filename field. We then read up to 3 more
header records (they are not required) and an EOF, at which
point, all is good.

VOL_OK            Volume name OK
VOL_NO_LABEL      No ANSI label on Volume
VOL_IO_ERROR      I/O error on read
VOL_NAME_ERROR    Wrong name in VOL1 record
VOL_LABEL_ERROR   Probably an ANSI label, but something wrong
We read an ANSI label and compare the Volume name . We require a VOL1 record of 80 characters followed by a HDR1 record containing BACULA . DATA in the filename field . We then read up to 3 more header records ( they are not required ) and an EOF at which point all is good . VOL_OK Volume name OK VOL_NO_LABEL No ANSI label on Volume VOL_IO_ERROR I / O error on read VOL_NAME_ERROR Wrong name in VOL1 record VOL_LABEL_ERROR Probably an ANSI label but something wrong
int read_ansi_ibm_label(DCR *dcr)
{
   DEVICE * volatile dev = dcr->dev;
   JCR *jcr = dcr->jcr;
   char label[80];                    
   int stat, i;
   char *VolName = dcr->VolumeName;
   bool ok = false;
   Dmsg0(100, "Read ansi label.\n");
   if (!dev->is_tape()) {
      return VOL_OK;
   }
   dev->label_type = B_BACULA_LABEL;  
   for (i=0; i < 6; i++) {
      do {
         stat = dev->read(label, sizeof(label));
      } while (stat == -1 && errno == EINTR);
      if (stat < 0) {
         berrno be;
         dev->clrerror(-1);
         Dmsg1(100, "Read device got: ERR=%s\n", be.bstrerror());
         Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
            dev->dev_name, be.bstrerror());
         Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
         dev->VolCatInfo.VolCatErrors++;
         return VOL_IO_ERROR;
      }
      if (stat == 0) {
         if (dev->at_eof()) {
            dev->set_eot();           
            Dmsg0(100, "EOM on ANSI label\n");
            Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n"));
            return VOL_LABEL_ERROR;   
         } else {
            dev->set_ateof();        
         }
      }
      switch (i) {
      case 0:                         
         if (stat == 80) {
            if (strncmp("VOL1", label, 4) == 0) {
               ok = true;
               dev->label_type = B_ANSI_LABEL;
               Dmsg0(100, "Got ANSI VOL1 label\n");
            } else {
               ebcdic_to_ascii(label, label, sizeof(label));
               if (strncmp("VOL1", label, 4) == 0) {
                  ok = true;;
                  dev->label_type = B_IBM_LABEL;
                  Dmsg0(100, "Found IBM label.\n");
                  Dmsg0(100, "Got IBM VOL1 label\n");
               }
            }
         }
         if (!ok) {
            Dmsg0(100, "No VOL1 label\n");
            Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
            return VOL_NO_LABEL;   
         }
         if (VolName && *VolName && *VolName != '*') {
            if (!same_label_names(VolName, &label[4])) {
               char *p = &label[4];
               char *q;
               free_volume(dev);
               q = dev->VolHdr.VolumeName;
               for (int i=0; *p != ' ' && i < 6; i++) {
                  *q++ = *p++;
               }
               *q = 0;
               Dmsg0(100, "Call reserve_volume\n");
               reserve_volume(dcr, dev->VolHdr.VolumeName);
               dev = dcr->dev;            
               Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
               Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName);
               return VOL_NAME_ERROR;
            }
         }
         break;
      case 1:
         if (dev->label_type == B_IBM_LABEL) {
            ebcdic_to_ascii(label, label, sizeof(label));
         }
         if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
            Dmsg0(100, "No HDR1 label\n");
            Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
            return VOL_LABEL_ERROR;
         }
         if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
            Dmsg1(100, "HD1 not Bacula label. Wanted  BACULA.DATA got %11s\n",
               &label[4]);
            Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
               dev->VolHdr.VolumeName);
            return VOL_NAME_ERROR;     
         }
         Dmsg0(100, "Got HDR1 label\n");
         break;
      case 2:
         if (dev->label_type == B_IBM_LABEL) {
            ebcdic_to_ascii(label, label, sizeof(label));
         }
         if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
            Dmsg0(100, "No HDR2 label\n");
            Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
            return VOL_LABEL_ERROR;
         }
         Dmsg0(100, "Got ANSI HDR2 label\n");
         break;
      default:
         if (stat == 0) {
            Dmsg0(100, "ANSI label OK\n");
            return VOL_OK;
         }
         if (dev->label_type == B_IBM_LABEL) {
            ebcdic_to_ascii(label, label, sizeof(label));
         }
         if (stat != 80 || strncmp("HDR", label, 3) != 0) {
            Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
            Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
            return VOL_LABEL_ERROR;
         }
         Dmsg0(100, "Got HDR label\n");
         break;
      }
   }
   Dmsg0(100, "Too many records in ANSI/IBM label.\n");
   Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
   return VOL_LABEL_ERROR;
}
int read_ansi_ibm_label ( DCR * dcr ) { DEVICE * volatile dev = dcr -> dev ; JCR * jcr = dcr -> jcr ; char label [ 80 ] ; int stat , i ; char * VolName = dcr -> VolumeName ; bool ok = false ; Dmsg0 ( 100 , " \n " ) ; if ( ! dev -> is_tape ( ) ) { return VOL_OK ; } dev -> label_type = B_BACULA_LABEL ; for ( i = 0 ; i < 6 ; i ++ ) { do { stat = dev -> read ( label , sizeof ( label ) ) ; } while ( stat == -1 && errno == EINTR ) ; if ( stat < 0 ) { berrno be ; dev -> clrerror ( -1 ) ; Dmsg1 ( 100 , " \n " , be . bstrerror ( ) ) ; Mmsg2 ( jcr -> errmsg , _ ( " \n " ) , dev -> dev_name , be . bstrerror ( ) ) ; Jmsg ( jcr , M_ERROR , 0 , " " , dev -> errmsg ) ; dev -> VolCatInfo . VolCatErrors ++ ; return VOL_IO_ERROR ; } if ( stat == 0 ) { if ( dev -> at_eof ( ) ) { dev -> set_eot ( ) ; Dmsg0 ( 100 , " \n " ) ; Mmsg0 ( jcr -> errmsg , _ ( " \n " ) ) ; return VOL_LABEL_ERROR ; } else { dev -> set_ateof ( ) ; } } switch ( i ) { case 0 : if ( stat == 80 ) { if ( strncmp ( " " , label , 4 ) == 0 ) { ok = true ; dev -> label_type = B_ANSI_LABEL ; Dmsg0 ( 100 , " \n " ) ; } else { ebcdic_to_ascii ( label , label , sizeof ( label ) ) ; if ( strncmp ( " " , label , 4 ) == 0 ) { ok = true ; ; dev -> label_type = B_IBM_LABEL ; Dmsg0 ( 100 , " \n " ) ; Dmsg0 ( 100 , " \n " ) ; } } } if ( ! ok ) { Dmsg0 ( 100 , " \n " ) ; Mmsg0 ( jcr -> errmsg , _ ( " \n " ) ) ; return VOL_NO_LABEL ; } if ( VolName && * VolName && * VolName != ' ' ) { if ( ! same_label_names ( VolName , & label [ 4 ] ) ) { char * p = & label [ 4 ] ; char * q ; free_volume ( dev ) ; q = dev -> VolHdr . VolumeName ; for ( int i = 0 ; * p != ' ' && i < 6 ; i ++ ) { * q ++ = * p ++ ; } * q = 0 ; Dmsg0 ( 100 , " \n " ) ; reserve_volume ( dcr , dev -> VolHdr . VolumeName ) ; dev = dcr -> dev ; Dmsg2 ( 100 , " \n " , VolName , dev -> VolHdr . VolumeName ) ; Mmsg2 ( jcr -> errmsg , _ ( " \" \" \" \" \n " ) , VolName , dev -> VolHdr . VolumeName ) ; return VOL_NAME_ERROR ; } } break ; case 1 : if ( dev -> label_type == B_IBM_LABEL ) { ebcdic_to_ascii ( label , label , sizeof ( label ) ) ; } if ( stat != 80 || strncmp ( " " , label , 4 ) != 0 ) { Dmsg0 ( 100 , " \n " ) ; Mmsg0 ( jcr -> errmsg , _ ( " \n " ) ) ; return VOL_LABEL_ERROR ; } if ( strncmp ( " " , & label [ 4 ] , 11 ) != 0 ) { Dmsg1 ( 100 , " \n " , & label [ 4 ] ) ; Mmsg1 ( jcr -> errmsg , _ ( " \" \" \n " ) , dev -> VolHdr . VolumeName ) ; return VOL_NAME_ERROR ; } Dmsg0 ( 100 , " \n " ) ; break ; case 2 : if ( dev -> label_type == B_IBM_LABEL ) { ebcdic_to_ascii ( label , label , sizeof ( label ) ) ; } if ( stat != 80 || strncmp ( " " , label , 4 ) != 0 ) { Dmsg0 ( 100 , " \n " ) ; Mmsg0 ( jcr -> errmsg , _ ( " \n " ) ) ; return VOL_LABEL_ERROR ; } Dmsg0 ( 100 , " \n " ) ; break ; default : if ( stat == 0 ) { Dmsg0 ( 100 , " \n " ) ; return VOL_OK ; } if ( dev -> label_type == B_IBM_LABEL ) { ebcdic_to_ascii ( label , label , sizeof ( label ) ) ; } if ( stat != 80 || strncmp ( " " , label , 3 ) != 0 ) { Dmsg0 ( 100 , " \n " ) ; Mmsg0 ( jcr -> errmsg , _ ( " \n " ) ) ; return VOL_LABEL_ERROR ; } Dmsg0 ( 100 , " \n " ) ; break ; } } Dmsg0 ( 100 , " \n " ) ; Mmsg0 ( jcr -> errmsg , _ ( " \n " ) ) ; return VOL_LABEL_ERROR ; }
We read an ANSI label and compare the Volume name.
We read an ANSI label and compare the Volume name .
/* tape label */ /*
    * Read VOL1, HDR1, HDR2 labels, but ignore the data
    *  If tape read the following EOF mark, on disk do
    *  not read.
    */ /* assume Bacula label */ /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */ /* second eof, set eot bit */ /* at EOM this shouldn't happen */ /* set eof state */ /* Want VOL1 label */ /* Try EBCDIC */ /* No ANSI label */ /* Compare Volume Names allow special wild card */ /* Store new Volume name */ /* ***FIXME***  why is this reserve_volume() needed???? KES */ /* may have changed in reserve_volume */ /* Not a Bacula label */