Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!seismo!munnari!moncskermit!basser!nucs!numm!Sm From: Sm@numm.UUCP Newsgroups: comp.os.vms Subject: Re: 2 questions: VAX-C RTL calls and VMS .DIR file entries Message-ID: <258@numm.nu> Date: Mon, 22-Jun-87 05:14:08 EDT Article-I.D.: numm.258 Posted: Mon Jun 22 05:14:08 1987 Date-Received: Fri, 26-Jun-87 02:12:28 EDT References: <2405@usceast.UUCP> Reply-To: Sm@numm.nu.oz (Scott Merrilees) Organization: Dept of Mathematics, University of Newcastle, Australia Lines: 364 Summary: Directory reading routines in C using RMS 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