HP OpenVMS Systems

ask the wizard
Content starts here

C and RMS?

» close window

The Question is:

 
I am trying to get the date-time information in a C program which used FAB,
RAB, and XAB (which I don't know how to use)...  How do I start from FAB,
opening the file for reading, and print out the date=time of creation?
 
Here is what I have been trying...:::
 
struct FAB infab, *fab
struct RAB inrab, *rab;
struct XABDAT inxab;
 
infab = cc$rms_fab;
inxab = cc$rms_xabdat;
...
infab.fab$l_xab = &inxab;
...
fab = &infab;
stat = sys$open ( fab );
...
stat = sys$display ( fab );
...
printf("VMS_FILE_inxab = {%ld %ld};",inxab.xab$q_cdt,inxab.xab$q_rdt);
...
 
Am I close?  Could I get a code fragment that shows the correct sequence of
calls?  Thanks.
 
I work for NASA in Greenbelt in a VMS cluster, and am having much success,
except for this.  Plus, I would LOVE to get the values in an ASCII string...
 
Can you help me?
 
Mark.
 
 


The Answer is :

 
  The C fstat() call would seem useful, if this is a file accessed via
  native C library calls.  The field st_ctime is the time_t value the
  file was created.
 
  Also see topics (6916), (1023), (5424), (6744), (6884).
 
  As for RMS, the consider following:
 
/*
** COPYRIGHT (c) 1992-1999 BY
** DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS.
** ALL RIGHTS RESERVED.
**
** THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
** ONLY  IN  ACCORDANCE  OF  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
** INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR  ANY  OTHER
** COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
** OTHER PERSON.  NO TITLE TO AND  OWNERSHIP OF THE  SOFTWARE IS  HEREBY
** TRANSFERRED.
**
** THE INFORMATION IN THIS SOFTWARE IS  SUBJECT TO CHANGE WITHOUT NOTICE
** AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
** CORPORATION.
**
** DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE  OR  RELIABILITY OF ITS
** SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
*/
 
/*
**++
**  Facility:
**
**	Examples
**
**  Version: V1.1
**
**  Abstract:
**
**	Example of working with RMS calls from C
**
**  Author:
**	Steve Hoffman (XDELTA::HOFFMAN)
**
**  Creation Date:  1-Jan-1990
**
**  Modification History:
**	    Hoffman	15-Oct-1994	Updates for DEC C
**--
*/
 
/*
//  RMS_EXAMPLES.C
//
//  Program displays some RMS calls made from the c language.  Types out
//  the calling process's SYS$LOGIN:LOGIN.COM file to SYS$OUTPUT.
//
//  Included is a main and three subroutines.  The subroutines open,
//  read a record, and close the file.  Several hooks, such as the
//  use of the NAM block to obtain the specification of the file that
//  was actually opened, are included but are not currently used.
//
//  To build:
//
//    $ CC [/DECC] [/DEBUG/NOOPTIM] RMS_EXAMPLES
//    $ LINK [/DEBUG] RMS_EXAMPLES
//    $ RUN [/[NO]DEBUG] RMS_EXAMPLES
*/
 
#include <descrip.h>
#include <lib$routines.h>
#include <rms.h>
#include <starlet.h>
#include <string.h>
#include <ssdef.h>
#include <stdio.h>
#include <stsdef.h>
 
/*
// RMS_MRS is the maximum record size that can be read (and thus
// displayed) by this program.
*/
#define RMS_MRS	255
 
/*
// The following is the core data structure for the program.
// The various RMS subroutines all communicate via a pointer
// referencing this struct.
*/
struct RmsFileContext
    {
    struct FAB fab;
    struct RAB rab;
    struct NAM nam;
    struct XABDAT xabdat;
    char rss[NAM$C_MAXRSS];
    short max_rec_siz;
    char *data_buffer;
    };
 
RmsShowDate( void **CtxArg, char *Subject, void *TimeQuad )
    {
    int RetStat;
    struct dsc$descriptor AsciiDate;
    int AsciiDateLen = 23;
    struct RmsFileContext *Ctx = *CtxArg;
 
    AsciiDate.dsc$b_class = DSC$K_CLASS_D;
    AsciiDate.dsc$b_dtype = DSC$K_DTYPE_T;
    AsciiDate.dsc$w_length = 0;
    AsciiDate.dsc$a_pointer = NULL;
    RetStat = lib$sget1_dd( &AsciiDateLen, &AsciiDate );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
    RetStat = sys$asctim ( 0, &AsciiDate, TimeQuad, 0 );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
    printf("%s\n", Subject );
    RetStat = lib$put_output( &AsciiDate );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
    printf("\n" );
    RetStat = lib$sfree1_dd( &AsciiDate );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
    return SS$_NORMAL;
    }
 
RmsFileOpen( void **CtxArg,
char *FileName, char *DefFileName, int flags, int rss )
    {
    int RetStat;
    struct RmsFileContext *Ctx;
    int howbig = sizeof( struct RmsFileContext );
    char *CDT = "CDT";
 
    /*
    // acquire some space for a Context block.
    */
    RetStat = lib$get_vm( &howbig, &Ctx, 0 );
 
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
 
    *CtxArg = (void *) Ctx;
 
    /*
    // Fill in the various fields of the Context block.
    // -- Builds the File Access Block (FAB), the Record Access
    // Block (RAB) and the Name (NAM) Block.  Along with some
    // other miscellaneous housekeeping stuff.
    */
    Ctx->fab = cc$rms_fab;
    Ctx->rab = cc$rms_rab;
    Ctx->nam = cc$rms_nam;
    Ctx->xabdat = cc$rms_xabdat;
 
    Ctx->fab.fab$l_nam = &Ctx->nam;
    Ctx->fab.fab$l_fop = FAB$M_NAM;
    Ctx->fab.fab$b_fac = FAB$M_GET;
 
    Ctx->fab.fab$l_fna = FileName;
    Ctx->fab.fab$b_fns = strlen( FileName );
    Ctx->fab.fab$l_dna = DefFileName;
    Ctx->fab.fab$b_dns = strlen( DefFileName );
 
    Ctx->rab.rab$l_fab = &Ctx->fab;
    Ctx->fab.fab$l_xab = &Ctx->xabdat;
 
    Ctx->nam.nam$b_rss = NAM$C_MAXRSS;
    Ctx->nam.nam$l_rsa = Ctx->rss;
 
    Ctx->rab.rab$b_rac = RAB$C_SEQ;
 
    /*
    // Attempt to open the file...
    */
    RetStat = sys$open( &Ctx->fab, 0, 0 );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
 
    /*
    //  Show the creation date...
    */
    RetStat = RmsShowDate( CtxArg, CDT, &Ctx->xabdat.xab$q_cdt );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
 
    /*
    // Allocate a buffer large enough for the biggest record.
    */
    RetStat = lib$get_vm( &RMS_MRS, &Ctx->data_buffer, 0 );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
 
    /*
    // Attempt to connect the record stream to the file...
    */
    RetStat = sys$connect( &Ctx->rab, 0, 0 );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
 
    return RetStat;
    }
 
RmsFileRead( void **CtxArg, char **BufAdr, int *BufLen )
    {
    int RetStat;
    struct RmsFileContext *Ctx = *CtxArg;
 
    Ctx->rab.rab$l_ubf = Ctx->data_buffer;
    Ctx->rab.rab$w_usz = RMS_MRS;
 
    RetStat = sys$get( &Ctx->rab, 0, 0 );
 
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	{
        *BufLen = (char) 0;
	*BufAdr = (char) 0;
	return RetStat;
	}
 
    *BufAdr = Ctx->rab.rab$l_rbf;
    *BufLen = Ctx->rab.rab$w_rsz;
 
    return RetStat;
    }
 
RmsFileClose( void **CtxArg )
    {
    int RetStat;
    struct RmsFileContext *Ctx = *CtxArg;
 
    /*
    // Free up the record buffer...
    */
    RetStat = lib$free_vm( &RMS_MRS, &Ctx->data_buffer, 0 );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
 
    /*
    // Be nice and clean up the record stream...
    */
    RetStat = sys$disconnect( &Ctx->rab, 0, 0 );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
 
    /*
    // And close the file...
    */
    RetStat = sys$close( &Ctx->fab, 0, 0 );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
 
    /*
    // And free up the allocated memory...
    */
    RetStat = lib$free_vm( &sizeof( struct RmsFileContext ), CtxArg, 0 );
    if ( !$VMS_STATUS_SUCCESS( RetStat ) )
	return RetStat;
 
    return RetStat;
 
    }
main()
    {
    int RetStat;
    void *Context;
    char *BufAdr;
    int BufLen;
 
    /*
    // Open the file.  Minimal checking is performed.  Read access only.
    */
    RetStat = RmsFileOpen( &Context, "LOGIN", "SYS$LOGIN:.COM", 0, 0 );
 
    /*
    // Read the file.  Minimal checking is performed.
    */
    for (;;)
	{
	RetStat = RmsFileRead( &Context, &BufAdr, &BufLen );
	if ( $VMS_STATUS_SUCCESS( RetStat ) )
	    printf("%*.*s\n", BufLen, BufLen, BufAdr );
	else
	    break;
	}
 
    /*
    // Close up shop.
    */
    RetStat = RmsFileClose( &Context );
 
    return RetStat;
    }
 
 

answer written or last revised on ( 17-AUG-2001 )

» close window