Article 158667 of comp.os.vms:
>Hi,
>
>I'm trying to find out how much free space on a disk on VMS using
>the system services SYS$GETDVI or LIB$GETDVI. But I look at the manuals
>and cannot figure out how to pass arguments to SYS$GETDVI or LIB$GETDVI.
>Does anyone have examples of calling SYS$GETDVI or LIB$GETDVI?
>
>Thanks for your help.
>
>Yingzhong Wen
>ywen@cs.buffalo.edu


Hello. When I was learning C, I mostly used system services for example programs.  I 
make no claims about this program as far as good programming style, etc. but it does 
compile and link without errors and it does work on VMS 6.2.

Bill McLaughlin

/* DISKINFO.C */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stsdef.h>
#include <ssdef.h>
#include <dcdef.h>
#include <descrip.h>
#include <dvidef.h>
#include <devdef.h>
#include <dcdef.h>
#include <lib$routines.h>
#include <starlet.h>

/* These are not in include files that I found */

#define DVS$_DEVCLASS 1
#define DVS$_DEVTYPE 2

main()
{
    unsigned long int Stat = 0,
                      GetDviStat = 0,
                      ItemNo = 0,
                      MaxBlocks = 0,
                      FreeBlocks = 0,
                      DeviceClass = 0,
                      DevChar = 0,
                      Mounted = 0,
                      DevType = 0,
                      ErrCnt = 0,
                      MediaNameLen = 0,
                      RetDeviceNameLen = 0,
                      AllDeviceNameLen = 0,
                      ShadowMember = 0,
                      ShadowMemberLen = 0,
                      ShadowMasterNameLen = 0,
                      VolumeNameLen = 0,
                      HostNameLen = 0,
                      ScanContext[2] = { 0, 0};

    unsigned short int DeviceNameLen = 0;

    char MediaName[65],
         RetDeviceName[65],
         AllDeviceName[65],
         ShadowMasterName[65],
         VolumeName[65],
         HostName[65];

    static char DeviceName[65];
    $DESCRIPTOR ( DeviceName_d, DeviceName );

    struct itemlist_3
      {
        unsigned short int BufLen;
        unsigned short int ItmCod;
        unsigned long int *BufAdr;
        unsigned long int *RetAdr;
      } DiskScanList[2];

    struct itemlist_3 DiskInfoList[25];

    struct IoStatusBlock
      {
        unsigned short int Stat;
        unsigned short int ByteCount;
        unsigned long int OtherInfo;
    } Iosb = { 0, 0, 0 };

    /* Set up itemlist for DEVICE_SCAN */

    memset ( DiskScanList, 0, sizeof(DiskScanList) );

    ItemNo = 0;

    DiskScanList[ItemNo].BufLen = sizeof(DeviceClass);
    DiskScanList[ItemNo].ItmCod = DVS$_DEVCLASS;
    DiskScanList[ItemNo].BufAdr = &DeviceClass;
    DiskScanList[ItemNo++].RetAdr = 0;

    DiskScanList[ItemNo].BufLen = 0;
    DiskScanList[ItemNo].ItmCod = 0;
    DiskScanList[ItemNo].BufAdr = 0;
    DiskScanList[ItemNo++].RetAdr = 0;

    /* Set up itemlist for GETDVI */

    memset ( DiskInfoList, 0, sizeof(DiskInfoList) );

    ItemNo = 0;

    DiskInfoList[ItemNo].BufLen = sizeof(MaxBlocks);
    DiskInfoList[ItemNo].ItmCod = DVI$_MAXBLOCK;
    DiskInfoList[ItemNo].BufAdr = &MaxBlocks;
    DiskInfoList[ItemNo++].RetAdr = 0;

    DiskInfoList[ItemNo].BufLen = sizeof(FreeBlocks);
    DiskInfoList[ItemNo].ItmCod = DVI$_FREEBLOCKS;
    DiskInfoList[ItemNo].BufAdr = &FreeBlocks;
    DiskInfoList[ItemNo++].RetAdr = 0;

    DiskInfoList[ItemNo].BufLen = sizeof(AllDeviceName) - 1;
    DiskInfoList[ItemNo].ItmCod = DVI$_ALLDEVNAM;
    DiskInfoList[ItemNo].BufAdr = (unsigned long int *) AllDeviceName;
    DiskInfoList[ItemNo++].RetAdr = &AllDeviceNameLen;

    DiskInfoList[ItemNo].BufLen = sizeof(VolumeName) - 1;
    DiskInfoList[ItemNo].ItmCod = DVI$_VOLNAM;
    DiskInfoList[ItemNo].BufAdr = (unsigned long int *) VolumeName;
    DiskInfoList[ItemNo++].RetAdr = &VolumeNameLen;

    DiskInfoList[ItemNo].BufLen = sizeof(HostName) - 1;
    DiskInfoList[ItemNo].ItmCod = DVI$_HOST_NAME;
    DiskInfoList[ItemNo].BufAdr = (unsigned long int *) HostName;
    DiskInfoList[ItemNo++].RetAdr = &HostNameLen;

    DiskInfoList[ItemNo].BufLen = sizeof(RetDeviceName) - 1;
    DiskInfoList[ItemNo].ItmCod = DVI$_DEVNAM;
    DiskInfoList[ItemNo].BufAdr = (unsigned long int *) RetDeviceName;
    DiskInfoList[ItemNo++].RetAdr = &RetDeviceNameLen;

    DiskInfoList[ItemNo].BufLen = sizeof(ShadowMasterName) - 1;
    DiskInfoList[ItemNo].ItmCod = DVI$_SHDW_MASTER_NAME;
    DiskInfoList[ItemNo].BufAdr = (unsigned long int *) ShadowMasterName;
    DiskInfoList[ItemNo++].RetAdr = &ShadowMasterNameLen;

    DiskInfoList[ItemNo].BufLen = sizeof(ShadowMember);
    DiskInfoList[ItemNo].ItmCod = DVI$_SHDW_MEMBER;
    DiskInfoList[ItemNo].BufAdr = &ShadowMember;
    DiskInfoList[ItemNo++].RetAdr = &ShadowMemberLen;

    DiskInfoList[ItemNo].BufLen = sizeof(DevChar);
    DiskInfoList[ItemNo].ItmCod = DVI$_DEVCHAR;
    DiskInfoList[ItemNo].BufAdr = &DevChar;
    DiskInfoList[ItemNo++].RetAdr = 0;

    DiskInfoList[ItemNo].BufLen = sizeof(DevType);
    DiskInfoList[ItemNo].ItmCod = DVI$_DEVTYPE;
    DiskInfoList[ItemNo].BufAdr = &DevType;
    DiskInfoList[ItemNo++].RetAdr = 0;

    DiskInfoList[ItemNo].BufLen = sizeof(ErrCnt);
    DiskInfoList[ItemNo].ItmCod = DVI$_ERRCNT;
    DiskInfoList[ItemNo].BufAdr = &ErrCnt;
    DiskInfoList[ItemNo++].RetAdr = 0;

    DiskInfoList[ItemNo].BufLen = sizeof(MediaName);
    DiskInfoList[ItemNo].ItmCod = DVI$_MEDIA_NAME;
    DiskInfoList[ItemNo].BufAdr = (unsigned long int *) MediaName;
    DiskInfoList[ItemNo++].RetAdr = &MediaNameLen;

    /* Terminator our itemlist */

    DiskInfoList[ItemNo].BufLen = 0;
    DiskInfoList[ItemNo].ItmCod = 0;
    DiskInfoList[ItemNo].BufAdr = 0;
    DiskInfoList[ItemNo].RetAdr = 0;

    /* Use $device_scan to search for all devices matching our criteria */

    DeviceClass = DC$_DISK;  /* All we care about is disks */

    memset ( DeviceName, 0, sizeof(DeviceName) );

    Stat = SS$_NORMAL;

    while ( Stat == SS$_NORMAL )
    {
        Stat = sys$device_scan ( &DeviceName_d,
                                 &DeviceNameLen, 
                                 0, 
                                 &DiskScanList, 
                                 &ScanContext );

        if ( Stat == SS$_NOMOREDEV ) break;

        if ( (Stat & 1) != 1 ) lib$stop ( Stat );

    /* Now put a null after device name since the $device_scan routine     */
    /* pads the device name with spaces.                                   */

        DeviceName[DeviceNameLen] = 0;

        memset ( MediaName, 0, sizeof(MediaName));

        GetDviStat = sys$getdviw ( 0, 0, &DeviceName_d, &DiskInfoList, 
                                   &Iosb, 0, 0, 0 );
                                  
        if ( (GetDviStat & 1) != 1 ) lib$stop ( GetDviStat );
        if ( (Iosb.Stat & 1) != 1 ) lib$stop ( Iosb.Stat );

        Mounted = ((DevChar & (long int)DEV$M_MNT) != 0);

        if (Mounted)
        {
          if (!ShadowMember)
          {
            printf("%14s (%6s) %s %s Free: %d / Total: %d  Errors: %d\n", 
                   AllDeviceName, HostName, MediaName, VolumeName,
                   FreeBlocks, MaxBlocks, ShadowMember,
                   ErrCnt);
          }
          else
          {
            printf("%14s (%6s) %s %s Member of %s Errors: %d\n", 
                   AllDeviceName, HostName, MediaName,
                   VolumeName, ShadowMasterName, 
                   ErrCnt);
          } /* End IF */
        }
        else
        {
          printf("%14s (%6s) %s ** Not Mounted**\n", 
                 AllDeviceName, HostName, MediaName);
        } /* End If */

    } /* End While */

    sys$exit ( 1 );

}



