www.sas.com > Service and Support > Technical Support
 
Technical Support SAS - The power to know(tm)
  TS Home | Intro to Services | News and Info | Contact TS | Site Map | FAQ | Feedback


/*-------------------------------------------------------------------+
|                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;
}

Copyright (c) 2000 SAS Institute Inc. All Rights Reserved.
Terms of Use & Legal Information | Privacy Statement