/*-------------------------------------------------------------------+
| Copyright (c) 1996, SAS Institute Inc. |
| Unpublished - All Rights Reserved |
| S A S / C S A M P L E |
| |
| NAME: TRYRACF |
| LANGUAGE: C |
| PURPOSE: Illustrate issuing a MVS RACROUTE call from |
| a C program. |
| INPUT/OUTPUT: Output is the return code from several RACROUTE |
| calls with different access for a dataset. |
| MVS - |
| COMPILE, LINK, EXECUTE: SUBMIT prefix.SAMPLE.AUX(TRYRACF) |
| where "prefix" is the installation defined high-level|
| qualifier for the SAS/C product. Supplied header |
| files "ihadva.h", "camlst.h", and "racf.h" must |
| be available. |
| TSO - |
| COMPILE: LC370 CLIST |
| LINK: CLK370 CLIST |
| EXECUTE: CALL your.load.lib(TRYRACF) |
+-------------------------------------------------------------------*/
#include <stdio.h>
#include <lcstring.h>
#include <svc.h>
#include <code.h>
#include <genl370.h>
#include "ihadva.h"
#include "camlst.h"
#include "racf.h"
/* The chain macro is used to reference a chain field */
/* in a control block. p addresses the control block, */
/* o is the character offset of the field */
#define chain(p,o) (void **) *((void **)(p)+(o)/4)
void main()
{
#define READ_ACCESS ACHKTRD /* define some handy constants */
#define UPDATE_ACCESS ACHKTUPD /* that are more readable */
#define CONTROL_ACCESS ACHKTCTL
#define ALTER_ACCESS ACHKTALT
int rc;
rc = racroute("SASC.SAMPLE.C", READ_ACCESS);
printf("racroute return code is %d\n", rc);
rc = racroute("SASC.SAMPLE.C", UPDATE_ACCESS);
printf("racroute return code is %d\n", rc);
rc = racroute("SASC.SAMPLE.C", CONTROL_ACCESS);
printf("racroute return code is %d\n", rc);
rc = racroute("SASC.SAMPLE.C", ALTER_ACCESS);
printf("racroute return code is %d\n", rc);
}
/*-------------------------------------------------------------------
* USAGE: <=== rc = racroute(dsname, mode);
* PURPOSE: <=== To issue a racroute call for a dataset
*
* ARGUMENTS: <===
* -ARG- -DCL--------- -DESCRIPTION-
* dsname char * null-terminated data set name
* mode int desired access mode
*
* RETURNS: <===
* rc int 0 access permitted
* <0 complement of locate return code
* 4 SAF router not active
* 8 desired access not permitted
*
*-----------------------------------------------------------------*/
int racroute(char *input_dsname, int mode)
{
struct { /* racroute class parameter */
char dslen; /* class name length */
char dsn[8]; /* class name proper */
} class = {'\07', "DATASET "};
struct { /* MVS router parm list */
struct SAFP safp;
struct ACHKLIST achklist;
} parm_list = {0, /* return code */
0, /* reason code */
sizeof(struct SAFP), /* safp parm list length */
0, /* reserved */
SAFPAU, /* request type (racheck) */
0, /* reserved */
NULL, /* request name address */
NULL, /* subsystem name address */
NULL, /* pointer to 512-byte work area*/
0, /* reserved */
0, /* reserved */
sizeof(struct SAFP), /* offset to RACF parm list */
sizeof(struct ACHKLIST), /* parm list length */
"\0\0\0", /* installation data address */
ACHK31IN, /* first flag byte */
"\0\0\0", /* entity name address */
ACHKTRD, /* second flag byte */
"\0\0\0", /* classs name address */
NULL, /* volser address word */
NULL, /* old volser address */
NULL, /* appl name address */
NULL, /* ACEE address */
NULL, /* owner address */
NULL, /* 31-bit installation data addr*/
NULL, /* entityx name address */
NULL, /* class name address */
NULL, /* volser address */
NULL, /* access value address */
NULL}; /* second access address */
struct VOLIST volist;
struct LOCATE locate;
int rc;
void *cvtptr; /* pointer to the CVT */
#define CVTSAF 0xf8
void *safvt; /* ptr to the SAF Vector Table */
#define SAFVSAFR 0xc
void *saf_router; /* ptr to the SAF router routine*/
char worka[512]; /* SAF work area */
char full_dsname[44]; /* blank-padded data set name */
/* initialize locate parmlist */
memset((char *) &locate, '\0', sizeof(locate));
memset((char *) &volist, '\0', sizeof(volist));
locate.opts[0] = LOCATE_OPT;
locate.dsn = full_dsname;
locate.volist = &volist;
/* locate requires 44-byte dsn */
memcpyp(full_dsname, input_dsname, 44, strlen(input_dsname), ' ');
_ldregs(R1, &locate); /* issue locate SVC to find */
_ossvc(26); /* dataset's volser */
rc = _stregs(R15);
if (rc != 0) return -rc; /* dataset not found */
/* initialize parm list fields */
parm_list.safp.pwa = &worka; /* work area address */
parm_list.achklist.flg2 = mode; /* desired access mode */
parm_list.achklist.cl31 = &class; /* class name */
parm_list.achklist.entx = full_dsname;
parm_list.achklist.vs31 = &volist.entry[0].volser; /* dataset volser */
cvtptr = chain(NULL, 16); /* point to the CVT */
safvt = chain(cvtptr, CVTSAF); /* point to SAF vector table */
if (!safvt) return -4; /* SAF router not available */
saf_router = chain(safvt, SAFVSAFR); /* point to SAF router routine */
if (!saf_router) return -4; /* SAF router not available */
_ldregs(R1, &parm_list); /* point to the SAF parm list */
_ldregs(R15, saf_router); /* point to the SAF router */
BALR(14,15); /* call the SAF router */
rc = _stregs(R15);
return rc;
}
|