![]() |
![]() HP OpenVMS Systemsask the wizard |
![]() |
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; }
|