still@usceast.UUCP (Bert Still) (06/10/87)
Hi There, I have 2 (possibly) strange questions for netland. The first concerns the VAX-C run-time library. Listed in the VAX-C manual are references to some run-time functions that are otherwise undocumented. I did a lib/list on the VAXCRTL.OLB file and verified that the following routines do exist: shell$from_vms -- translate VMS filespecs to UNIX filespecs shell$to_vms -- translate UNIX filespecs to VMS filespecs shell$cli_name -- determine user's command interpreter shell$fix_time -- convert VMS time to UNIX format shell$clint -- interface to argument lists under shell shell$wild -- wildcard expansion to infinite names. Does anyone have a copy of the correct calling sequences for these ? (I have tried to experiment, and can guess at some of the arguments, like string descriptors, etc. but I cannot seem to get them all.) We do not run DEC/Shell (yet, we probably will buy it in the future), and I suspect that the answer lies therein. In the meantime, can some kind soul please send me a copy of the calling sequences to any/all of the above? The second question concerns VMS directories. I have perused the "orange manuals" for the last two weeks looking for something that describes the VMS directory files' organization. So far, by dumping the contents of several .DIR files, I have determined that the entries begin with 32767, and filenames are followed by an ASCII null (\0), and that the version number immediately follows the filename. Does anyone have a complete description of an entry in a .DIR file, or know where I can find the information? (For the curious, I am trying to convert some systems programs that I have from BSD UNIX to run under VMS, and I need the OPENDIR, READDIR, CLOSEDIR, and IOCTL functions; hence, I am trying to write them, and meeting with little success... any help will be greatly appreciated.) PS. If anyone has any of these functions written for VMS, I would be extremely appreciative of any advice/aid I might receive. Bert 8-} -------------------------------------------------------------------------------- What DesCartes really meant was "I think; therefore, I am paid." -------------------------------------------------------------------------------- ("shar" is actually an ancient term meaning "some assembly required.") -------------------------------------------------------------------------------- # UUCP: {...ihnp4!akgua | # US SNAIL: Bert Still ...seismo!ncr-sd!ncrcae} # Dept of Mathematics !usceast!still # University of South Carolina # Columbia, SC 29208 BITNET: T410119@UNIVSCVM # # --------------------------------------------------------------------------------
carl@CITHEX.CALTECH.EDU (Carl J Lydick) (06/12/87)
> I have 2 (possibly) strange questions for netland. The first concerns > the VAX-C run-time library. Listed in the VAX-C manual are references to some > run-time functions that are otherwise undocumented. I did a lib/list on the > VAXCRTL.OLB file and verified that the following routines do exist: > shell$from_vms -- translate VMS filespecs to UNIX filespecs > shell$to_vms -- translate UNIX filespecs to VMS filespecs > shell$cli_name -- determine user's command interpreter > shell$fix_time -- convert VMS time to UNIX format > shell$clint -- interface to argument lists under shell > shell$wild -- wildcard expansion to infinite names. > Does anyone have a copy of the correct calling sequences for these ? (I have > tried to experiment, and can guess at some of the arguments, like string > descriptors, etc. but I cannot seem to get them all.) We do not run DEC/Shell > (yet, we probably will buy it in the future), and I suspect that the answer > lies therein. In the meantime, can some kind soul please send me a copy of > the calling sequences to any/all of the above? > SHELL$FROM_VMS num_files_found = shell$from_vms( vms_filespec, action_routine, wild_flag ) char *vms_filespec; int wild_flag; int action_routine(); int shell$from_vms(); SHELL$TO_VMS num_files_found = shell$to_vms( shell_filespec, action_routine, wild_flag ) char *shell_filespec; int wild_flag; int action_routine(); int shell$to_vms(); SHELL$CLI_NAME status = shell$cli_name( cli_name_desc ) # include descrip int shell$cli_name(); struct dsc$descriptor *cli_name_desc; SHELL$FIX_TIME unxtim = shell$fix_time( vmstim ) int quadword[2]; int *vmstim = quadword; int shell$fix_time(); SHELL$MATCH_WILD status = shell$match_wild( string, pattern ) char *string; char *pattern; int shell$match_wild(); > The second question concerns VMS directories. I have perused the > "orange manuals" for the last two weeks looking for something that describes > the VMS directory files' organization. So far, by dumping the contents of > several .DIR files, I have determined that the entries begin with 32767, and > filenames are followed by an ASCII null (\0), and that the version number > immediately follows the filename. Does anyone have a complete description of > an entry in a .DIR file, or know where I can find the information? 4.3 Directory Structure A directory is a contiguous file, organized as a sequential file with variable length records, with the attribute set that records do not cross block boundaries, and no carriage control attributes. Directory entries within each block are packed together to conform to the variable length record format; a -1 byte count signals the end of records for that block. (See Section 6 for a discussion of record formats.) The entries in a directory are sorted alphabetically, per- mitting the use of an optimized search. Entries which are multiple versions of the same name and type are arranged in order of decreasing version number to optimize version re- lated operations. Each directory record consists of the following: |---------------------------------------| | Record Byte Count | |---------------------------------------| | Version Limit | |-------------------|-------------------| | Name Byte Count | Flags | |-------------------|-------------------| | | | | | | | File Name String | | | | | | | |---------------------------------------| | | | | | Value Field | | | | | |---------------------------------------| Count This two byte field is the standard byte count field of a variable length record. Limit This word contains the maximum number of versions that are to be retained for this name and type. An attempt to enter more versions than the limit will result in the deletion of the least recent version, or an error return, at the implementing system's option. Flags This byte contains the type code of the directory entry and assorted flags bits. The type code is contained in the three low bits of the flags byte. It is one of the following values: DV.FID The value field is a list of version numbers and 48 bit File ID's. DV.SLK The value field is a symbolic link string. The following flag bits are defined: DV.PRV Set if the preceding directory record contains the same name and type as this one. DV.NXV Set if the next directory record con- tains the same name and type as this one. Name This field contains the file name and type in ASCII, separated by a dot. The dot is present even if either name, or type, or both, are null. Only upper case alphabetic and numeric characters may be present in the name and type. If the length of the name is odd, it is padded with a single null. Value This field contains the "value" of the directory entry; i.e., the information returned to the user from a lookup operation. If the directory record is a File ID list (the type field is DV.FID), the value field is a list of version numbers and cor- responding file ID's, appearing in descending order by version number. The number of entries in the list is deduced from the record byte count. |---------------------------------------| | Version number | |---------------------------------------| | | |-- --| | File ID | |-- --| | | |---------------------------------------| | Version number | |---------------------------------------| | | |-- --| | File ID | |-- --| | | |---------------------------------------| | | | | | | | | | |---------------------------------------| | Version number | |---------------------------------------| | | |-- --| | File ID | |-- --| | | |---------------------------------------| Version This word contains the version number of the di- rectory entry in binary. Version numbers must lie in the range from 1 to 32767. File ID These three words are the file ID that the direc- tory entry points to. If the directory entry is a symbolic link (the flags byte contains DV.SLK), then the value field is variable length. Its first byte is a byte count, and the remainder is an ASCII string which describes the linkage. The string is padded to the next word boundary with a null if necessary. The format is the following: |-------------------|-------------------| | | Byte Count | |-- |-------------------| | | | | | | | Symbolic Link String | | | | | | | |---------------------------------------|
LEICHTER-JERRY@YALE.ARPA (06/18/87)
...Listed in the VAX-C manual are references to some run-time functions that are otherwise undocumented. I did a lib/list on the VAXCRTL.OLB file and verified that the following routines do exist: shell$from_vms -- translate VMS filespecs to UNIX filespecs shell$to_vms -- translate UNIX filespecs to VMS filespecs shell$cli_name -- determine user's command interpreter shell$fix_time -- convert VMS time to UNIX format shell$clint -- interface to argument lists under shell shell$wild -- wildcard expansion to infinite names. Does anyone have a copy of the correct calling sequences for these? These functions are documented in the DEC Shell documentation. The calling sequences are somewhat complex - e.g., shell$from_vms is given the address of an action routine to pass each translated file spec to (there can be many if the input had wild-cards) - so it's probably best if you get a copy of the documentation. The second question concerns VMS directories. I have perused the "orange manuals" for the last two weeks looking for something that des- cribes the VMS directory files' organization.... Does anyone have a com- the information? The internal format of directory files is undocumented. (However, the infor- mation does appear as part of the ODS-II specification; copies of this have appeared in DECUS publications.) (For the curious, I am trying to convert some systems programs that I have from BSD UNIX to run under VMS, and I need the OPENDIR, READDIR, CLOSEDIR, and IOCTL functions; hence, I am trying to write them, and meeting with little success... any help will be greatly appreciated.) There's no simple way to do this. Where Unix programs read directories as files, VMS programs use the $SEARCH function of RMS. The ideal approach would be to convert the USE of the functions. Failing that, use $SEARCH to look for *.*;*, which will give you all the file specs; you can then use them to build whatever data structure you like. -- Jerry -------
Sm@numm.UUCP (06/22/87)
Below are the directory routines I wrote a couple of months ago when I needed a VMS implementation of the BSD opendir, closedir, readdir and rewinddir routines. The opendir() routine accepts a directory specification and prepares the directory to be read, readdir() reads the next entry, etc. The routines are encapsulated in a DCL archive below. Scott Merrilees [Samarium] ACSnet: Sm@numm.nu.oz ARPA: Sm%numm.nu.oz@seismo.css.gov UUCP: ...!seismo!munnari!numm.nu.oz!Sm ......................... Cut between dotted lines and save .................... $!.............................................................................. $! $! VAX/VMS archive file created by VMS_SHAR Version:'09-Jun-1987' $! Copyright (c) 1987, by Michael Bednarek $! To unpack, simply execute (@) the file. $! This archive was created by C8262502 $! on Monday 22-JUN-1987 17:53:00.02 $! It contains the following file(s): $! AAAREADME.DOC CLOSEDIR.C NDIR.H OPENDIR.C READDIR.C REWINDDIR.C TEST.C $!============================================================================== $ Set Symbol/Scope=(NoLocal,NoGlobal) $ CR[0,8]=13 $ Pass_or_Failed="failed!,passed." $ Goto Start $Convert_File: $ Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd $No_Error1:Open/Write Out 'File_is $ Open/Read In VMS_SHAR_DUMMY.DUMMY $Next_Record: Read/End_Of_File=EOF In Record $ Write Out F$Extract(1,255,Record) $ Goto Next_Record $EOF: Close Out $ Close In $ Delete VMS_SHAR_DUMMY.DUMMY;* $ Checksum 'File_is $ Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR $ Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd $No_Error2:Return $Start: $ File_is="AAAREADME.DOC" $ Check_Sum_is=425232041 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X Directory Reading Routines: X X Linking: It is necessary to link in the module c$$translate X from sys$library:vaxcrtl.olb as there is no X corresponding universal symbol in sys$share:vaxcrtl.exe. X Otherwise you could add transfer vectors and link X opendir,readdir,closedir and rewinddir into vaxcrtl X but this would be painfull when a new RTL arrived. X /* c$$translate translates vms error codes into */ X /* *un%x error codes in errno. */ X X Extensions: opendir() accepts an optional int argument, X flags, which currently has only one bit utilized, X bit _D_V_WILD allowing wildcard usage. X X Kludges: Since inodes are not used under VMS, ino_t was X specified as int and the first two words of the X file id were used. The third word is zero unless X you are using multi-volume disks. X X Unimplemented: seekdir() and telldir(). $ GoSub Convert_File $ File_is="CLOSEDIR.C" $ Check_Sum_is=1937127202 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X/* X * @(#) closedir.c V01-000 2-Apr-1987 X * X * Copyright (C) 1987, Scott Merrilees [Samarium] X */ X#include "ndir.h" X X/* X * Close a directory, making sure RMS context is deallocated. X */ X Xvoid Xclosedir(Dp) X register DIR * Dp; X{ X Dp->_D_fab.fab$b_dns = 0; X Dp->_D_nam.nam$b_nop |= NAM$M_SYNCHK; X sys$parse(&Dp->_D_fab); X free(Dp->_D_dir); X free((char *)Dp); X} $ GoSub Convert_File $ File_is="NDIR.H" $ Check_Sum_is=1581550862 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X/* X * @(#) dir.h V01-000 2-Apr-1987 X * X * Copyright (C) 1987, Scott Merrilees [Samarium] X */ X X#ifndef DIRSIZ X X#ifndef FAB$C_BID X#include fab X#endif FAB$C_BID X X#ifndef NAM$C_BID X#include nam X#endif NAM$C_BID X X#define DIRSIZ NAM$C_MAXRSS /* Maximum file name size */ X X#ifndef INO_T Xtypedef int ino_t; /* Pseudo inode type */ X#define INO_T int X#endif INO_T X Xstruct direct X{ X union X { X ino_t _d_ino; /* Pseudo inode number */ X unsigned short X _d_fid[3]; /* File ID */ X } X _d_u0; X#define d_ino _d_u0._d_ino X#define d_fid _d_u0._d_fid X char d_name[DIRSIZ + 1]; /* File name */ X}; X Xtypedef struct X{ X char * _D_dir; /* Argument to opendir() */ X struct FAB _D_fab; /* FAB for RMS */ X struct NAM _D_nam; /* NAM for RMS */ X char _D_esa[NAM$C_MAXRSS]; /* Expanded string area */ X char _D_rsa[NAM$C_MAXRSS + 1];/*Resultant string area */ X int _D_flags; /* Flags, see below */ X X#define _D_V_WILD 0 /* Wild directory allowed */ X#define _D_S_WILD 1 X#define _D_M_WILD 1 X} X DIR; X X/* X * Note: seekdir() and telldir() are not implemented. X */ Xextern DIR *opendir(); Xextern struct direct *readdir(); Xextern void closedir(); Xextern void rewinddir(); X X#endif DIRSIZ $ GoSub Convert_File $ File_is="OPENDIR.C" $ Check_Sum_is=2019389696 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X/* X * @(#) opendir.c V01-000 2-Apr-1987 X * X * Copyright (C) 1987, Scott Merrilees [Samarium] X */ X X#include "ndir.h" X#include errno X#include stsdef X#include varargs X X/* X * Pesudo directory open, actually allocate RMS context, using $parse, X * to do subsequent $search operations. X */ X XDIR * Xopendir(name, va_alist) X char * name; X va_dcl X{ X char * malloc(); X char * strcpy(); X register DIR * Dp; X va_list ap; X X if ( (Dp = (DIR *)malloc(sizeof(DIR))) == (DIR *)0 ) X return (DIR *)0; X X va_count(Dp->_D_flags); X if (Dp->_D_flags == 1) X Dp->_D_flags = 0; X else X { X va_start_1(ap, 1); X Dp->_D_flags = va_arg(ap, int); X va_end(ap); X } X X Dp->_D_fab = cc$rms_fab; X Dp->_D_fab.fab$b_fns = strlen(name); X if ( (Dp->_D_dir = malloc(Dp->_D_fab.fab$b_fns + 1)) == (char *)0 ) X { X free((char *)Dp); X return (DIR *)0; X } X Dp->_D_fab.fab$l_fna = strcpy(Dp->_D_dir, name); X Dp->_D_fab.fab$l_nam = &Dp->_D_nam; X X Dp->_D_nam = cc$rms_nam; X Dp->_D_nam.nam$l_esa = &Dp->_D_esa; X Dp->_D_nam.nam$l_rsa = &Dp->_D_rsa; X Dp->_D_nam.nam$b_ess = Dp->_D_nam.nam$b_rss = NAM$C_MAXRSS; X X if ( !(sys$parse(&Dp->_D_fab) & STS$K_SUCCESS) ) X { X c$$translate(Dp->_D_fab.fab$l_sts); X free(Dp->_D_dir); X free((char *)Dp); X return (DIR *)0; X } X X if /* Considered converting fred or fred.dir into [.fred] */ X ( /* but only needed to use correct directory syntax. */ X (Dp->_D_nam.nam$l_fnb & (NAM$M_EXP_NAME|NAM$M_EXP_TYPE|NAM$M_EXP_VER)) X || X (Dp->_D_nam.nam$b_dev == 0) X || X (Dp->_D_nam.nam$b_dir == 0) X || X ( X ((Dp->_D_flags & _D_M_WILD) == 0) X && X (Dp->_D_nam.nam$l_fnb & NAM$M_WILDCARD) X ) X ) X Dp->_D_fab.fab$l_sts = STS$K_ERROR; X else X { X Dp->_D_fab.fab$l_dna = Dp->_D_fab.fab$l_fna; X Dp->_D_fab.fab$b_dns = Dp->_D_fab.fab$b_fns; X Dp->_D_fab.fab$l_fna = "*.*;*"; X Dp->_D_fab.fab$b_fns = 5; X sys$parse(&Dp->_D_fab); X } X X if ( !(Dp->_D_fab.fab$l_sts & STS$K_SUCCESS) ) X { X if ( Dp->_D_fab.fab$l_sts == STS$K_ERROR ) X errno = ENOTDIR; X else X c$$translate(Dp->_D_fab.fab$l_sts); X Dp->_D_fab.fab$b_dns = 0; X Dp->_D_nam.nam$b_nop |= NAM$M_SYNCHK; X sys$parse(&Dp->_D_fab); X free(Dp->_D_dir); X free((char *)Dp); X return (DIR *)0; X } X X return Dp; X} $ GoSub Convert_File $ File_is="READDIR.C" $ Check_Sum_is=1796104212 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X/* X * @(#) readdir.c V01-000 2-Apr-1987 X * X * Copyright (C) 1987, Scott Merrilees [Samarium] X */ X#include "ndir.h" X#include rmsdef X#include stsdef X X/* X * Return the next entry in a directory as returned by $search. X */ X Xstruct direct * Xreaddir(Dp) X register DIR * Dp; X{ X static struct direct dir; X X if ( !(sys$search(&Dp->_D_fab) & STS$K_SUCCESS) ) X { X if ( Dp->_D_fab.fab$l_sts != RMS$_NMF ) X c$$translate(Dp->_D_fab.fab$l_sts); X return (struct direct *)0; X } X X dir.d_fid[0] = Dp->_D_nam.nam$w_fid[0]; X dir.d_fid[1] = Dp->_D_nam.nam$w_fid[1]; X dir.d_fid[2] = Dp->_D_nam.nam$w_fid[2]; X Dp->_D_rsa[Dp->_D_nam.nam$b_rsl] = '\0'; X strcpy(dir.d_name, Dp->_D_rsa); X X return &dir; X} $ GoSub Convert_File $ File_is="REWINDDIR.C" $ Check_Sum_is=559161474 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X/* X * @(#) rewinddir.c V01-000 2-Apr-1987 X * X * Copyright (C) 1987, Scott Merrilees [Samarium] X */ X#include "ndir.h" X#include stsdef X X/* X * Rewind directory search. This operation is why the original X * directory specification was saved, as the directory may have X * been a search list. X */ X Xvoid Xrewinddir(Dp) X register DIR * Dp; X{ X if ( !(sys$parse(&Dp->_D_fab) & STS$K_SUCCESS) ) X c$$translate(Dp->_D_fab.fab$l_sts); X} $ GoSub Convert_File $ File_is="TEST.C" $ Check_Sum_is=68367500 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X/* X * test.c Test directory routines. X * X * Scott Merrilees [Samarium] X */ X#include "ndir.h" X#include stdio X Xmain() X{ X char buf[BUFSIZ]; X int flags; X DIR * Dp; X struct direct * dp; X char *gets(); X X printf("Flags:\t\t"); X flags = atoi(gets(buf)); X printf("Directory:\t"); X gets(buf); X X if ((Dp = opendir(buf, flags)) == (DIR *)0) X perror(buf); X else X { X while ((dp = readdir(Dp)) != (struct direct *)0) X printf("%s\n", dp->d_name); X rewinddir(Dp); X while ((dp = readdir(Dp)) != (struct direct *)0) X printf("%s\n", dp->d_name); X closedir(Dp); X } X} $ GoSub Convert_File -- Scott Merrilees [Samarium] ACSnet: Sm@numm.nu.oz ARPA: Sm%numm.nu.oz@seismo.css.gov UUCP: ...!seismo!munnari!numm.nu.oz!Sm
jimp@cognos.uucp (Jim Patterson) (06/26/87)
In article <2405@usceast.UUCP> still@usceast.UUCP (Bert Still) writes: > >Hi There, > The second question concerns VMS directories. I have perused the >"orange manuals" for the last two weeks looking for something that describes >the VMS directory files' organization. >(For the curious, I am trying to convert some systems programs that I have >from BSD UNIX to run under VMS, and I need the OPENDIR, READDIR, CLOSEDIR, and >IOCTL functions) Rather than trying to decode the VMS directory structures, you might be better off to use the RMS directory search primatives. You could set up the following equivalences: OPENDIR - establishes the directory name, and sets up SYS$SEARCH using the given directory name and a filename of *.*;* . (You may need to call SYS$PARSE at this point). READDIR - calls SYS$SEARCH to retrieve the next filename and store information about it into the FAB (File Access Block) and NAMe structures (plus any XABs you may need). You can then move whatever information is appropriate into the directory structure your program expects. CLOSEDIR - can just free up the various control structures. I don't know where IOCTL fits in. There are RTL routines that are similar (LIB$FIND_FILE, etc.). If all you need are names of files, these may be sufficient. -- Jim Patterson decvax!utzoo!dciem!nrcaer!cognos!jimp Cognos Incorporated
levy@ttrdc.UUCP (06/29/87)
In article <258@numm.nu>, Sm@numm.nu (Scott Merrilees) writes: > Below are the directory routines I wrote a couple of months ago when I needed > a VMS implementation of the BSD opendir, closedir, readdir and rewinddir > routines. The opendir() routine accepts a directory specification and prepares > the directory to be read, readdir() reads the next entry, etc. The routines > are encapsulated in a DCL archive below. ... Thanks, Scott, for these handy routines. However, I would like to know if it would be too much to ask of DCL "shar" posters that they try to keep backward compatibility with the previous few versions of VMS. VMS 4.X has been around long enough that long file names are probably OK, but not everyone has GOSUB yet. (Is that VMS 4.4 or 4.6? We're at 4.3 and can't update yet because of applications that won't work right under later versions of VMS. UNIX systems often do better at binary backward compatibility. This is not a flame, just an [admittedly biased :-)] observation.) Thanks for making VMS code easier to unshar in the future.... -- |------------dan levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an engihacker @ | vax135}!ttrdc!ttrda!levy | at&t data systems division | Disclaimer: try datclaimer. |--------skokie, illinois--------|