[comp.sys.apple] ProDOS directories

gwyn@BRL.ARPA.UUCP (05/27/87)

I have an implementation of the POSIX/SVR3 directory library routines
for Aztec C65 ProDOS.  It shouldn't be hard to adapt them to other C
implementations such as APW C.  Should I post them, and in what format
(Aztec .ARC comes to mind, since it's easy to parse with simple tools
such as a text editor)?

ranger@ecsvax.UUCP (Rick N. Fincher) (05/27/87)

In article <8705261801.aa19842@VGR.BRL.ARPA>, gwyn@BRL.ARPA (Doug Gwyn, VLD/VMB) writes:
> I have an implementation of the POSIX/SVR3 directory library routines
> for Aztec C65 ProDOS.  It shouldn't be hard to adapt them to other C
> implementations such as APW C.  Should I post them, and in what format
> (Aztec .ARC comes to mind, since it's easy to parse with simple tools
> such as a text editor)?

I would be interested in just about any Apple II C code.  What does this
cpode do?

Thanks,

Rick Fincher
ranger@ecsvax

gwyn@BRL.ARPA.UUCP (05/28/87)

The C routines I plan to post (as soon as the format question is
settled) implement the IEEE 1003.1 (POSIX) interface for reading
directory entries, as found in UNIX System V Release 3.0.  I
recently posted a generic UNIX implementation to mod.sources; I
adapted that to produce the version I now use with Manx's Aztec C
on ProDOS.  I'm including the relevant UNIX manual entries for
them; if you don't have a UNIX system available, these may be
rough reading.  For this posting (only) I've preceded each file
with its name surrounded by ten = signs on each side, like this:

========== directory.3c ==========
.TH DIRECTORY 3C "Standard Extension"
.SH NAME
opendir, readdir, telldir, seekdir, rewinddir, closedir \- directory operations
.SH SYNOPSIS
.B "#include <sys/types.h>"
.br
.B "#include <dirent.h>"
.P
.B "DIR \(**opendir (dirname)"
.br
.B "char \(**dirname;"
.P
.B "struct dirent \(**readdir (dirp)"
.br
.B "DIR \(**dirp;"
.P
.B "off_t telldir (dirp)"
.br
.B "DIR \(**dirp;"
.P
.B "void seekdir (dirp, loc)"
.br
.B "DIR \(**dirp;"
.br
.B "off_t loc;"
.P
.B "void rewinddir (dirp)"
.br
.B "DIR \(**dirp;"
.P
.B "int closedir (dirp)"
.br
.B "DIR \(**dirp;"
.SH DESCRIPTION
.I Opendir
establishes a connection between
the directory named by
.I dirname
and a unique object of type
.SM DIR
known as a
.I "directory stream"
that it creates.
.I Opendir
returns a pointer to be used to identify the
directory stream
in subsequent operations.
A
.SM NULL
pointer is returned if
.I dirname
cannot be accessed or is not a directory,
or if
.I opendir
is unable to create the
.SM DIR
object
(perhaps due to insufficient memory).
.P
.I Readdir
returns a pointer to an internal structure
containing information about the next active directory entry.
No inactive entries are reported.
The internal structure may be overwritten by
another operation on the same
directory stream;
the amount of storage needed to hold a copy
of the internal structure is given by the value of a macro,
.IR DIRENTSIZ(strlen(direntp\->d_name)) ,
not by
.I "sizeof(struct\ dirent)"
as one might expect.
A
.SM NULL
pointer is returned
upon reaching the end of the directory,
upon detecting an invalid location in the directory,
or upon occurrence of an error while reading the directory.
.P
.I Telldir
returns the current position associated with the named
directory stream
for later use as an argument to
.IR seekdir .
.P
.I Seekdir
sets the position of the next
.I readdir
operation on the named
directory stream.
The new position reverts to the one associated with the
directory stream
when the
.I telldir
operation from which
.I loc
was obtained was performed.
.P
.I Rewinddir
resets the position of the named
directory stream
to the beginning of the directory.
All buffered data for the directory stream is discarded,
thereby guaranteeing that the actual
file system directory will be referred to for the next
.I readdir
on the
directory stream.
.P
.I Closedir
closes the named
directory stream;
internal resources used for the
directory stream are liberated,
and subsequent use of the associated
.SM DIR
object is no longer valid.
.I Closedir
returns a value of zero if no error occurs,
\-1 otherwise.
.P
There are several possible errors that can occur
as a result of these operations;
the external integer variable
.I errno
is set to indicate the specific error.
.RI ( Readdir 's
detection of the normal end of a directory
is not considered to be an error.)
.SH EXAMPLE
Sample code which searches the current working directory for entry
.IR name :
.P
.ft B
	dirp = opendir( "." );
