Article 96087 of comp.os.vms:
Xref: mv comp.os.vms:96087
Path: mv!news.sprintlink.net!newsfeed.internetmci.com!news.mathworks.com!mvb.saic.com!info-vax
From: "Ed James 410-204-2042 james@mml.mmc.com" <JAMES@mml.mmc.com>
Newsgroups: comp.os.vms
Subject: RE: Volume label of unmounted disk
Message-ID: <960305084447.202000c5@mml.mmc.com>
Date: Tue, 5 Mar 1996 8:44:47 -0500 (EST)
Organization: Info-Vax<==>Comp.Os.Vms Gateway
X-Gateway-Source-Info: Mailing List
Lines: 276

buxtonr@southpower.co.nz  wrote on  5 Mar 96 13:12:08 NZST:

> Does anyone know the location of any software that can return
> the label on an unmounted disk.

> I've got a compiled VAX program that does this and returns the
> volume label as a symbol, alas, I don't have the source and 
> we're migrating to Alpha.

Here's a program I got somewhere in MACRO. Does anyone know to whom the
credit belongs for the original?  I changed it to C and added code
to check for ISO 9660 CD-ROM labels.  It will work on VAX and Alpha.

I hope this helps.

Ed James                       Manager, Computer & Communications Services
Lockheed Martin Laboratories   Internet james@mml.mmc.com
1450 South Rolling Road        Voice    410-204-2042
Baltimore MD, 21227-3898       Fax      410-204-2115

/* Original program GET_F11_VOLUME_LABEL.MAR
 Abstract:
 GET_F11_LABEL will read LBN 1 of a disk device and extract the volume
 label field from the Home Block. LBN 1 is always a Home Block, the offset
 to the label field (12 characters) is decimal 472. Note that if LBN 1 has
 been revectored, this routine is not smart enough to go looking for another
 homeblock like MOUNT will - too much effort to implement this feature for
 very minimal gain. The disk must (obviously) be a valid ODS II volume.
 Disk does not need to be mounted (the whole point of the exercise is to get
 the label *without* mounting the disk.

 940118 vej
  Changed to check for null (hexadecimal zero) volume label. This assumes
  ISO 9660 format cdrom.  Then reads block 64 to get volume label of 32
  characters.

 940201 vej
  Converted to C

  Ed James                       Manager, Computer & Communications Services
  Lockheed Martin Laboratories   Internet james@mml.mmc.com
  1450 South Rolling Road        Voice    410-204-2042
  Baltimore MD, 21227-3898       Fax      410-204-2115

*/

#include ssdef
#include signal
#include iodef
#include descrip
#include string
#include stdlib
#include stdio
#include lib$routines
#include starlet

#ifndef EXIT_FAILURE
/* "Inhibit message" bit set in EXIT_FAILURE so a message is not displayed
   when program exits.
*/
#define EXIT_FAILURE 0x10000002  
#define EXIT_SUCCESS 0
#endif

typedef struct {
   unsigned short int status;
   union {
      struct {
         unsigned char transmit, receive, crfill, lffill, parity, zero;
      } trclpz;
      struct {
         unsigned short int speeds, fills, parityw;
      } sfp;
      struct {
         unsigned short int termoff, termchar, termsize;
      } ocs;
      struct {
         unsigned short int mbxbytes;
         unsigned long int senderpid;
      } mbx;
   } tsom;
} IOSTATBLOCK;

#define ERROR_MSG    fprintf( stderr,

#define BLOCK_SIZE   512   /* size of one disk block */
#define DEVNAM_SIZE  255   /* size of max filespec */
#define ODS_LAB_SIZE 12    /* ODS-2 volume label length */
#define ISO_LAB_SIZE 32    /* ISO 9660 volume label length */
#define MEDOFL_TIMES 30    /* Times to retry if SS$_MEDOFL */
#define MEDOFL_SECS  2     /* Seconds to wait before retry if SS$_MEDOFL */
                           /* Total time to wait for SS$_MEDOFL to clear
                              is MEDOFL_TIMES * MEDOFL_SECS */

unsigned int isnull( char *inptr, int inlen)
{
   int ii;

   for( ii=0; ii<inlen; ii++) {
      if( *inptr != '\0') return FALSE;
      inptr++;
   }
   return TRUE;
}

