From: dpm@access4.digex.net (David P. Murphy)
Subject: Re: C FILE pointer.
Date: 1997/06/23
Message-ID: <dpm.867095187@access4>
References: <01bc8003$5e9dfa40$afe0f6c6@192.168.1.1.premierltd.com>
Organization: Express Access Online Communications USA: 800-969-9090
Newsgroups: comp.os.vms



"Alexander Gorelik" <agorelik@sungardams.com> writes:

>Does anyone know how to get to RMS structures given a C file pointer? What
>does "_iobuf" structure tells me? I have a strange problem with program
>that writes buffers of 1980 bytes into STREAM_LF file. When it reaches
>block 720, it suddenly starts to write in block 736, leaving 16 blocks of
>gargbage(not zeros) in between. I was hoping to examine RMS structures at
>the point it starts to write into block 736. 

i wrote FINDRMS.C a little less than a year ago; it should help you.

/* given a valid FILE *, return the addresses of the six RMS blocks
 * associated with that open file by the C run-time library
 *
 * this code has been tested --- and works --- on the following:
 *    VAX/VMS V5.5 using VAXC
 *    VAX/VMS V6.1 using VAXC
 *    AXP/VMS V6.1 using DECC
 *
 * please send any comments or bug reports to
 *     David P. Murphy
 *     dpm@access.digex.net
 */

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <rms.h>

/* need this for the probing
 */
#ifdef __DECC
#  include <builtins.h>
#else
#  pragma builtins
#endif

/* the "date/time xab" was changed during version V5, so we not only
 * have to check two different sizes (at least on a vax), we also
 * need to avoid using the canonical name XAB$K_DATLEN since it
 * might be equated to 60 or it might be equated to 44.
 */
#define XAB$K_DATLEN_NEW 60       /* a.k.a. XAB$K_DATLEN */
#ifdef VAXC
#define XAB$K_DATLEN_OLD 44       /* a.k.a. XAB$K_DATLEN_V54 */
#endif

/* the first seven members of this structure are cut&pasted
 * from the _iobuf definition in the public STDIO.H header
 */
struct C_RUNTIME_FILEINFO {
	int _cnt;
	char *_ptr;
	char *_base;
	unsigned char _flag;
	unsigned char _file;
	unsigned char _pad1;
	unsigned char _pad2;
#ifdef __DECC
	union {
		struct V61_DECC_FCB {
			long skip1[10];
			struct RAB *fcb_l_rab;
			long skip2[8];
			char *vms_name;
			long skip3[8];
			struct FAB *fcb_l_fab;
			struct XABDAT *fcb_l_xabdat;
			struct XABFHC *fcb_l_xabfhc;
			struct XABPRO *fcb_l_xabpro;
		} v61;
		/* the V6.2 source listings do not include the .SRC file :-(
		 */
		struct V70_DECC_FCB {
			long skip1[20];
			char *vms_name;
			long skip2[5];
			struct FAB *fcb_l_fab;
			struct RAB *fcb_l_rab;
			struct XABDAT *fcb_l_xabdat;
			struct XABFHC *fcb_l_xabfhc;
			struct XABPRO *fcb_l_xabpro;
		} v70;
	} version;
#else
	short skip1[26];
	struct FAB fcb_l_fab;		/* file access block */
	struct NAM fcb_l_nam;		/* name block */
	struct RAB fcb_l_rab;		/* record access block */
	char fcb_l_rsa[NAM$C_MAXRSS];	/* result file name string */
	struct XABFHC fcb_l_xabfhc;	/* extended attribute block */
	struct XABPRO fcb_l_xabpro;	/* extended attribute block */
	struct XABDAT fcb_l_xabdat;	/* extended attribute block */
#endif
};

int TestRmsPointer(
	void *pSource,
	int nCode,
	int nSize
)
{
	int bResult = FALSE;
	struct XAB *testptr;

	testptr = (struct XAB *) pSource;
	if (_PROBER(1, nSize, testptr)) {
		if (testptr->xab$b_cod == nCode) {
			if (testptr->xab$b_bln == nSize) {
				bResult = TRUE;
			}
		}
	}

	return(bResult);
}