.br
	while ( (dp = readdir( dirp )) != NULL )
.br
		if ( strcmp( dp\->d_name, name ) == 0 )
.br
			{
.br
			(void) closedir( dirp );
.br
			return FOUND;
.br
			}
.br
	(void) closedir( dirp );
.br
	return NOT_FOUND;
.ft P
.SH "SEE ALSO"
getdents(2), dirent(4).
.SH WARNINGS
Entries for "." and ".."
may not be reported for some file system types.
.P
The value returned by
.I telldir
need not have any simple interpretation
and should only be used as an argument to
.IR seekdir .
Similarly,
the
.I loc
argument to
.I seekdir
must be obtained from a previous
.I telldir
operation on the same
directory stream.
.P
.I Telldir
and
.I seekdir
are unreliable when used in conjunction with
file systems that perform directory compaction or expansion
or when the directory stream has been closed and reopened.
It is best to avoid using
.I telldir
and
.I seekdir
altogether.
.P
The exact set of
.I errno
values and meanings may vary among implementations.
.P
Because directory entries can dynamically
appear and disappear,
and because directory contents are buffered
by these routines,
an application may need to continually rescan
a directory to maintain an accurate picture
of its active entries.

========== getdents.2 ==========
.TH GETDENTS 2 "Standard Extension"
.SH NAME
getdents \- get directory entries in a file system independent format
.SH SYNOPSIS
.B "#include <sys/types.h>"
.br
.B "#include <sys/dirent.h>"
.P
.B "int getdents (fildes, buf, nbyte)"
.br
.B "int fildes;"
.br
.B "char \(**buf;"
.br
.B "unsigned nbyte;"
.SH DESCRIPTION
.I Fildes
is a file descriptor obtained from an
.IR open (2)
or
.IR dup (2)
system call.
.P
.I Getdents
attempts to read
.I nbyte
bytes from the directory associated with
.I fildes
and to format them as
file system independent entries
in the buffer pointed to by
.IR buf .
Since the file system independent directory entries
are of variable length,
in most cases the actual number of bytes returned
will be less than
.IR nbyte .
.P
The file system independent directory entry is specified by the
.I dirent
structure.
For a description of this see
.IR dirent (4).
.P
On devices capable of seeking,
.I getdents
starts at a position in the file given by
the file pointer associated with
.IR fildes .
Upon return from
.IR getdents ,
the file pointer has been incremented
to point to the next directory entry.
.P
This system call was developed in order to implement the
.I readdir
routine
[for a description see
.IR directory (3C)]
and should not be used for other purposes.
.SH "SEE ALSO"
directory(3C), dirent(4).
.SH DIAGNOSTICS
Upon successful completion
a non-negative integer is returned
indicating the number of bytes of
.I buf\^
actually filled.
(This need not be the number actually used
in the actual directory file.)\|\|
A value of zero
indicates the end of the directory has been reached.
If
.I getdents
fails for any other reason,
a value of \-1 is returned and
the external integer variable
.I errno
is set to indicate the error.
.SH WARNINGS
Entries for "." and ".."
may not be reported for some file system types.
.P
The exact set of
.I errno
values and meanings may vary among implementations.

========== dirent.4 ==========
.TH DIRENT 4 "Standard Extension"
.SH NAME
dirent \- file system independent directory entry
.SH SYNOPSIS
.B "#include <sys/types.h>"
.br
.B "#include <sys/dirent.h>"
.SH DESCRIPTION
Different file system types
may have different directory entries.
The
.I dirent
structure defines a
file system independent directory entry,
which contains information common to
directory entries in different file system types.
A set of these structures is returned by the
.IR getdents (2)
system call.
.P
The
.I dirent
structure is defined below.
.br
struct	dirent	{
.br
			long			d_ino;
.br
			off_t			d_off;
.br
			unsigned short		d_reclen;
.br
			char			d_name[1];
.br
		};
.P
The field
.I d_ino
is a number which is unique
for each file in the file system.
The field
.I d_off\^
represents an offset of that directory entry
in the actual file system directory.
The field
.I d_name
is the beginning of the character array
giving the name of the directory entry.
This name is null terminated
and may have at most
.SM NAME_MAX
characters in addition to the null terminator.
This results in file system independent directory entries
being variable-length entities.
The value of
.I d_reclen
is the record length of this entry.
This length is defined to be the number of bytes
between the beginning of the current entry and the next one,
adjusted so that the next entry
will start on a long boundary.
.SH FILES
/usr/5include/sys/dirent.h
.SH "SEE ALSO"
getdents(2).
.SH WARNING
The field
.I d_off\^
does not have a simple interpretation
for some file system types
and should not be used directly by applications.