unsigned int main( int argc, char *argv[])
{

   $DESCRIPTOR( symdesc, "VOLUME_LABEL");
   $DESCRIPTOR( isodesc, "VOLUME_IS_ISO");

   IOSTATBLOCK dev_iosb;
   short int channel, ii, jj, done;
   unsigned long int status;
   char iso;
   
   struct dsc$descriptor_s devnam_desc;
   struct dsc$descriptor_s op_desc;
   char devnam_buffer[DEVNAM_SIZE+1], block_buffer[BLOCK_SIZE+1];

   devnam_desc.dsc$b_dtype = DSC$K_DTYPE_T;
   devnam_desc.dsc$b_class = DSC$K_CLASS_S;
   devnam_desc.dsc$a_pointer = devnam_buffer;

   if (argc == 2) {
      devnam_buffer[DEVNAM_SIZE+1] = '\0';
      strncpy( devnam_buffer, argv[1], DEVNAM_SIZE);
      devnam_desc.dsc$w_length = (short int) strlen( devnam_buffer);
   }                                          
   else {
      ERROR_MSG "Usage: get_f11_volume_label <device>\n");
      exit( EXIT_FAILURE);
   }

   /* Assign a channel to disk */
   status = sys$assign( 
      &devnam_desc,  /* disk device name descriptor */
      &channel,      /* disk device channel number */
      0,             /* default access mode */
      0);            /* no mailbox */
   if( (status & 1) == 0) {
      ERROR_MSG "Error in assign status\n");
      lib$stop( status);
   }

   for( ii=0, done=FALSE; ((ii<MEDOFL_TIMES) && (! done)); ii++) {
      status = sys$qiow(
         0,                   /* Default event flag #, OK for synch I/O */
         channel,             /* Disk channel */
         IO$_PACKACK,         /* pack acknowledge sets pack valid bit */
         &dev_iosb,           /* I/O Status Block */
         0,                   /* No AST completion routine */
         0,                   /*   or parameters */
         0, 0, 0, 0, 0, 0);   /* No P1-P6 */
      if( (((status & 1) == 0) && (status == SS$_MEDOFL)) ||
          (((dev_iosb.status & 1) == 0) && (dev_iosb.status == SS$_MEDOFL)) ) {
         /* the medium is offline, retry i/o */
         if( sleep( MEDOFL_SECS) < 0) {
            ERROR_MSG "Error in readpblk 1 sleep status\n");
            lib$stop( status);
         }
      }
      else {
         done = TRUE;
      }
   }
   if( (status & 1) == 0) {
      ERROR_MSG "Error in packack status\n");
      lib$stop( status);
   }
   if( (dev_iosb.status & 1) == 0) {
      ERROR_MSG "Error in packack dev_iosb.status\n");
      lib$stop( dev_iosb.status);
   }

   for( ii=0, done=FALSE; ((ii<MEDOFL_TIMES) && (! done)); ii++) {
      /* Read Logical Block Number (LBN) 1 - home block if not ISO */
      status = sys$qiow(
         0,                   /* Default event flag #, OK for synch I/O */
         channel,             /* Disk channel */
         IO$_READLBLK,        /* Read logical block */
         &dev_iosb,           /* I/O Status Block */
         0,                   /* No AST completion routine */
         0,                   /*   or parameters */
         block_buffer,        /* P1 = buffer address */
         BLOCK_SIZE,          /* P2 = byte count */
         1,                   /* P3 = LBN */
         0, 0, 0);            /* No P4-P6 */
      if( (((status & 1) == 0) && (status == SS$_MEDOFL)) ||
          (((dev_iosb.status & 1) == 0) && (dev_iosb.status == SS$_MEDOFL)) ) {
         /* the medium is offline, retry i/o */
         if( sleep( MEDOFL_SECS) < 0) {
            ERROR_MSG "Error in readpblk 1 sleep status\n");
            lib$stop( status);
         }
      }
      else {
         done = TRUE;
      }
   }
   if( (status & 1) == 0) {
      ERROR_MSG "Error in readpblk 1 status\n");
      lib$stop( status);
   }
   if( (dev_iosb.status & 1) == 0) {
      ERROR_MSG "Error in readpblk 1 dev_iosb.status\n");
      lib$stop( dev_iosb.status);
   }

   op_desc.dsc$b_dtype = DSC$K_DTYPE_T;
   op_desc.dsc$b_class = DSC$K_CLASS_S;

   if( ! isnull( &block_buffer[472], ODS_LAB_SIZE)) {
      iso = 'N';        /* Not ISO disk */
      op_desc.dsc$w_length = ODS_LAB_SIZE;
      op_desc.dsc$a_pointer = &block_buffer[472];
   }
   else {
      iso = 'Y';        /* ISO disk */
      op_desc.dsc$w_length = ISO_LAB_SIZE;
      op_desc.dsc$a_pointer = &block_buffer[40];
      for( ii=0, done=FALSE; ((ii<MEDOFL_TIMES) && (! done)); ii++) {
         /* Read LBN 64 - home block if ISO */
         status = sys$qiow(
            0,                   /* Default event flag #, OK for synch I/O */
            channel,             /* Disk channel */
            IO$_READLBLK,        /* Read logical block */
            &dev_iosb,           /* I/O Status Block */
            0,                   /* No AST completion routine */
            0,                   /*   or parameters */
            block_buffer,        /* P1 = buffer address */
            BLOCK_SIZE,          /* P2 = byte count */
            64,                  /* P3 = LBN */
            0, 0, 0);            /* No P4-P6 */
         if( (((status & 1) == 0) && (status == SS$_MEDOFL)) ||
             (((dev_iosb.status & 1) == 0) && (dev_iosb.status == SS$_MEDOFL)) ) 
{
            /* the medium is offline, retry i/o */
            if( sleep( MEDOFL_SECS) < 0) {
               ERROR_MSG "Error in readpblk 64 sleep status\n");
               lib$stop( status);
            }
         }
         else {
            done = TRUE;
         }
      }
      if( (status & 1) == 0) {
         ERROR_MSG "Error in readpblk 64 status\n");
         lib$stop( status);
      }
      if( (dev_iosb.status & 1) == 0) {
         ERROR_MSG "Error in readpblk 64 dev_iosb.status\n");
         lib$stop( dev_iosb.status);
      }
   }
   /* Deassign channel to disk */
   status = sys$dassgn( channel);
   if( (status & 1) == 0) {
      ERROR_MSG "Error in deassign status\n");
      lib$stop( status);
   }
   status = lib$set_symbol( &symdesc, &op_desc);
   if( (status & 1) == 0) {
      ERROR_MSG "Error in lib$set_symbol volume_label\n");
      lib$stop( status);
   }
   op_desc.dsc$w_length = 1;
   op_desc.dsc$a_pointer = &iso;
   status = lib$set_symbol( &isodesc, &op_desc);
   if( (status & 1) == 0) {
      ERROR_MSG "Error in lib$set_symbol volume_is_iso\n");
      lib$stop( status);
   }
}



