580 lines
14 KiB
RPGLE
580 lines
14 KiB
RPGLE
**FREE
|
|
|
|
//=====================================================================
|
|
//
|
|
// Media Definition Parser
|
|
//
|
|
// Parses TAPE0200 data returned by QSRRTVMD.
|
|
//
|
|
//=====================================================================
|
|
|
|
ctl-opt
|
|
option(*srcstmt:*nodebugio) nomain;
|
|
|
|
|
|
/COPY './meddfn_h.rpgle'
|
|
/COPY './meddfnap_h.rpgle'
|
|
|
|
|
|
//=====================================================================
|
|
//
|
|
// Prototype
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-pr MD_ParseRetrieveBuffer;
|
|
|
|
ReceiverBuffer
|
|
char(32767) const
|
|
options(*varsize);
|
|
|
|
ReceiverLength
|
|
int(10) const;
|
|
|
|
MediaDefinition
|
|
likeds(MD_MediaDefinition_T);
|
|
|
|
Error
|
|
likeds(MD_Error_T);
|
|
|
|
end-pr;
|
|
|
|
|
|
//=====================================================================
|
|
//
|
|
// MD_ParseRetrieveBuffer
|
|
//
|
|
// Parses a retrieved TAPE0200 buffer.
|
|
//
|
|
// Supported:
|
|
//
|
|
// - TAPE0200 Header
|
|
// - Device Definitions
|
|
// - Media File Definitions
|
|
// - Volume Identifier Arrays
|
|
//
|
|
// Parser errors are returned in Error.
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-proc MD_ParseRetrieveBuffer export;
|
|
|
|
dcl-pi *n;
|
|
|
|
ReceiverBuffer
|
|
char(32767) const
|
|
options(*varsize);
|
|
|
|
ReceiverLength
|
|
int(10) const;
|
|
|
|
MediaDefinition
|
|
likeds(MD_MediaDefinition_T);
|
|
|
|
Error
|
|
likeds(MD_Error_T);
|
|
|
|
end-pi;
|
|
|
|
|
|
//==================================================================
|
|
// TAPE0200 structures
|
|
//==================================================================
|
|
|
|
dcl-ds Header
|
|
likeds(MD_Tape0200Header_T);
|
|
|
|
dcl-ds Device
|
|
likeds(MD_Tape0200DeviceDefinition_T);
|
|
|
|
dcl-ds MediaFile
|
|
likeds(MD_Tape0200MediaFileDefinition_T);
|
|
|
|
|
|
//==================================================================
|
|
// Working variables
|
|
//==================================================================
|
|
|
|
dcl-s DeviceOffset
|
|
int(10);
|
|
|
|
dcl-s MediaOffset
|
|
int(10);
|
|
|
|
dcl-s VolumeOffset
|
|
int(10);
|
|
|
|
dcl-s DeviceIndex
|
|
int(10);
|
|
|
|
dcl-s MediaIndex
|
|
int(10);
|
|
|
|
dcl-s VolumeIndex
|
|
int(10);
|
|
|
|
dcl-s RequiredLength
|
|
int(10);
|
|
|
|
|
|
//==================================================================
|
|
// Initialize
|
|
//==================================================================
|
|
|
|
clear MediaDefinition;
|
|
clear Error;
|
|
|
|
|
|
//==================================================================
|
|
// Receiver buffer
|
|
//==================================================================
|
|
|
|
if ReceiverLength < %size(Header);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2005';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
//==================================================================
|
|
// TAPE0200 Header
|
|
//==================================================================
|
|
|
|
Header =
|
|
%subst(
|
|
ReceiverBuffer :
|
|
1 :
|
|
%size(Header));
|
|
|
|
|
|
//==================================================================
|
|
// Validate Header
|
|
//==================================================================
|
|
|
|
if Header.LengthOfHeader <> %size(Header);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2001';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if Header.NumberOfDeviceDefinitions < 1
|
|
or Header.NumberOfDeviceDefinitions > MD_MaxDeviceDefinitions;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2001';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if Header.OffsetToFirstDeviceDefinition < %size(Header)
|
|
or Header.OffsetToFirstDeviceDefinition >
|
|
ReceiverLength - %size(Device);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2001';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if Header.DeviceAllocation <> MD_DeviceAllocateAll
|
|
and Header.DeviceAllocation <> MD_DeviceAllocateOne
|
|
and Header.DeviceAllocation <> MD_DeviceAllocateMinimum;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2001';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if Header.SaveFormat <> MD_SaveFormatAuto
|
|
and Header.SaveFormat <> MD_SaveFormatSerial
|
|
and Header.SaveFormat <> MD_SaveFormatParallel;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2001';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if Header.MaximumParallelDeviceResources < 0
|
|
or Header.MinimumParallelDeviceResources < 0
|
|
or Header.MinimumParallelDeviceResources >
|
|
Header.MaximumParallelDeviceResources;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2001';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
//==================================================================
|
|
// Header -> Media Definition
|
|
//==================================================================
|
|
|
|
MediaDefinition.MaximumParallelResources =
|
|
Header.MaximumParallelDeviceResources;
|
|
|
|
MediaDefinition.MinimumParallelResources =
|
|
Header.MinimumParallelDeviceResources;
|
|
|
|
MediaDefinition.NumberOfDevices =
|
|
Header.NumberOfDeviceDefinitions;
|
|
|
|
MediaDefinition.DeviceAllocation =
|
|
Header.DeviceAllocation;
|
|
|
|
MediaDefinition.SaveFormat =
|
|
Header.SaveFormat;
|
|
|
|
|
|
//==================================================================
|
|
// Device Definitions
|
|
//==================================================================
|
|
|
|
DeviceOffset =
|
|
Header.OffsetToFirstDeviceDefinition;
|
|
|
|
|
|
for DeviceIndex = 1
|
|
to Header.NumberOfDeviceDefinitions;
|
|
|
|
|
|
//===============================================================
|
|
// Validate Device Offset
|
|
//===============================================================
|
|
|
|
if DeviceOffset < 0
|
|
or DeviceOffset > ReceiverLength - %size(Device);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2002';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
//===============================================================
|
|
// Read Device Definition
|
|
//===============================================================
|
|
|
|
Device =
|
|
%subst(
|
|
ReceiverBuffer :
|
|
DeviceOffset + 1 :
|
|
%size(Device));
|
|
|
|
|
|
//===============================================================
|
|
// Validate Device Definition
|
|
//===============================================================
|
|
|
|
if Device.LengthOfDeviceDefinition <> %size(Device);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2002';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if Device.NumberOfMediaFileDefinitions < 1
|
|
or Device.NumberOfMediaFileDefinitions > MD_MaxMediaDefinitions;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2002';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if %trim(Device.DeviceName) = '';
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2002';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if Device.OffsetToFirstMediaFileDefinition < %size(Device);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2002';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
//===============================================================
|
|
// Device -> Media Definition
|
|
//===============================================================
|
|
|
|
MediaDefinition.Device(DeviceIndex).DeviceName =
|
|
Device.DeviceName;
|
|
|
|
MediaDefinition.Device(DeviceIndex).NumberOfMediaFiles =
|
|
Device.NumberOfMediaFileDefinitions;
|
|
|
|
|
|
//===============================================================
|
|
// Media Files
|
|
//===============================================================
|
|
|
|
MediaOffset =
|
|
DeviceOffset
|
|
+ Device.OffsetToFirstMediaFileDefinition;
|
|
|
|
|
|
for MediaIndex = 1
|
|
to Device.NumberOfMediaFileDefinitions;
|
|
|
|
|
|
//============================================================
|
|
// Validate Media Offset
|
|
//============================================================
|
|
|
|
if MediaOffset < 0
|
|
or MediaOffset > ReceiverLength - %size(MediaFile);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2003';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
//============================================================
|
|
// Read Media File Definition
|
|
//============================================================
|
|
|
|
MediaFile =
|
|
%subst(
|
|
ReceiverBuffer :
|
|
MediaOffset + 1 :
|
|
%size(MediaFile));
|
|
|
|
|
|
//============================================================
|
|
// Validate Media File Definition
|
|
//============================================================
|
|
|
|
if MediaFile.LengthOfMediaFileDefinition <> %size(MediaFile);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2003';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if MediaFile.NumberOfVolumeIdentifiers < 0
|
|
or MediaFile.NumberOfVolumeIdentifiers > MD_MaxVolumeIdentifiers;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2003';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
|
|
if MediaFile.NumberOfVolumeIdentifiers = 0;
|
|
|
|
if MediaFile.OffsetToVolumeIdentifierArray <> 0
|
|
or MediaFile.LengthOfVolumeIdentifier <> 0
|
|
or MediaFile.StartingVolumeArrayElement <> 0;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2004';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
else;
|
|
|
|
if MediaFile.OffsetToVolumeIdentifierArray <= 0
|
|
or MediaFile.LengthOfVolumeIdentifier <> MD_VOLUME_ID_LENGTH
|
|
or MediaFile.StartingVolumeArrayElement < 1;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2004';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
RequiredLength =
|
|
MediaFile.NumberOfVolumeIdentifiers
|
|
* MediaFile.LengthOfVolumeIdentifier;
|
|
|
|
if MediaFile.OffsetToVolumeIdentifierArray >
|
|
ReceiverLength - RequiredLength
|
|
or MediaFile.OffsetToVolumeIdentifierArray <
|
|
MediaOffset + %size(MediaFile);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2004';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
endif;
|
|
|
|
|
|
//============================================================
|
|
// Media File -> Media Definition
|
|
//============================================================
|
|
|
|
MediaDefinition.Device(DeviceIndex)
|
|
.MediaFile(MediaIndex)
|
|
.SequenceNumber =
|
|
MediaFile.SequenceNumber;
|
|
|
|
|
|
MediaDefinition.Device(DeviceIndex)
|
|
.MediaFile(MediaIndex)
|
|
.StartingPositionInFile =
|
|
MediaFile.StartingPositionInFile;
|
|
|
|
|
|
MediaDefinition.Device(DeviceIndex)
|
|
.MediaFile(MediaIndex)
|
|
.NumberOfVolumeIdentifiers =
|
|
MediaFile.NumberOfVolumeIdentifiers;
|
|
|
|
|
|
//============================================================
|
|
// Volume Identifier Array
|
|
//============================================================
|
|
|
|
if MediaFile.NumberOfVolumeIdentifiers > 0;
|
|
|
|
VolumeOffset =
|
|
MediaFile.OffsetToVolumeIdentifierArray;
|
|
|
|
|
|
for VolumeIndex = 1
|
|
to MediaFile.NumberOfVolumeIdentifiers;
|
|
|
|
MediaDefinition.Device(DeviceIndex)
|
|
.MediaFile(MediaIndex)
|
|
.VolumeIdentifier(VolumeIndex)
|
|
.VolumeIdentifier =
|
|
%subst(
|
|
ReceiverBuffer :
|
|
VolumeOffset
|
|
+ ((VolumeIndex - 1)
|
|
* MediaFile.LengthOfVolumeIdentifier)
|
|
+ 1 :
|
|
MediaFile.LengthOfVolumeIdentifier);
|
|
|
|
endfor;
|
|
|
|
endif;
|
|
|
|
|
|
//============================================================
|
|
// Next Media File
|
|
//============================================================
|
|
|
|
if MediaIndex
|
|
< Device.NumberOfMediaFileDefinitions;
|
|
|
|
if MediaFile.OffsetToNextMediaFileDefinition <=
|
|
MediaOffset
|
|
or MediaFile.OffsetToNextMediaFileDefinition >
|
|
ReceiverLength - %size(MediaFile);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2003';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
MediaOffset =
|
|
MediaFile.OffsetToNextMediaFileDefinition;
|
|
|
|
else;
|
|
|
|
if MediaFile.OffsetToNextMediaFileDefinition <> 0;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2003';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
endif;
|
|
|
|
|
|
endfor;
|
|
|
|
|
|
//================================================================
|
|
// Next Device
|
|
//================================================================
|
|
|
|
if DeviceIndex < Header.NumberOfDeviceDefinitions;
|
|
|
|
if Device.OffsetToNextDeviceDefinition <=
|
|
DeviceOffset
|
|
or Device.OffsetToNextDeviceDefinition >
|
|
ReceiverLength - %size(Device);
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2002';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
DeviceOffset =
|
|
Device.OffsetToNextDeviceDefinition;
|
|
|
|
else;
|
|
|
|
if Device.OffsetToNextDeviceDefinition <> 0;
|
|
|
|
Error.HasError = *on;
|
|
Error.MessageID = 'MDF2002';
|
|
Error.MessageData = *blanks;
|
|
return;
|
|
|
|
endif;
|
|
|
|
endif;
|
|
|
|
|
|
endfor;
|
|
|
|
|
|
end-proc;
|