int FindRMSBlocks(
	FILE *fp,
	struct FAB    **fabhandle,
	struct NAM    **namhandle,
	struct RAB    **rabhandle,
	struct XABDAT **xabdathandle,
	struct XABFHC **xabfhchandle,
	struct XABPRO **xabprohandle
)
{
	struct FAB    *myfab;
	struct NAM    *mynam;
	struct RAB    *myrab;
	struct XABDAT *myxabdat;
	struct XABFHC *myxabfhc;
	struct XABPRO *myxabpro;
	struct C_RUNTIME_FILEINFO *xyzzy;
	int nFound = 0;

	/* do not return unknown values
	 */
	if (fabhandle    != NULL) *fabhandle    = NULL;
	if (namhandle    != NULL) *namhandle    = NULL;
	if (rabhandle    != NULL) *rabhandle    = NULL;
	if (xabdathandle != NULL) *xabdathandle = NULL;
	if (xabfhchandle != NULL) *xabfhchandle = NULL;
	if (xabprohandle != NULL) *xabprohandle = NULL;

	/* dereference the pointer-to-FILE which was passed to us
	 * to obtain the address of the FCB used by the run-time library.
	 * note that i make no special check here to ensure that the
	 * pointer-to-FILE is valid, except that it is a pointer.
	 */
	if (fp == NULL) {
		return(-1);
	}
	if (! _PROBER(1, sizeof(FILE), fp)) {
		return(-2);
	}
	xyzzy = *((struct C_RUNTIME_FILEINFO **) fp);

#ifdef __DECC
	if (TestRmsPointer(xyzzy->version.v61.fcb_l_fab, FAB$C_BID, FAB$K_BLN)) {
		myfab    = xyzzy->version.v61.fcb_l_fab;
		mynam    = NULL;
		myrab    = xyzzy->version.v61.fcb_l_rab;
		myxabdat = xyzzy->version.v61.fcb_l_xabdat;
		myxabfhc = xyzzy->version.v61.fcb_l_xabfhc;
		myxabpro = xyzzy->version.v61.fcb_l_xabpro;
	}
	else {
		myfab    = xyzzy->version.v70.fcb_l_fab;
		myrab    = xyzzy->version.v70.fcb_l_rab;
		myxabdat = xyzzy->version.v70.fcb_l_xabdat;
		myxabfhc = xyzzy->version.v70.fcb_l_xabfhc;
		myxabpro = xyzzy->version.v70.fcb_l_xabpro;
	}
#else
	myfab    = &xyzzy->fcb_l_fab;
	mynam    = &xyzzy->fcb_l_nam;
	myrab    = &xyzzy->fcb_l_rab;
	myxabdat = &xyzzy->fcb_l_xabdat;
	myxabfhc = &xyzzy->fcb_l_xabfhc;
	myxabpro = &xyzzy->fcb_l_xabpro;
#endif

	if (TestRmsPointer(myfab,    FAB$C_BID, FAB$K_BLN)) {
		if (fabhandle != NULL) *fabhandle = myfab;
		++nFound;
		if (mynam == NULL) {
			mynam = myfab->fab$l_nam;
		}
	}
	if (TestRmsPointer(mynam,    NAM$C_BID, NAM$K_BLN)) {
		if (namhandle != NULL) *namhandle = mynam;
		++nFound;
	}
	if (TestRmsPointer(myrab,    RAB$C_BID, RAB$K_BLN)) {
		if (rabhandle != NULL) *rabhandle = myrab;
		++nFound;
	}
	if (TestRmsPointer(myxabdat, XAB$C_DAT, XAB$K_DATLEN_NEW)) {
		if (xabdathandle != NULL) *xabdathandle = myxabdat;
		++nFound;
	}
#ifdef XAB$K_DATLEN_OLD
	else if (TestRmsPointer(myxabdat, XAB$C_DAT, XAB$K_DATLEN_OLD)) {
		if (xabdathandle != NULL) *xabdathandle = myxabdat;
		++nFound;
	}
#endif
	if (TestRmsPointer(myxabfhc, XAB$C_FHC, XAB$K_FHCLEN)) {
		if (xabfhchandle != NULL) *xabfhchandle = myxabfhc;
		++nFound;
	}
	if (TestRmsPointer(myxabpro, XAB$C_PRO, XAB$K_PROLEN)) {
		if (xabprohandle != NULL) *xabprohandle = myxabpro;
		++nFound;
	}

	return(nFound);
}

int main(
	int argc,
	char *argv[]
)
{
	FILE *fp;
	int nCount;
	struct FAB    *fabptr;
	struct NAM    *namptr;
	struct RAB    *rabptr;
	struct XABDAT *xabdatptr;
	struct XABFHC *xabfhcptr;
	struct XABPRO *xabproptr;

#define GETCODE(ptr, id)  (ptr == NULL) ? 0 : ptr->id

	if ((fp = fopen("SYS$LOGIN:LOGIN.COM", "r")) != NULL) {
		nCount = FindRMSBlocks(fp, &fabptr, &namptr, &rabptr, &xabdatptr, &xabfhcptr, &xabproptr);
		printf("count returned is %d.\n", nCount);
		printf("\nFAB   =%08X CODE=%2d (%2d)", fabptr,    GETCODE(fabptr,    fab$b_bid), FAB$C_BID);
		printf("\nNAM   =%08X CODE=%2d (%2d)", namptr,    GETCODE(namptr,    nam$b_bid), NAM$C_BID);
		printf("\nRAB   =%08X CODE=%2d (%2d)", rabptr,    GETCODE(rabptr,    rab$b_bid), RAB$C_BID);
		printf("\nXABDAT=%08X CODE=%2d (%2d)", xabdatptr, GETCODE(xabdatptr, xab$b_cod), XAB$C_DAT);
		printf("\nXABFHC=%08X CODE=%2d (%2d)", xabfhcptr, GETCODE(xabfhcptr, xab$b_cod), XAB$C_FHC);
		printf("\nXABPRO=%08X CODE=%2d (%2d)", xabproptr, GETCODE(xabproptr, xab$b_cod), XAB$C_PRO);
		printf("\n");
		if (namptr != NULL && namptr->nam$b_rsl && namptr->nam$l_rsa != NULL) {
			printf("resfs=%-*s\n", (int) namptr->nam$b_rsl, namptr->nam$l_rsa);
		}
	}

	exit(EXIT_SUCCESS);
}

ok
dpm
-- 
David P. Murphy             mailto:murphy@connor.datametrics.com     (work)
systems programmer          mailto:dpm@access.digex.net          (personal)
                            http://www.access.digex.net/~dpm
COGITO ERGO DISCLAMO             ftp://access.digex.net/pub/access/dpm


