home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
viscobv6.zip
/
vac22os2
/
ibmcobol
/
samples
/
sdu
/
dfmacall.c
< prev
next >
Wrap
Text File
|
1997-03-19
|
61KB
|
1,253 lines
/**************************************************************************
**************************** DFMACALL.C *********************************
***************************************************************************
*
* DFM DataAgent Sample
*
* Module Name: DFMACALL.C
* This module demonstrates the ability to invoke DFM DataAgent
* functions from C applications on workstations running SdU.
*
* If modified, rename and compile it on a workstation using the header
* files distributed with SdU.
*
* SdU (program no. 5648-02011)
*
* Version: 1.0
* Release: 1.0
*
* Copyright (C)
* International Business Machines Corporation 1997
*
* DISCLAIMER OF WARRANTIES: The following (enclosed) code is sample code
* created by the IBM Corporation. This sample code is not a part of any
* IBM product and is provided to you solely for the purpose of assisting
* you in the development of your applications. The code is provided
* "AS IS", without warranty of any kind. IBM shall not be liable for any
* damages arising out of your use of the sample code, even if they have
* been advised of the possibility of such damages.
*
* The sample program does the following:
*
* 1) Construct a filename and filename suffix from the input parameters.
* 2) Do a DDMOpen for the file or directory to trigger MVS suffix
* processing.
* 3) Do a DDMClose for the file or directory to terminate processing.
* 4) Do a DDMUnLoadFileFirst and DDMUnLoadFileNext to display a server
* system file.
*
* COMMAND LINE INVOCATION:
*
* Note:
* 1. References to "driverletter" represents a driver letter that
* has been defined to be associated with a server system and optionally,
* a logon userid of IBMUSER via the dfmdrive command. In the examples that
* follow, drive letters r: and s: have been defined by issuing the
* following dfmdrive commands.
*
* dfmdrive assign r: //MVS
*
* dfmdrive assign s: IBMUSER //MVS
*
* In this case, MVS is the remote server system, and IBMUSER is
* the logon userid to MVS. References to MVS and IBMUSER will be
* used in the following examples.
*
* 2. When the DISPLAY option is specified, the records of a server system
* file is displayed on the console. To ensure that the data to display
* is in ASCII format, a FILE_DESCRIPTOR_MAP statement for the server
* system file to display should be defined. For example, if the
* possible server system files to display are IBMUSER.DFMXTSO.SYSTSPRT
* and IBMUSER.DFMQTSO.SYSTSPRT, the following FILE_DESCRIPTOR_MAP
* statement may be created to ensure that data from these files are
* converted from EBCDIC to ASCII.
*
* FILE_DESCRIPTOR_MAP (
* TARGET_SYSTEM (MVS)
* TARGET_FILENAME (IBMUSER.DFM*.*)
* BASE_DDF(base.ddf)
* VIEW_DDF(view.ddf)
* )
*
* The last splat '*' character of the TARGET_FILENAME parameter
* ensures that the stream of data which represents a DataAgent
* request (ie. IBMUSER.DFMQTSO.SYSTSPRT,(dfmqtso,u=userID,pgm(dfmqtso),
* parm()) does not prevent DFM for Windows from converting the
* server system file data from EBCDIC to ASCII.
*
* The view.adl and base.adl files are defined as follows:
*
* view.adl
* ========
* DECLARE
* BEGIN;
* ViewRec:
* SEQUENCE
* BEGIN;
* Localtxt: CHAR LENGTH (80) CCSID (437);
* END;
* END;
*
* base.adl
* ========
* DECLARE
* BEGIN;
* BaseRec:
* SEQUENCE
* BEGIN;
* Remotetxt: CHAR LENGTH (80) CCSID(500);
* END;
* END;
*
*
* 3. When issuing the TSO requests from dfmacall, data set IBMUSER.DFMXTSO.SYSTSPRT
* and IBMUSER.DFMXTSO.SYSTSIN should be predefined. Similarly, when issuing
* a QTSO request, IBMUSER.DFMQTSO.SYSTSPRT should be predefined. These
* datasets should be defined to have a logical record length of 80 to match
* the view and base adl record format descriptions examples described above.
* Note: a record length mismatch condition between the base/view adl file
* record format description and the remote/local files may lead to a Translation
* Error (ie. XLATERM reply message).
*
* This sample can be invoked in the following formats:
*
* DFMACALL QTSO driveletter: TSOcommandline [DISPLAY]
* DFMACALL TSO driveletter: [TSOcommandline] [DISPLAY]
* DFMACALL AGENT driveletter:[filename] MVSprocedure[,procedural_parameters]
* [PGM program_name] [PARM program-parameters] [DISPLAY]
* DFMACALL START driveletter: MVSprocedure[,procedural_parameters]
* DFMACALL driveletter:filename[,filename_suffix] [DISPLAY]
*
* The last format is free-form in which MVS parameters can be specified
* in the filename suffix. Parameters that are relevant to DFM
* DataAgent processing are the following:
* AGENT(agentname) - Specifies the name of a procedure in SYS1.PROCLIB
* that provides the JCL for agent processing and, if PGM is
* omitted, the name of the DataAgent routine (program) to run.
* Note that procedural parameters can also be specifed. For
* example, AGENT(agentname,USER=userID,DSNAME=DS1,...). If
* you use the free-form format, remember to specify PARM also.
* PGM(programname) - Specifies the name of the DataAgent routine.
* PARM(program_name) - Specifies input parameters to the DataAgent
* routine.
* START(procedurename,procedure parameters) - Specifies the name of an
* MVS procedure to be started asynchronously.
* DISPLAY - Displays the result of the call to DFM DataAgent. In the case of
* QTSO or TSO the result is the SYSTSPRT file. In the case of other
* DataAgents it is the output name returned by the DataAgent routine
* after successful invocation. See DFMXSORT for an example.
* (Note that DISPLAY can be used as a DataAgent name with DFMACALL
* but not as a TSO command.)
*
* Examples:
*
* dfmacall r:ibmuser.a.b
* ==> Opens and closes MVS file ibmuser.a.b on remote drive r.
*
* dfmacall r:ibmuser.a.b,agent(dfmxagnt)
* ==> Opens and closes MVS file ibmuser.a.b invoking agent dfmxagnt.
*
* dfmacall r:ibmuser.a.b,agent(dfmx0001),pgm(dfmxagnt)
* ==> Opens and closes MVS file ibmuser.a.b invoking agent dfmx0001
* ==> with program dfmxagnt.
*
* dfmacall agent r:ibmuser.a.b dfmxagnt
* ==> Opens and closes MVS file ibmuser.a.b invoking agent dfmxagnt
* ==> with default program dfmxagnt and null parameters implied.
*
* dfmacall agent r:ibmuser.a.b dfmxtso pgm ikjeft01
* ==> Opens and closes MVS file ibmuser.a.b invoking agent dfmxtso
* ==> with (APF-authorized) program ikjeft01. (Equivalent to
* ==> DFMACALL TSO.)
*
* dfmacall start s: dfmx0001,dfminit=iefbr14
* ==> Asynchronously starts procedure dfmx0001 with parameter
* ==> dfminit set to iefbr14.
*
* dfmacall qtso s: listc display
* ==> Calls TSO to list catalog entries and place the results
* ==> in IBMUSER.DFMQTSO.SYSTSPRT. No SYSTSIN input file is
* ==> expected. The SYSTSPRT file is displayed.
*
* dfmacall tso s:
* ==> Calls TSO to process input file IBMUSER.DFMXTSO.SYSTSIN
* ==> and put the results in IBMUSER.DFMXTSO.SYSTSPRT.
*
* dfmacall tso s: "profile prefix(ibmuser)" display
* ==> After running the command passed it (in this case "profile")
* ==> it calls TSO to process input file IBMUSER.DFMXTSO.SYSTSIN
* ==> and put the results in IBMUSER.DFMXTSO.SYSTSPRT. Display the
* ==> output file.
*
*
* Change Summary:
* $L0,960724,SJPLMMR: Initial code for SdU support of DFM/MVS DataAgent
* $P1,970303,SJPLWBN: Increase buffer parameter size from 100 to 255
* (PARMLEN).
* $P2,970314,SJPLTML: DataAgent request is nolonger suppressed when the
* DISPLAY option is specified.
* $P3=970319,SJPLTML: Add missing RM table entries.
*
***************************************************************************/
#include <os2.h> /* required for RLIO applications */
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
#include "dub.h" /* required master include for RLIO applications */
/*-------------------------------------------------------------------------
-- SYMBOLIC CONSTANTS
--------------------------------------------------------------------------*/
#define FILCLS_SIZE sizeof(OBJLENGTH) + (2 * sizeof(CODEPOINT))
#define FILCLS_NAME ".DDM_FILCLS"
#define RECDATALEN 100
#define RPYMSBFLN 546 /* reply message buffer length */
#define PATHLEN 300 /* path with 45 extra bytes */
#define PARMLEN 255 /* arbitrary maximum parm len@P1C*/
#define USPARMLEN 255 /* arbitrary max user parm len */
#define MINPQTSO 4 /* minimum parameters for QTSO */
#define MAXPQTSO 5 /* maximum parameters for QTSO */
#define MINPTSO 3 /* minimum parameters for TSO */
#define MAXPTSO 5 /* maximum parameters for TSO */
#define MINPAGENT 4 /* minimum parameters for AGENT */
#define MAXPAGENT 9 /* maximum parameters for AGENT */
#define MINPSTART 4 /* minimum parameters for START */
#define MAXPSTART 4 /* maximum parameters for START */
#define MINPFF 2 /* minimum parameters for FF */
#define MAXPFF 3 /* maximum parameters for FF */
/*-------------------------------------------------------------------------
-- LOCAL FUNCTION DECLARATIONS
--------------------------------------------------------------------------*/
int SpecialOptions(int index, int argc, char* argv[]);
int CheckRange(int min, int max, int argc, char uarg[PARMLEN]);
VOID DumpBuffer(PDDMOBJECT pAttribute, USHORT Count);
CODEPOINT ReplyMsg(VOID);
VOID OmitError(VOID);
VOID GeneralError(VOID);
VOID ValueError(char *value);
VOID ParmLenError(char *value);
int strupper(char *out, char *in, int bufflen);
VOID DisplayBuffer(ULONG count, PDDMRECORD pRcdarea);
VOID DuplicateError(VOID);
VOID HasFileNameError(VOID);
VOID NoFileNameError(VOID);
VOID TooManyError(VOID);
VOID NotEnoughError(VOID);
VOID DisplayHelp(char *helpflag);
/*-------------------------------------------------------------------------
-- DFMACALL
--------------------------------------------------------------------------*/
int dummy_filename = 0; /* Dummy filename flag */
int display_filename = 0; /* Display filename flag */
int TSO_retry = 0; /* TSO error retry flag */
int debug = 1; /* Debug flag: 0 = nothing displayed,*/
/* 1 = filename display, 2 = all of */
/* the above plus major functions, */
/* 5 = all the above plus data. */
int display_counter = 0; /* Record display counter */
int intrc; /* internal return code */
main(int argc, char* argv[])
{
int i; /* Loop counter */
int fnlen = 0; /* Filename length */
int pgmcnt = 0; /* Number of PGM parm occurrences */
int parmcnt = 0; /* Number of PARM parm occurrences */
int data_follows; /* Data follows in next arg */
APIRET SevCode; /* Severity code (see DUBDEFS.H) */
CODEPOINT LCodePoint; /* Local Code Point for reply msg */
PDDMRECORD pRecord;
RECLENGTH RecordSize;
PDDMRECAL pRecAL;
PDDMRECALK pRecALK;
RECLENGTH RecALSize;
PBYTE pData;
HDDMLOAD UnLoad; /* File handle for unload */
ULONG RecCount;
ULONG DDMMoreDataFlag;
int minparms; /* minimum parameters current cmd */
int maxparms; /* maximum parameters current cmd */
HDDMFILE FileHandle;
/* Filename to be operated on */
CHAR MVSFilename[PATHLEN];
CHAR RootName[PATHLEN]; /* Root name for TSO retry */
CHAR dummy_name[9] = "NULLFILE";
CHAR display_name[PATHLEN];
CHAR uarg[PARMLEN]; /* Upper case argument */
CHAR usparg[USPARMLEN]; /* Upper case subparameter */
/******************************************************************/
/* Determine which command format was used and build the MVS */
/* filename and filename suffix accordingly. */
/******************************************************************/
RootName[0] = 0; /* Set TSO root name to null string*/
switch (argc)
{ case 1: /* no user arguments */
NotEnoughError();
DisplayHelp("N");
return(SC_SEVERE);
default:
/*************************************************************/
/* 1 or more user arguments--check further */
/*************************************************************/
/* Convert current user argument to upper case. */
if (intrc = strupper(uarg, argv[1], PATHLEN))
return intrc;
if (strcmp(uarg,"QTSO") == 0 |
strcmp(uarg,"TSO") == 0 ) {
if (strcmp(uarg,"QTSO") == 0) {
/******************************************************/
/* QTSO format */
/******************************************************/
minparms = MINPQTSO;
maxparms = MAXPQTSO;
}
else {
/******************************************************/
/* TSO format */
/******************************************************/
minparms = MINPTSO;
maxparms = MAXPTSO;
}
if (intrc = CheckRange(minparms,maxparms,argc, uarg) > 0)
return(intrc);
/********************************************************/
/* Set special processing flags */
/********************************************************/
for (i=minparms; i < argc; i++) {
if (intrc = SpecialOptions(i, argc, argv) > 0)
return(intrc);
}
/********************************************************/
/* Build filename in the format of */
/* x:fn,agent(dfmqtso,u=userID),pgm(dfmqtso), */
/* parm(...) */
/* -- OR -- */
/* x:fn,agent(dfmxtso,u=userID),pgm(ikjeft01), */
/* parm(...) */
/* (Note that MVS will append u=userid) */
/********************************************************/
if (intrc = strupper(MVSFilename,argv[2],PATHLEN))
return(intrc);
fnlen = strlen(MVSFilename); /* Save true filename len */
if ( fnlen > 2 | strncmp(&MVSFilename[1],":",1) != 0 ) {
HasFileNameError();
DisplayHelp(&uarg[0]);
return(SC_SEVERE);
}
/********************************************************/
/* Build root filename. */
/********************************************************/
if (display_filename) {
if (strcmp(uarg,"QTSO") == 0)
strcat(MVSFilename,"DFMQTSO.SYSTSPRT");
else
strcat(MVSFilename,"DFMXTSO.SYSTSPRT");
strcpy(RootName,MVSFilename);
} else {
dummy_filename = 1;
strcat(MVSFilename,dummy_name);
} /* endif */
/********************************************************/
/* Attach filename suffix. */
/********************************************************/
if (strcmp(uarg,"QTSO") == 0)
strcat(MVSFilename,",agent(dfmqtso),parm(");
else
strcat(MVSFilename,",agent(dfmxtso),pgm(ikjeft01),parm(");
/********************************************************/
/* Concatenate parm field */
/********************************************************/
if (argc >= 4 ) {
if (intrc = strupper(usparg, argv[3], USPARMLEN))
return (intrc);
if (strcmp(usparg,"DISPLAY") != 0)
strcat(MVSFilename,argv[3]);
else if (strcmp(uarg,"QTSO") == 0) {
/* DFMQTSO requires a parameter field */
OmitError();
DisplayHelp(&uarg[0]);
return(SC_SEVERE);
}
}
strcat(MVSFilename,")"); /* Terminate parameter field */
} /* End of QTSO/TSO case */
else if (strcmp(uarg,"AGENT") == 0) {
/********************************************************/
/* AGENT format */
/********************************************************/
minparms = MINPAGENT;
maxparms = MAXPAGENT;
if (intrc = CheckRange(minparms,maxparms,argc, uarg) > 0)
return(intrc);
/********************************************************/
/* Set special processing flags */
/********************************************************/
for (i=minparms; i < argc; i++) {
if (intrc = SpecialOptions(i, argc, argv) > 0)
return(intrc);
}
/********************************************************/
/* Build filename in the format of */
/* x:fn,agent(agentname),pgm(program_name),parm(parms) */
/********************************************************/
if (intrc = strupper(MVSFilename,argv[2], PATHLEN))
return(intrc);
fnlen = strlen(MVSFilename); /* Save true filename len */
/* Add dummy filename if one wasn't specified */
if ( fnlen == 2 & strncmp(&MVSFilename[1],":",1) == 0 ) {
dummy_filename = 1;
strcat(MVSFilename,dummy_name);
}
/* Check the filename format for obvious errors. */
fnlen = strlen(MVSFilename); /* Save true filename len */
if (fnlen < 3 ) {
NoFileNameError();
DisplayHelp(&uarg[0]);
return(SC_SEVERE);
}
strcat(MVSFilename,",agent(");
strcat(MVSFilename,argv[3]);
strcat(MVSFilename,")");
/********************************************************/
/* Concatenate optional fields */
/********************************************************/
if (argc > 4) {
/******************************************************/
/* Optional parameters are present */
/******************************************************/
/******************************************************/
/* All but DISPLAY are in format of keyword + value. */
/******************************************************/
data_follows = 0;
for (i=4; i < argc; i++) {
if (!data_follows) {
/* Not data object -- process the keyword. */
data_follows = 1;
if (intrc = strupper(usparg, argv[i], USPARMLEN))
return (intrc);
if (strcmp(usparg,"PGM") == 0) {
pgmcnt++;
strcat(MVSFilename,",pgm(");
}
else if (strcmp(usparg,"PARM") == 0) {
parmcnt++;
strcat(MVSFilename,",parm(");
}
else { /* Unidentified keyword?*/
/* Make sure it's not a display option */
if (strcmp(usparg,"DISPLAY") != 0 ) {
GeneralError();
DisplayHelp(&uarg[0]);
return(SC_SEVERE);
}
else
data_follows = 0; /* No following data */
} /* End, unidentified kwd*/
} /* End, even number */
else {
/* Process the keyword's data. */
data_follows = 0;
strcat(MVSFilename,argv[i]);
strcat(MVSFilename,")");
} /* End, data field */
} /* End of for loop */
}
/********************************************************/
/* Ensure no duplicate parameters */
/********************************************************/
if ( pgmcnt > 1 | parmcnt > 1 ) {
DuplicateError();
DisplayHelp(&uarg[0]);
return(SC_SEVERE);
}
/********************************************************/
/* Ensure AGENT is invoked with a PARM */
/********************************************************/
if (parmcnt == 0)
strcat(MVSFilename,",parm()");
} /* End of AGENT */
else if (strcmp(uarg,"START") == 0) {
/********************************************************/
/* START format */
/********************************************************/
minparms = MINPSTART;
maxparms = MAXPSTART;
if (intrc = CheckRange(minparms,maxparms,argc, uarg) > 0)
return(intrc);
/********************************************************/
/* Build filename in the format of */
/* x:fn,start(proc,parms) */
/********************************************************/
if (intrc = strupper(MVSFilename,argv[2],PATHLEN))
return(intrc);
fnlen = strlen(MVSFilename);
if ( (fnlen > 2) | (strncmp(&MVSFilename[1],":",1) != 0) ) {
HasFileNameError();
DisplayHelp(&uarg[0]);
return(SC_SEVERE);
}
dummy_filename = 1;
strcat(MVSFilename,dummy_name);
strcat(MVSFilename,",start(");
strcat(MVSFilename,argv[3]);
strcat(MVSFilename,")");
} /* End of START parameter */
else { /* None of the above */
/********************************************************/
/* Free-form command otherwise */
/********************************************************/
/********************************************************/
/* Check for help request. */
/********************************************************/
if (strncmp(uarg, "?",1) == 0) {
DisplayHelp(&uarg[0]);
return(SC_WARNING);
}
minparms = MINPFF;
maxparms = MAXPFF;
if (intrc = CheckRange(minparms,maxparms,argc, uarg) > 0)
return(intrc);
/********************************************************/
/* Set special processing flags */
/********************************************************/
for (i=minparms; i < argc; i++) {
if (intrc = SpecialOptions(i, argc, argv) > 0)
return(intrc);
}
if (intrc = strupper(MVSFilename,argv[1], PATHLEN))
return(intrc);
fnlen = strlen(MVSFilename); /* Save true filename len */
if (fnlen < 3) {
NoFileNameError();
DisplayHelp(&uarg[0]);
return(SC_SEVERE);
}
} /* End of free form parameters */
}
/******************************************************************/
/* Begin processing the MVS file @P2M*/
/******************************************************************/
if (debug >= 1) printf
("DFMACALL: Processing filename and filename suffix of %s.\n",
MVSFilename);
/****************************************************************/
/* Open the file @P2M*/
/****************************************************************/
SevCode = DDMOpen
(MVSFilename, /* FileName @P2M*/
&FileHandle, /* FileHandle @P2M*/
RELRNBAM, /* AccessMethod @P2M*/
DDM_GETAI, /* AccIntList @P2M*/
DDM_UPDATERS, /* FileShare @P2M*/
NULL, /* EABuf @P2M*/
NULL /* reserved @P2M*/
); /* @P2M*/
if (SevCode != SC_NO_ERROR) /* @P2M*/
{ /* @P2M*/
if (dummy_filename == 0) /* @P2M*/
{ /* @P2M*/
printf("Error opening file %s\n",MVSFilename); /* @P2M*/
printf("Severity code = %u\n",SevCode); /* @P2M*/
} /* @P2M*/
ReplyMsg(); /* @P2M*/
return(SevCode); /* @P2M*/
} /* @P2M*/
/****************************************************************/
/* Close the file @P2M*/
/****************************************************************/
SevCode = DDMClose /* @P2M*/
(FileHandle /* FileHandle @P2M*/
); /* @P2M*/
if (SevCode != SC_NO_ERROR) /* @P2M*/
{ /* @P2M*/
if (dummy_filename == 0) /* @P2M*/
{ /* @P2M*/
printf("Error closing file %s\n",MVSFilename); /* @P2M*/
printf("Severity code = %u\n",SevCode); /* @P2M*/
} /* @P2M*/
ReplyMsg(); /* @P2M*/
return(SevCode); /* @P2M*/
} /* @P2M*/
if (display_filename) {
/****************************************************************/
/* Perform unload of records to satisfy display request */
/****************************************************************/
/****************************************************************/
/* Allocate a record buffer */
/****************************************************************/
RecALSize = 64000; /* Try to use a 64K Buffer for records*/
if ((pRecord = (PDDMRECORD)malloc(RecALSize)) == NULL) {
/* Not enough storage--make one last try for 32K */
RecALSize = RecALSize / 2; /* Try 32K Buffer */
if ((pRecord = (PDDMRECORD)malloc(RecALSize)) == NULL) {
printf("DFMACALL: Out of memory\n");
return(SC_SEVERE);
}
}
/****************************************************************/
/* Unload the first batch of records in rcd number order */
/****************************************************************/
SevCode = 1;
while (SevCode) {
SevCode = DDMUnLoadFileFirst
(MVSFilename, /* FileName */
&UnLoad, /* UnLoadHandle */
0UL, /* AccessFlags */
&DDMMoreDataFlag, /* Flags */
pRecord, /* RecordBuf */
RecALSize, /* RecordBufLen */
(CODEPOINT) RECSEQ, /* UnloadOrder=rcd number */
&RecCount /* RecCount */
);
if (SevCode > SC_WARNING) {
printf("DFMACALL: Error on DDMUnLoadFileFirst for %s.\n",
MVSFilename);
printf("Severity code = %u\n",SevCode);
LCodePoint = ReplyMsg();
/* Retry TSO unload output file if not tried already. */
if (strcmp(MVSFilename,RootName) != 0 &
LCodePoint == VALNSPRM ) {
TSO_retry = 1;
strcpy(MVSFilename,RootName);
} /* End, TSO retry */
else { /* Permanent error */
free(pRecord);
return(SevCode);
} /* End, permanent error */
} /* End of error from unload file first. */
} /* End of while no error. */
if (SevCode > SC_WARNING) {
free(pRecord);
return(SevCode);
} /* End, unload first err */
if (debug >= 2 )
printf ("DDMUnLoadFileFirst: %d records in buffer.\n",
RecCount);
if (TSO_retry > 0 ) {
printf ("\n** The TSO Output File associated with the error is\
as follows: **\n");
printf ("** (Note that its contents may be from a previou\
s run.) **\n");
}
DisplayBuffer(RecCount,pRecord);
/****************************************************************/
/* Unload remaining records in record number order. */
/* When DDMMoreDataFlag is 0x00UL then the file handle is */
/* invalid and the file will be closed. */
/****************************************************************/
while (DDMMoreDataFlag == 0x01UL)
{
SevCode = DDMUnLoadFileNext
(UnLoad, /* UnLoadHandle */
0x0000UL, /* Flags */
&DDMMoreDataFlag, /* UnloadFlags */
pRecord, /* RecordBuf */
RecALSize, /* RecordBufLen */
&RecCount /* RecCount */
);
if (SevCode > SC_WARNING) {
printf("DFMACALL: Error on DDMUnLoadFileNext for %s.\n",
MVSFilename);
printf("Severity code = %u\n",SevCode);
ReplyMsg();
free(pRecord);
return(SevCode);
}
if (debug >= 2)
printf ("DDMUnLoadFileNext: %d records in buffer.\n",
RecCount);
DisplayBuffer(RecCount,pRecord);
} /* End of WHILE loop */
free(pRecord);
} else {
/****************************************************************/
/* No display--just open to trigger DataAgent and then close */
/****************************************************************/
}
return(SC_NO_ERROR);
} /* End--sample main */
/**************************************************************************
**************************** ReplyMsg ***********************************
***************************************************************************
* Process the reply message if there is a Severity Code other than
* SC_NO_ERROR;
*
***************************************************************************/
CODEPOINT ReplyMsg(VOID)
{
static BYTE pRpyMsgBuf[RPYMSBFLN];
APIRET rc;
CODEPOINT CodePoint;
PDDMOBJECT pReplyObject;
USHORT index;
/*---------------------------------------------------------------------
-- The following table contains the count for the number of parameters
-- expected for each reply message (1st column), and it also contains
-- the expanded error messages
--
-- The first message in the table, KEYUDIRM, has the lowest
-- code point value. It is also the first message in a block of
-- message code points that ends with RECNAVRM.
--
-- The next block of message code points (in ascending code point order)
-- begins with OS2ERRRM and ends with FILERRRM.
-- The low-order byte is used as the index into this block.
----------------------------------------------------------------------*/
static struct
{ USHORT Count;
BYTE msg[52];
} ErrorMsgBuffer[] =
{ 6, "Key Update Not Allowed by Different Index \0",
0, " \0",
3, "System Command Reply Message \0", /* SYSCMDRM */ /*@P3C*/
0, "Default Record Error \0",
5, "Cursor Not Selecting a Record Position \0",
7, "Invalid Data Record \0",
3, "Duplicate File Name \0",
8, "Duplicate Key Different Index \0",
7, "Duplicate Key Same Index \0",
7, "Duplicate Record Number \0",
3, "End of File \0",
7, "File is Full \0",
4, "File in Use \0",
3, "File Not Found \0",
6, "File Space Not Available \0",
3, "Manager Level Conflict \0", /* MGRLVLRM */ /*@P3C*/
4, "File Not Opened \0", /* FILNOPRM */ /*@P3C*/
3, "Invalid File Name \0",
0, " \0",
3, "Shadow Exists \0", /* SHDEXSRM */ /*@P3C*/
7, "Record Length Mismatch \0",
3, "Storage Class Not Found \0", /* STGNFNRM */ /*@P3C*/
3, "Management Class Not Found \0", /* MGMNFNRM */ /*@P3C*/
4, "Manager Dependency Error \0", /* MGRDEPRM */ /*@P3C*/
0, " \0",
3, "Not Authorized to Storage Class \0", /* STGATHRM */ /*@P3C*/
3, "Not Authorized to Management Class \0", /* MGMATHRM */ /*@P3C*/
2, "Not Authorized to Function \0",
4, "File Open Lock Option Changed \0", /* FILOLORM */ /*@P3C*/
4, "File Temporarily Not Available \0",
0, " \0",
2, "Declare Conflict \0", /* DCLCNFRM */ /*@P3C*/
3, "Directory is Temporarily Not Available \0", /* DRCTNARM */ /*@P3C*/
0, " \0",
0, " \0",
7, "Record Number Out of Bounds \0",
5, "Record Not Found \0",
0, " \0",
0, " \0",
0, " \0",
0, " \0",
0, " \0",
0, " \0",
3, "Data Class Not Found \0", /* DTANFNRM */ /*@P3C*/
3, "Invalid Key Length \0",
0, " \0",
0, " \0",
3, "Not Authorized to Access Method \0",
0, "Invalid Access Method \0",
3, "Permanent Agent Error \0",
6, "Resource Limits Reached on Target System \0",
3, "Invalid Base File Name \0",
0, " \0",
0, " \0",
2, "Not Authorized to Directory \0",
0, "Management Class Conflict \0",
0, "Storage Class Conflict \0",
3, "Existing Condition \0",
4, "Not Authorized to File \0",
6, "Invalid Request \0",
4, "Invalid Key Definition \0",
0, " \0",
5, "Key Update Not Allowed by Same Index \0",
8, "Invalid Key Value \0",
3, "Invalid User \0", /* INVUSRRM */ /*@P3C*/
3, "Open Conflict Error \0", /* OPNCNFRM */ /*@P3C*/
3, "Open Exclusive by Same User \0",
4, "Concurrent Open Exceeds Maximum \0",
4, "Conversational Protocol Error \0",
0, " \0",
0, " \0",
0, " \0",
7, "Record Damaged \0",
7, "Record in Use \0",
2, "Command Processing Completed \0", /* CMDCMPRM */ /*@P3C*/
5, "Data Stream Syntax Error \0",
7, "Update Cursor Error \0",
5, "No Update Intent on Record \0",
3, "Invalid New File Name \0",
3, "Function Not Supported \0",
3, "Parameter Not Supported \0",
4, "Parameter Value Not Supported \0",
4, "Object Not Supported \0",
5, "Command Check \0",
2, "Duplicate Declared Name \0", /* DUPDCLRM */ /*@P3C*/
2, "Invalid Declared Name \0", /* DCLNAMRM */ /*@P3C*/
2, "File Handle Not Found \0",
3, "Directory Full \0",
3, "Record Inactive \0",
7, "File Damaged \0",
4, "Load Records Count Mismatch \0",
3, "Not Authorized to Open Intent for Named File \0",
5, "User Attribute Error \0", /* USRATTRM */ /*@P3C*/
3, "File Closed with Damage \0",
2, "Target Not Supported \0",
5, "Key Value Modified after Cursor was Last Set \0",
4, "Change File Attributes Rejected \0", /* CHGFATRM */ /*@P3C*/
3, "Invalid Directory Name \0", /* DRCNAMRM */ /*@P3C*/
3, "Directory Not Found \0", /* DRCNFNRM */ /*@P3C*/
5, "Stream In Use Error \0", /* STRIUSRM */ /*@P3C*/
7, "Invalid Substream \0", /* SUBSTRRM */ /*@P3C*/
0, "Access Intent List Error \0",
3, "Directory In Use \0", /* DRCIUSRM */ /*@P3C*/
7, "Stream Damaged \0", /* STRDMGRM */ /*@P3C*/
3, "Invalid Directory Entry \0", /* DRCENTRM */ /*@P3C*/
3, "Duplicate Directory Name \0", /* DUPDRCRM */ /*@P3C*/
3, "Directory Space Not Available \0", /* DRCSNARM */ /*@P3C*/
7, "Data Mapping Error \0", /* DTAMAPRM */ /*@P3C*/
0, " \0",
4, "Load Stream Count Mismatch \0", /* LODSTRRM */ /*@P3C*/
5, "Record Not Available \0",
/************ START OF SECOND CODE POINT RANGE *************/
0, "OS/2 Error \0",
0, "Data Description File Not Found \0",
0, "Conversion Table Not Found \0",
2, "Translation Error \0",
0, " \0",
2, "Invalid Flag \0",
0, " \0",
2, "Communications Error \0",
0, " \0",
0, " \0",
0, " \0",
0, " \0",
0, " \0",
0, " \0",
0, " \0",
0, " \0",
2, "Resource Limit Reached in OS/2 V2.0 Source System \0",
2, "Field Length Error \0",
2, "Address Error \0",
0, " \0",
2, "Function Continuation Error \0",
0, " \0",
2, "File Error \0"
};
/*---------------------------------------------------------------------
-- For each reply message available, retrieve and display it.
----------------------------------------------------------------------*/
do
{ /*------------------------------------------------------------------
-- Get the reply message
-------------------------------------------------------------------*/
rc = DDMGetReplyMessage(pRpyMsgBuf, (ULONG)RPYMSBFLN, (ULONG)1);
switch (rc)
{ case SC_NO_ERROR: /* All reply messages have been received */
case SC_WARNING: /* There are more reply messages to be received*/
break;
case SC_ERROR:
printf(" ReplyMsg: reply message buffer is too small -\n");
printf(" enlarge and recompile ...\n");
return(rc);
break;
case SC_SEVERE:
printf(" ReplyMsg: Warning: A reply message was requested,\n");
printf(" but there are none available ...\n");
return(rc);
break;
case SC_ACCESSDAMAGE:
printf(" ReplyMsg: Error: An invalid reply message buffer\n");
printf(" address was specified ...\n");
return(rc);
break;
case SC_PERMDAMAGE:
printf(" ReplyMsg: Severe Error: An unarchitected reply message\n");
printf(" object was encountered ...\n");
return(rc);
break;
default:
printf(" ReplyMsg: Unknown return code from DDMGetReplyMessage\n");
return(rc);
break;
} /* endswitch */
/*------------------------------------------------------------------
-- Get the reply message
-------------------------------------------------------------------*/
pReplyObject = (PDDMOBJECT)pRpyMsgBuf;
CodePoint = pReplyObject->cpObject; /* get code point */
/* reset pointer to first parm base */
pReplyObject = (PDDMOBJECT)((PBYTE)pReplyObject
+ (sizeof(CODEPOINT)
+ sizeof(OBJLENGTH))
);
/*------------------------------------------------------------------
-- Calculate the index into the parameter/msg table based on
-- the codepoint.
-------------------------------------------------------------------*/
if (CodePoint <= RECNAVRM) /* if code point in first block */
index = (USHORT)(CodePoint - KEYUDIRM);
else /* code point in second block */
index = (USHORT)
((RECNAVRM - KEYUDIRM + 1) /* number of entries in
first block */
+ (CodePoint % 0x0100UL) /* index into second block */
);
/* If the index indicates "file not found" and a dummy filename */
/* is being used, ignore the error. */
if (index == 13 & dummy_filename == 1 )
return(SC_NO_ERROR);
/*------------------------------------------------------------------
-- Begin dissecting the reply message buffer
-------------------------------------------------------------------*/
if (ErrorMsgBuffer[index].Count > 0)
{ printf("RPYMSG: %s\n",ErrorMsgBuffer[index].msg);
DumpBuffer(pReplyObject, ErrorMsgBuffer[index].Count);
printf("\n");
}
} while (rc == SC_WARNING); /* enddo */
return(CodePoint);
} /* ReplyMsg */
/**************************************************************************
************************** DumpBuffer ***********************************
***************************************************************************
*
* For each object in the reply message buffer, print out its contents.
*
***************************************************************************/
VOID DumpBuffer(PDDMOBJECT pAttribute,
USHORT Count)
{
int i; /* Local loop counter */
do
{ if (pAttribute->cbObject == (sizeof(CODEPOINT) + sizeof(OBJLENGTH)))
{ printf("Null object returned = %x\n",pAttribute->cbObject);
pAttribute->cpObject = 0;
}
else
{ switch(pAttribute->cpObject)
{ case ACCMTHCL: /* Access Method Class */
printf("ACCMTHCL = 0x%X\n", *(PCODEPOINT)(pAttribute->pData));
break;
case BASFILNM: /* Base File Name */
printf("BASFILNM = %s\n", pAttribute->pData);
break;
case CODPNT: /* Code Point */
printf("CODPNT = 0x%X\n", *(PCODEPOINT)(pAttribute->pData));
break;
case CSRPOSST: /* Cursor Position Status */
printf("CSRPOSST = 0x%hX\n", *(PBYTE)(pAttribute->pData));
break;
case DTALCKST: /* Data Lock Status */
printf("DTALCKST = 0x%hX\n", *(PBYTE)(pAttribute->pData));
break;
case ERRFILNM: /* Error File Name */
printf("ERRFILNM = %s\n", pAttribute->pData);
break;
case FILNAM: /* File Name */
printf("FILNAM = %s\n", pAttribute->pData);
break;
case KEYDEFCD: /* Key Definition Error Code */
printf("KEYDEFCD = 0x%hX\n", *(PBYTE)(pAttribute->pData));
break;
case MAXOPN: /* Maximum Number of File Extents
Concurrent Opens Allowed */
printf("MAXOPN = %d\n", *(PUSHORT)(pAttribute->pData));
break;
case NEWFILNM: /* New File Name */
printf("NEWFILNM = %s\n", pAttribute->pData);
break;
case PRCCNVCD: /* Conversational Protocol Error Code */
printf("PRCCNVCD = 0x%hX\n", *(PBYTE)(pAttribute->pData));
break;
case RECCNT: /* Record Count */
printf("RECCNT = %ld\n", *(PULONG)(pAttribute->pData));
break;
case RECNBR: /* Record Number */
printf("RECNBR = %ld\n", *(PRECNUM)(pAttribute->pData));
break;
case SRVDGN: { /* Server Diagnostic Information */
printf("SRVDGN = 0x\n");
for (i=1; i < (pAttribute->cbObject-5); i++) /* 2 byte len, 2 byte codept*/
{ if (i % 16 ==0)
printf("%02X\n", *(PBYTE)(pAttribute->pData+i-1));
else
if (i % 4 ==0)
printf("%02X ", *(PBYTE)(pAttribute->pData+i-1));
else
printf("%02X", *(PBYTE)(pAttribute->pData+i-1));
}
}
break;
case SVRCOD: /* Severity Code */
printf("SVRCOD = 0x%X\n", *(PCODEPOINT)(pAttribute->pData));
break;
case SYNERRCD: /* Syntax Error Code */
printf("SYNERRCD = 0x%hX\n", *(PBYTE)(pAttribute->pData));
break;
default:
printf("Unknown code point - 0x%X\n",
*(PCODEPOINT)(pAttribute->pData));
break;
} /* endswitch */
} /* endif */
/* go to next object */
pAttribute = (PDDMOBJECT)((PBYTE)pAttribute + pAttribute->cbObject);
} while(--Count > 0);
} /* DumpBuffer */
/**************************************************************************
**************************** Error Routines ******************************
**************************************************************************/
VOID GeneralError()
{
printf("DFMACALL: Incorrect command line syntax.\n");
} /* GeneralError */
VOID OmitError()
{
printf("DFMACALL: A required parameter was omitted.\n");
}
VOID TooManyError()
{
printf("DFMACALL: Too many parameters were on the command line.\n");
}
VOID NotEnoughError()
{
printf("DFMACALL: Not enough parameters were on the command line.\n");
}
VOID HasFileNameError()
{
printf("DFMACALL: Filename is not allowed for QTSO, TSO, or START.\n");
}
VOID NoFileNameError()
{
printf("DFMACALL: A filename must be specified.\n");
}
VOID ValueError(char *value)
{
printf("DFMACALL: Incorrect parameter value %s.\n",value);
}
VOID ParmLenError(char *value)
{
printf("DFMACALL: Parameter %s is too long.\n",value);
}
int strupper(char *oarg, char *iarg, int bufflen)
{
/* Convert string to upper case. */
int i;
if (strlen(iarg) > bufflen) {
ParmLenError(iarg);
return(SC_SEVERE);
}
for (i=0; i < strlen(iarg); i++) {
oarg[i] = toupper(iarg[i]);
}
oarg[i] = 0;
return (0);
}
VOID DuplicateError()
{
printf("DFMACALL: One or more parameters were duplicated.\n");
}
VOID DisplayBuffer(ULONG count, PDDMRECORD pCurrentRecord)
{
/* Display a buffer full of records */
ULONG i; /* record counter */
int j; /* index to character in record */
int cRecLen; /* current record length */
UCHAR c; /* current converted character */
UCHAR savechar; /* savearea for trailing character */
for (i=1; i <= count; i++) {
cRecLen = pCurrentRecord->cbRecord - sizeof(pCurrentRecord->cbRecord)
- sizeof(pCurrentRecord->cpRecord);
/*******************************************************************/
/* Replace all instances of non-printable characters, */
/*******************************************************************/
/* Make sure the string is printable and */
/* make sure that there is no 0 in the middle of string. */
for (j=0; j < cRecLen; j++) {
if (!(c = pCurrentRecord->pRecord[j]))
pCurrentRecord->pRecord[j] = ' '; /* Replace x00 with blank */
else if (!isprint(c))
pCurrentRecord->pRecord[j] = '.'; /* Make nonprintable a "." */
} /* End of for j= loop */
savechar = pCurrentRecord->pRecord[cRecLen]; /* save trailing char */
pCurrentRecord->pRecord[cRecLen] = '\0';
if (debug >= 5) {
display_counter++;
printf ("Displaying record %d with length %d:\n",
display_counter,cRecLen);
}
printf ("%s\n",pCurrentRecord->pRecord);
pCurrentRecord->pRecord[cRecLen] = savechar; /* restore trailing */
pCurrentRecord = (PDDMRECORD) (pCurrentRecord->pRecord + cRecLen);
}
}
SpecialOptions(int index, int argc, char *argv[])
{
CHAR uarg[PARMLEN]; /* Upper case argument */
/* Check for special processing options. */
if (intrc = strupper(uarg, argv[index], PARMLEN))
return(intrc);
if (strcmp(uarg,"DISPLAY") == 0)
display_filename = 1;
return(0);
} /* End of SpecialOptions */
CheckRange(int minparms, int maxparms, int argc, char uarg[PARMLEN])
{
/* Ensure number of parameters is reasonable for the command */
/********************************************************/
/* Ensure enough parameters */
/********************************************************/
if (argc < minparms) {
NotEnoughError();
DisplayHelp(&uarg[0]);
return(SC_SEVERE);
}
/********************************************************/
/* Ensure no leftover parameters */
/********************************************************/
if (argc > maxparms) {
TooManyError();
DisplayHelp(&uarg[0]);
return(SC_SEVERE);
}
return(0);
}
/**********************************************************************
**************************** DisplayHelp *****************************
***********************************************************************
* Display the correct syntax for invoking this function.
*
**********************************************************************/
VOID DisplayHelp(char *fullhelp)
{
if (strncmp(fullhelp,"?",1) == 0) {
/* Print full help text. */
printf("Correct syntax: \n\n");
printf(" DFMACALL QTSO driveletter: TSOcommandline [DISPLAY] \n");
printf(" DFMACALL TSO driveletter: [TSOcommandline] [DISPLAY] \n");
printf(" DFMACALL AGENT driveletter:[filename] MVSproc[,proc_parms] \n");
printf(" [PGM prog_name] [PARM prog_parms] [DISPLAY] \n");
printf(" DFMACALL START driveletter: MVSproc[,proc_parms] \n");
printf(" DFMACALL driveletter:filename[,filename_suffix] [DISPLAY] \n\n");
printf(" Examples: \n\n");
printf(" dfmacall qtso s: listc display \n");
printf(" dfmacall tso s: display \n");
printf(" dfmacall agent r:ibmuser.a.b dfmxagnt \n");
printf(" dfmacall agent r:ibmuser.a.b dfmxtso \n");
printf(" pgm ikjeft01 parm listc \n");
printf(" dfmacall start s: dfmx0001,dfminit=iefbr14 \n");
printf(" dfmacall r:ibmuser.a.b,agent(dfmxagnt),parm(hello) \n");
printf(" dfmacall r:ibmuser.a.b,agent(dfmx0001),pgm(dfmxagnt)\n\n");
}
else {
/* Print clue for getting correct help text. */
printf("DFMACALL: Enter DFMACALL ? to get the correct command syntax. \n\n");
}
}