% If you somehow got this file without fullpage.sty,  delete
% ``fullpage'' from the list of style options.  It just pulls out the
% margins a bit.
\documentstyle[11pt,twoside,fullpage]{article}
% New commands
%-------------
% Intro copied from prospero-protocol-v5.txt

% for meta-symbols
\newcommand{\meta}[1]{{\bf \mbox{\(<\)#1\(>\)}}}
% for literal tokens.
\newcommand{\lit}[1]{{\tt \mbox{#1}}}
%for attributes
\newcommand{\atr}[1]{\mbox{\sc #1}}
% for identifying text
\newcommand{\text}[1]{{\em #1}\/}

% Start and end of One or More
\newcommand{\ooms}{\([\,\)}
\newcommand{\oome}{\(\,]^+\)}
% start and end of zero or more
\newcommand{\zoms}{\([\,\)}
\newcommand{\zome}{\(\,]^*\)}
% Start and end of zero or one
\newcommand{\zoos}{\([\,\)}
\newcommand{\zooe}{\(\,]\)}
% start an OR
\newcommand{\ors}{{\bf (\,}}
\newcommand{\ore}{{\bf \,) }}
\newcommand{\metaor}{{\em \,or\, }}
\newcommand{\hexnum}[1]{\(\mbox{#1}_{16}\)}
\newcommand{\unix}{{\sc unix}}
\newenvironment{command}{\begin{verse}\sloppy}{\end{verse}}
\newcommand{\commandsize}{\large}

%\newtheorem{example}{Example}
% Uncomment this for almost-double spacing
%\renewcommand{\baselinestretch}{1.7}
%\newcommand{\hozline}{\rule{\textwidth}{0.3mm}}
%\newcommand{\hozline}{\makebox[\textwidth]{\hrulefill}}
%\newcommand{\bex}{\begin{example} \begin{rm}}
%\newcommand{\eex}{$\Box$ \end{rm} \end{example}}
%\newcommand{\cbs}{\chgbarbegin}
%\newcommand{\cbe}{\chgbarend}
%\newcommand{\cbs}{}
%\newcommand{\cbe}{}

%\newcommand{\ptag}{\begin{flushright} {\rm ($P$)} \end{flushright} }


\begin{document}

\pagenumbering{arabic}
\pagestyle{plain}

\renewcommand{\thepage}{\arabic{page}}


\begin{titlepage}

\renewcommand{\thefootnote}{}
\footnotetext{\hspace*{-21pt}
A digital copy of the latest revision of this document may be obtained
through Prospero as
\mbox{\verb"/papers/subjects/operating-systems/prospero/doc/library.PS.Z"},
in the \mbox{\tt \#/INET/EDU/ISI/swa} virtual system, or through
Anonymous FTP from \mbox{\tt PROSPERO.ISI.EDU} as
\mbox{\verb"/pub/prospero/doc/prospero-library.PS.Z"}
}
\footnotetext{\hspace*{-21pt}
This work was supported in part by the National Science
Foundation (Grant No. CCR-8619663), the Washington Technology Center,
Digital Equipment Corporation, and the Defense Advance Research
Projects Agency under NASA Cooperative Agreement NCC-2-539.
The views and conclusions contained in
this document are those of the authors and should not be interpreted as
representing the official policies, either expressed or implied, of
any of the funding agencies.
The authors may be reached
at USC/ISI, 4676 Admiralty Way, Marina del Rey, California\ \ 90292-6695, USA.
Telephone +1 (310) 822-1511, email \mbox{\verb"info-prospero@isi.edu"}.  }
\renewcommand{\thefootnote}{\arabic{footnote}}


\vspace*{\fill}
\begin{center}
\LARGE Prospero Library Manual\\
\Large Version 5\\
\vskip 1.5em
{\large Draft of 30 March 1994} \\
{\large Document Revision No. 0.5.3} \\
\end{center}
\vspace{.5in}

\Large \hspace*{\fill} B. Clifford Neuman
%\footnotetext{\hspace*{-18pt}
%	To Contact the Authors: \\
%	Electronic Mail: \mbox{\verb"info-prospero@isi.edu"} \\
%    Telephone: +1 (310) 822-1511 \\
%    Mail: USC Information Sciences Institute, 4676 Admiralty Way,
%  Marina del Rey, California  90292--6695\ \ U.S.A.
%}
\hfill Steven Seger Augart \hspace*{\fill} \\
\vspace{.2in}
\begin{center}
\Large Information Sciences Institute \\
University of Southern California
\end{center}
\vspace*{1.2in}
\vspace*{\fill}
\end{titlepage}

\tableofcontents

\section{WARNINGS}

\begin{enumerate}
\item This manual is preliminary.  It does not fully describe all of the
Prospero library calls.

\item This manual reflects Prospero releases Alpha.5.2 and later.
You can use it with Prospero releases between Alpha.5.0 and Beta.5.1;
changes are documented under the appropriate functions.

\end{enumerate}

\section{Introduction}

This manual describes the entry points to the Prospero library.

\section{PFS Library}

\subsection{Introduction}

The PFS library includes procedures for allocating and freeing
Prospero data structures, resolving names using Prospero, reading
directories, retrieving attributes, adding and deleting links, and
creating directories.  Only those procedures generally used by application
programmers are described here.  The remaining routines are called
internally.

These functions are prototyped in the include file {\tt pfs.h}, found
in the {\tt include} directory in the Prospero source tree.  The data
structures manipulated by these functions and the definitions of the
flag options are also defined and documented in that file.  When
Prospero is installed normally, the library (ready to be linked with)
can be found in {\tt lib/pfs/libpfs.a} in the Prospero source
hierarchy.

Since this manual is still not complete, a programmer will often find
it helpful to look at the source code files for the functions discussed
here.  Most of them are preceded with large comments discussing their
behavior in more detail than is gone into here.  They can all be found
in the {\tt lib/pfs} directory in the Prospero source tree.

Examples of using these functions can be found in the {\tt user}
directory of the Prospero source tree.

Programmers looking for examples of listing a directory and retrieving
attributes should look at {\tt vls.c}.  Examples of setting attributes
are in {\tt set\_atr.c}.  An example of the {\tt pget\_am} interface
to retrieving files is in {\tt vget.c} (after you see it, we expect
you'll appreciate the simplicity of {\bf pfs\_open()}.  An example of {\tt
add\_vlink()} is in {\tt vln.c}.

\subsection{Multi-threading}

Work to make the Prospero library safe in a multi-threaded
environment, such as pthreads, is in progress.  Since one of the
Prospero developers shot off his mouth and promised to get a
multi-threaded Prospero server to a certain loyal Prospero customer
well before November 15th, you can expect this item soon.

\subsection{Error Reporting}

Most functions in this library return a numeric error code (defined in
{\tt perrno.h}).  The functions in this library which return pointers
to structures will return a null pointer in case of an error.  They
will indicate which error occurred by setting the global variable {\tt
perrno} (defined in the include file {\tt perrno.h}) to one of the
constants defined in that file.  Note: Functions that return an
explicit numeric error code are not guaranteed to set {\tt perrno}.

Most functions that set perrno or return an error code will also set
an explanatory message in the global variable {\tt p\_err\_string}
(also defined in that file).   Even if they have no additional
information, they are supposed to set {\tt p\_err\_string} to the
empty string so that the user isn't misled by an old error message.

The Prospero library guarantees that {\tt p\_err\_string} will always
be a pointer to a string of some sort, frequently empty.  You don't
have to worry about it being a NULL pointer.  {\tt p\_err\_string} and
{\tt p\_warn\_string} may change in value during the program's
execution.  If you are operating in multi-threaded mode, their values
will be different in different threads.

The error indicators in {\tt perrno} and {\tt p\_err\_string} are
persistent across library calls.  To clear them before making a
library call, use the function {\bf p\_clear\_errors()}:
\begin{verbatim}
extern void p_clear_errors(void);
\end{verbatim}

\subsubsection{WARNING}

All the functions in this library are supposed to obey the above
convention about {\tt p\_err\_string}.  We have not gone over all of
them to make certain that the convention is obeyed in every case, due
to the press of other work.

\subsection{Argument modification}

A function that accepts a {\it VLINK} may modify that link if the
object it points to has been forwarded.  If it does so, it will modify
the link to refer to the new location of the object.

Not all calls to the Prospero library currently do this.  When we take
the time to revise the library, we will attempt to make this behavior
consistent across all functions in the library that accept {\it VLINK}s
and send Prospero protocol messages that inform them the link's target
has been forwarded.

\subsection{Initialization}

Every Prospero client {\bf must} call the function 
{\bf p\_initialize()} before making any calls to Prospero library
functions.  Your program may well crash weirdly if you don't.


\begin{verbatim}
extern void p_initialize(char *software_id, int flags, 
                         struct p_initialize_st * arg_st);
\end{verbatim}

If you're writing a client, send email to {\tt
pfs-administrator@isi.edu} and request a software ID string.  If
you're just experimenting with the libraries, you can pass a NULL
pointer or empty string  as the software ID.  
At the moment, no flag values are defined, and no members of the
structure for additional arguments are defined, so the most common
calling sequence is:
\begin{verbatim}
	p_initialize((char *) NULL, 0, (struct p_initialize_st *) NULL);
\end{verbatim}

\subsection{Data Structures}

Most of the data structures in the PFS library are allocated and freed
with special allocation functions ({\it VLINK}s are allocated with
{\bf vlalloc}, etc.  The allocation functions also initialize the
members of the structure to common values and the freeing functions
de-allocate allocated memory referred to by the members of
the structure.  

Do not use the C library function {\bf free} to free memory allocated
by one of the special Prospero allocating functions, and do not use
one of the special freeing functions to free memory allocated by {\bf malloc}.

The {\it VDIR} structure does not have special allocation and freeing
structures.  This is because in the current uses of the Prospero
library, one generally does not make linked lists of {\it VDIR}
structures; instead, one allocates them on the stack with code that
looks like this:

\begin{verbatim}
VDIR_ST dir_st;
VDIR dir = &dir_st;
\end{verbatim}
and then initializes them with:
\begin{verbatim}
vdir_init(dir);
\end{verbatim}
and frees the allocated memory referred to by the members with:
\begin{verbatim}
vdir_freelinks(dir);
\end{verbatim}

\subsubsection{Linked Lists}

Prospero uses linked lists of items as a basic data structure.  In all
cases, these are doubly linked lists.  As usual, the empty list is
represented by a list whose head is the NULL pointer.  When a doubly
linked has one or more items in it, then the {\tt previous} field of
the first item in the list points at the last item, and the {\tt next}
field on the last is NULL.  Therefore, when a list has only one item
in it, then the {\tt next} pointer of the last item is NULL and the
{\tt previous} points back to itself.  In other words, if {\it head}
is non-null, {\it head$->$previous} will always be the TAIL of the
list.

Macros for manipulating lists of these structures are in the {\tt
list\_macros.h} include file.  This file is included by {\tt pfs.h}, but may be
included again without problems.

{\bf APPEND\_ITEM}({\it new, head}) appends the item {\it new} to a doubly linked
list pointed to by {\it head}.  The item {\it new} goes  at the TAIL
of the list.  It must not already be present in the list.  This macro
modifies its second argument, {\it head}, which should be a variable.

{\bf EXTRACT\_ITEM}({\it item, head}) removes {\it item} from a
doubly-linked list headed by {\it head}.  If {\it item} is not a
member of the list, the results are not defined.  The extracted {\it
item} will NOT be freed.

{\bf APPEND\_LISTS}({\it list1,list2}) performs an O(1) list appending
operation.  It sets {\it list1} to point to a doubly-linked list
consisting of {\it list1} appended to {\it list2}.  {\it list2} must
not already be a part of {\it list1} or the results are unpredictable.
{\it list2} will be a garbage value at the end of this exercise, since
it will no longer point to a valid doubly-linked list.  {\it list1}
and {\it list2} must already be valid doubly-linked lists.

\subsubsection{Application-reserved ({\tt app}) member of Prospero structures}

This feature is available in prospero versions Alpha.5.3 and later.

For all exported structures in Prospero visible at the library
interface (except for TOKENs), there is a special member named {\tt
app}, for applications writers.  This member is a union:

\begin{verbatim}
	union app {
		int flg;		/* Flag or number */
		void *ptr;              /* Generic Pointer */
	};
\end{verbatim}

Each allocation/freeing package (eg: vlalloc(), vlfree(), vllfree(),
vlcopy()) has a 'application freeing function specifying function'
(e.g., vlappfree()) associated with it.

So, if we use the app.ptr member of the VLINK structure to point to a
'struct vlink\_aux', to be freed (if non-null) with the 'vlauxlfree
function, then code using the VLINK in that way will have to call:
vlappfree(vlauxlfree); and then all subsequent calls to vlfree() will
call vlauxlfree on the app.ptr member.

\subsection{Entry Points}

\begin{tabbing}
{\Large \bf Entry points:} \= {\bf atalloc, atfree, atlfree, vlalloc,
vlfree, vllfree, add\_vlink,}\\ 
\> {\bf del\_vlink, p\_get\_dir, mk\_vdir, pget\_am, pget\_at, rd\_vdir,}\\
\>{\bf rd\_vlink, pfs\_open, {\rm and} pfs\_fopen}. 
\end{tabbing}

\noindent {\bf PATTRIB atalloc}({\it void}), {\bf FILTER flalloc}({\it void}), {\bf TOKEN
tkalloc}({\it char *s}), {\bf ACL acalloc}({\it void}), and {\bf VLINK
vlalloc}({\it void}) allocate and initialize structures for storing attributes,
filters, tokens, access control list entries, and virtual links.
They call out\_of\_memory() on failure, which is a macro in {\tt
pfs.h} which currently raises an error condition and aborts program
execution.  Its behavior may be changed by resetting the value of the
global variable {\bf internal\_error\_handler} (defined in {\tt pfs.h}
to a function with some alternative behavior (such as popping up a 
window with a failure message and offering to restart the application
or exit).\footnote{
	The Prospero directory server takes advantage of this and
rebinds {\bf internal\_error\_handler()} to a function that logs a
message to the server's log file and attempts to restart the server.}
Since the only failure condition for these functions is running out of
available memory, they do not set {\bf perrno}.  

{\bf atfree}({\it
PATTRIB at}), {\bf flfree}({\it FILTER fl}), {\bf acfree({\it ACL
ac})}, and {\bf vlfree}({\it VLINK vl}) free the storage allocated to
{\it at}, {\it fl}, {\it ac}, and {\it vl}.  They also free any
standard Prospero memory structures referenced by the members of these
structures; for example, freeing a {\it VLINK} will also free any
Prospero string referenced by the {\it VLINK'\/}s {\tt host} member.
They also free any memory referred to by the structure's {\tt app.ptr}
member, using whatever function the user set via {\bf atappfree(),
flappfree(), acappfree(),} or {\bf vlappfree(),} as appropriate.  The
user can disable this feature, if it has already been enabled, by
calling the appropriate {\it xx}{\bf appfree()} function with a null
pointer as its argument.

{\bf atlfree}({\it at}) and {\bf vllfree}({\it vl}) free {\it at} and
{\it vl} and all successors in a linked list of such structures.  They
do not return error codes nor do they set {\tt perrno}, since they
cannot fail.  {\bf tkalloc({\it s})} initializes the {\tt token}
member of the {\it TOKEN} structure it allocates to be a copy of {\it
s}.

{\bf {\it FILTER} flcopy({\it FILTER fl, int recurse})} will return a
copy of the filter {\it fl}.  If the {\it recurse} flag is non-zero,
then it will also recursively copy the linked list of filters that
{\it fl} points to the head of.

{\bf {\it char *} stcopy({\it char *s})} allocates an area of memory
large enough to hold the string {\it s} and copies {\it s} into it.
It is usually used to store a string.  The number of bytes allocated
to a string 
can be checked with the macro {\bf stsize({\it char * string})}.  An
alternative interface to {\bf stcopy} is {\bf {\it char *}
stalloc({\it size\_t nbytes})}.  {\bf stalloc} allocates an area of
uninitialized memory large enough to hold {\it nbytes} bytes of data
and returns a pointer to it.  Another interface is {\bf {\it char
*}stcopyr({\it char *source, char *dest})}.  The sequence:
\begin{verbatim}
a = stcopyr("string", a);
\end{verbatim}
will yield results functionally equivalent to the sequence:
\begin{verbatim}
stfree(a);
a = stcopy("string");
\end{verbatim}
The only
difference is that {\bf stcopyr()} attempts to reuse the already
allocated space, if available.  This avoids the overhead of extra
calls to {\bf malloc()} and {\bf free()}, and is therefore frequently more
efficient than the equivalent longer sequence of calls.  The existing
Prospero libraries and utilities make frequent use of {\bf stcopyr()}
for this purpose.

Also note that \verb|a = stcopyr("foo", (char *) NULL)| is equivalent to 
\verb|a = stcopy("foo");|
Memory allocated by all of these interfaces should be freed with {\bf
stfree({\it st})}.  {\bf stfree({\tt (char *) NULL})} is a guaranteed
no-op.  The various interfaces to {\bf stcopy()} all call {\tt
out\_of\_memory() when appropriate.}  

A frequent cause of problems when using memory allocation functions is
freeing the same chunk of memory twice.  One may optionally enable
consistency checking code in the allocators and freeing functions by
defining {\tt ALLOCATOR\_CONSISTENCY\_CHECK} in {\tt pfs.h}.  This code
has not yet been finished for the {\bf stalloc()} family, but works
for all other allocators.  If any double freeing is detected, {\bf
internal\_error\_handler()} will be called.

A programmer may also easily check for memory leaks by looking at the
global variables {\bf {\it int\/} acl\_count, pattrib\_count,
filter\_count, pauth\_count, pfile\_count, token\_count, vlink\_count,
and rreq\_count} to see how many of each of the  corresponding
structures have been allocated.\footnote{
	We use this facility to debug the Prospero server; it returns
this information in response to the {\tt pstatus} command.}%
	\footnote{
Some of the structures mentioned in this list of global variables
are not yet documented in this manual.}

{\bf add\_vlink}({\it direct,lname,l,flags}) adds a new link {\it l}
to the directory named {\it direct} with the new link name {\it
lname}.  {\it direct} is a string naming the directory that is to
receive the link.  If {\it flags} is {\sc avl\_union}, then the link
is added as a union link. {\bf add\_vlink} returns {\sc psuccess} (0)
on success and an error code on failure. 

This interface to this function will change in a later version of the
library to be {\bf p\_add\_nlink()}, with a corresponding {\bf p\_add\_link}
that takes a {\it VLINK} instead of a string for the {\it direct} argument.

{\bf del\_vlink}({\it path,flags}) deletes the link named by {\it
path}.  At present, {\it flags} is unused.  {\bf del\_vlink} returns
{\sc psuccess} (0) on success and an error code on failure.

This interface to this function will change in a later version of the
library to be {\bf p\_del\_nlink()}, with a corresponding {\bf p\_del\_link()}
that takes a {\it VLINK} instead of a string for the {\it path} argument.

{\bf p\_get\_dir}({\it VLINK dlink,char *components,VDIR dir,int
flags,TOKEN acomp})
contacts the Prospero server on host {\it dlink-$>$host} to read the directory
{\it dlink-$>$hsoname}, resolving union links that are returned and applying
{\it dlink-$>$filters}, if set.

If {\it components} is a null pointer, all links in the directory are
returned.  If {\it components} is a non-null string, only those
links with names matching the string.  The string may be a wildcarded name
containing the {\tt *} and {\tt ?} characters; these have their
conventional meanings.  The string may also be a regular expression,
enclosed between parentheses; in that case, all links matching the
regular expression are returned.

{\bf p\_get\_dir()} will always, in addition to any other links it might
return, return any link whose literal name is the {\it components}
string.  This feature means that you do not have to worry about
retrieving links whose names contain special characters, even if more
special characters are defined at some future time.  An example: The
{\it components} string {\tt (ba\(na\)*na)}, in addition to matching
{\tt banana} and {\tt banananana}, also (as an important special case)
matches the component whose literal name is {\tt (ba\(na\)*na)}.

{\it dir} is a Prospero directory structure that is filled in.  {\it
flags} can suppress the expansion of union links ({\sc gvd\_union}),
force their expansion ({\sc gvd\_expand}), request the return of link
attributes on the {\it VLINK} structure's {\tt lattrib} member ({\sc
gvd\_attrib}), and suppress sorting of the directory links ({\sc
gvd\_nosort}).  {\it acomp} should normally be {\sc null}.  For many
applications, one does not need to call this procedure, and should use
{\bf rd\_vdir} and {\bf rd\_vlink} instead.  {\bf p\_get\_dir} returns
{\sc psuccess} (0) on success and an error code on failure.

The standard way to retrieve the attributes of a link in a directory
is to call {\bf p\_get\_dir} with the {\it dlink} argument pointing
to the directory in which the link is located and the {\it components}
argument being the name of the link whose attributes are to be
retrieved.  

Compatability note: {\bf p\_get\_dir} was named {\bf get\_vdir} or
{\bf p\_get\_vdir()} in releases of Prospero before Alpha.5.2.  Those
older interfaces are still available but should be converted.
release is backwards-compatible with those older uses.
Please note that the Alpha.5.3 release of {\bf p\_get\_dir()} will not
moify the {\it dlink}, but that previous releases did corrupt the {\it
dlink} while expanding a union lnk.

{\bf mk\_vdir}({\it char path[], int flags}) creates a new virtual
directory with 
the new name {\it path} in the currently active virtual system.  {\it
flags} should usually be 0; the only flag currently defined is {\sc
MKVD\_LPRIV}, which causes the directory to be created with very
limited permissions available to the creator.  See the documentation
of the {\tt CREATE-OBJECT} command in the protocol specification if
you want a better explanation of this option.
{\bf mk\_vdir} returns {\sc psuccess} (0) on success and an error code
on failure. 

This interface to this function will change in a later version of the
library to be {\bf p\_mk\_ndir()}, with a corresponding {\bf p\_mk\_dir}
that takes a {\it VLINK} referring to the directory and a string which
is the new link name.

{\bf pget\_am}({\it VLINK link,TOKEN *ainfop, int methods}) returns
the access method that should be used to access the object referenced
by {\it link}.  {\it *ainfop} is a pointer to a variable of type
TOKEN.  When {\bf pget\_am} returns, this variable will be a NULL
pointer if no appropriate access methods were available or will point
to the value of the best {\sc access-method} attribute associated with
the object referenced by {\it link} if appropriate methods were
available.  When more than one appropriate access method is available,
{\bf pget\_am} attempts to choose the least expensive one.  

{\it methods} is a bit-vector identifying the methods that are acceptable
to the application.  The methods presently supported are: the local
filesystem ({\sc p\_am\_local}), anonymous FTP ({\sc p\_am\_aftp}),
regular FTP ({\sc p\_am\_ftp}), Sun's Network File System ({\sc
p\_am\_nfs}), the Andrew File System ({\sc p\_am\_afs}), the Gopher
distributed directory service binary and text file retrieval protocols
({\sc p\_am\_gopher}), and telnettable services ({\sc p\_am\_telnet}).
Note that to effectively use the ({\sc p\_am\_ftp}) access method, the
server on the remote end will have to know that the user has an
account valid for FTP on the server.  {\bf pget\_am} returns {\sc
p\_am\_error} (0) on failure and leaves an error code in {\tt perrno}.
Upon success, {\bf pget\_am} returns the value of the access method
that was chosen.

This interface returns information that allows you to retrieve a file,
but does not do any of the work of retrieving it.  We expect most
programmers to use the {\bf pfs\_open} or {\bf pfs\_fopen} interfaces
instead.  The only exception is the TELNET access methods

{\bf PATTRIB pget\_at}({\it VLINK link,char atname[]}) returns a list of values of
the {\it atname} attribute for the object referenced by {\it link}.
If {\it atname} is {\sc null}, all attributes for the referenced
object are returned.  If {\it atname} is a string, it is a string
which is just a plus-separated list of attribute specification options
to the {\tt EDIT-OBJECT-INFO} protocol message.  {\bf pget\_at}
returns {\sc null} on failure, or when no attributes are found.  On
failure, an error code is left in {\tt perrno}.  On success, {\tt
perrno} is explicitly set to {\tt PSUCCESS}.

If the object has been forwarded, pget\_at() will follow the
forwarding pointers, just as other PFS library functions do.  If the
object has been forwarded, pget\_at() will modify {\it link}  so that
the link's {\tt host} and {\tt hsoname} members refer to the link's
new location.

This function will be renamed in a later version of this library.  The
new function will be named {\bf p\_get\_at}.

{\bf rd\_vdir}({\it dirarg,comparg,dir,flags}) lists the directory
named by {\it dirarg} (relative to the current working directory or
the root of the active virtual system) returning the links whose names
match {\it comparg}.  {\it dir} is a Prospero directory structure that
is filled in.  {\it flags} can suppress the expansion of union
links ({\sc rvd\_union}), force their expansion ({\sc rvd\_expand}),
request the return of link attributes ({\sc rvd\_attrib}), suppress
sorting of the directory links ({\sc rvd\_nosort}), suppress use of
cached data when resolving names ({\sc rvd\_nocache}), or request the
return of a reference to the named directory, suppressing the return
of its contents ({\sc rvd\_dfile\_only}).  {\bf rd\_vdir} returns {\sc
psuccess} (0) on success and an error code on failure.

As a special case, if the {\it comparg} is a null pointer or the empty
string and the {\it dirarg} refers to a link that is not a  DIRECTORY,
then a directory entry containing a single link to the {\it vlink}
named by comparg is returned; in that special case, this interface
behaves similarly to {\bf rd\_slink}.

This function's interface will change; it will probably be
renamed {\bf p\_get\_ndir()}.

{\bf VLINK rd\_vlink}({\it path}) is an alternative interface for
resolving names.  {\bf rd\_vlink} returns the single link named by
{\it path}.  Its function is equivalent to calling {\bf rd\_vdir} with
{\it comparg} set to the last component of the path and {\it dirarg}
set to the prefix.  {\bf rd\_vlink} returns {\sc null} on failure
leaving an error code in {\tt perrno}.  {\bf rd\_vlink()} will also
expand symbolic links it encounters, whereas {\bf rd\_vdir()} returns
the symbolic links in a directory unexpanded.  

{\bf {\it VLINK} rd\_slink}({\it path}) works just like {\bf
rd\_vlink}, except it will not expand symbolic links.


{\bf pfs\_open}({\it VLINK vl,int flags}) and
{\bf FILE *pfs\_fopen}({\it VLINK vl, char *type}) are identical to {\bf open} and {\bf fopen} in
the C library except that instead of a filename, they take a pointer
to a Prospero 
virtual link structure and open the file referenced by the link.
Note that they currently do not work to create files; indeed, they
inherently can't, since they accept a pointer to an already existing
link.   {\bf pfs\_open} does not take the third optional {\it mode}
argument that {\bf open} takes, since Prospero's access control list
mechanism does map well onto the {\sc unix} protection modes.

For files which are not already mapped into the local {\sc unix}
filesystem, these functions work by retrieving the file as a temporary
file; a reference to this temporary file is then returned.  In the
current implementation, we do not cache files; a new copy is retrieved
every time you call pfs\_open() or pfs\_fopen().  If you want to use
the same data more than once (e.g., display it via a paging program
and then offer to save it), it will speed up your program
substantially if you know that {\bf pfs\_open()} and {\bf
pfs\_fopen()} return file references which you can run {\bf lseek()}
or {\bf fseek()} on, respectively.

Until Prospero release Alpha.5.2, the {\bf pfs\_open} and {\bf
pfs\_fopen} calls were in libpcompat, not in libpfs.

\section{Pcompat Library}

The compatibility library includes replacements for existing system
calls and library routines that interact with the directory service.
The replacements optionally resolve names using the Prospero file
system.  The behavior depends on the value of the {\tt pfs\_enable}
global variable.  Possible values are defined in {\it pcompat.h} and
are described below.  Note that {\tt pfs\_enable} exists in only a
single instance, even in a multithreaded context; setting it for one
thread sets it for all.

\begin{sloppypar}
The default Prospero installation procedure leaves the compatibility
library in {\tt lib/pcompat/libpcompat.a}.  Programs linked with the
compatibility library should also be linked with the pfs library,
since the compatibility library uses some functions in libpfs.
\end{sloppypar}

The routines in the compatibility library are self-initializing; they
will call p\_initialize() and initialize all data structures
internally.  This makes it possible to relink existing programs with
the compatibility library with less effort.

Like the POSIX readdir(), the Prospero readdir() is not
multithread-safe because it uses internal data structures.  We would
gladly accept a contributed readdir\_r(), but will not write it
ourselves until a strong need appears.

As of this writing, the compatibility library does not run on as many
machines as the pfs library does.  Specifically, the compatibility
library is known not to work on {\sc HP-UX} and on {\sc AIX}.
Therefore, use of the pfs library is suggested for maximal
portability.  The compatibility library is not compiled by default.
(See the Prospero installation instructions for instructions on how to
compile it.).

If you are interested in the pcompat library, you should also look at
the Prospero User's Manual, in the section titled ``The Compatibility
Library''.

Setting the environment variable {\tt PFS\_DEBUG} to a numeric value will
cause the PCOMPAT library to set the PFS library's value of {\tt
pfs\_debug} to that value.  This is useful for debugging applications
that use the compatibility library.

By default, the pfs compatability library will report prospero errors
encountered by compatibility functions such as open() to {\tt stderr}.
You can silence these error messages by setting the variable {\tt int
pfs\_quiet} in your program to a non-zero value or by defining your
own global variable {\tt pfs\_quiet} with a non-zero initialized
value.  The global variable {\tt pfs\_quiet} is not multi-threaded; a
single instance of it is shared among multi-threaded programs.

\begin{table}
\begin{center}
\caption{Settings for the {\tt pfs\_enable} global variable\label{pfsenable}}
\vspace{0.1in}
\begin{tabular}{|l|p{3.9in}|} \hline
Value & Meaning \\ \hline \hline
PMAP\_DISABLE & Never resolve names within the virtual system \\ \hline 
PMAP\_ENABLE & Always resolve names within the virtual system \\ \hline 
PMAP\_COLON & Resolve names within the virtual system if they contain a : \\ \hline 
PMAP\_ATSIGN\_NF & Resolve names within the virtual system by default, but
treat names beginning with an @ or full path names that
don't exist in the virtual system as native file names \\ \hline 
PMAP\_ATSIGN & Resolve names within the virtual system by default, but 
treat names beginning with an @ as native file names \\ \hline
\end{tabular}
\vspace{-0.1in}
\end{center}
\end{table}

\subsection{Entry Points}

\begin{tabbing}
{\Large \bf Entry points:} \= {\bf closedir creat, execve,
open, opendir, readdir, scandir,}\\
\>{\bf seekdir, stat, telldir, and pfs\_access}.
\end{tabbing}

\noindent {\bf closedir, creat, execve, open, opendir, readdir, scandir,
seekdir, stat}, and {\bf telldir} are identical to the entry points
with the same names in the standard C library except that, depending
on the value of the {\tt pfs\_enable} variable, file names may be resolved
using Prospero.

{\bf pfs\_access}({\it char *path,char *npath,int npathlen, int
flags}) accepts a name, {\it path}, that is to be resolved using
Prospero.  {\bf pfs\_access} resolves the name, selects an access
method, mounts the appropriate file system or retrieves the file if
necessary, and returns a new name in {\it npath} that may be passed to
open.  {\it npath} must be a buffer large enough to hold the new name,
and its size must be passed in {\it npathlen}.  By setting {\it
flags}, it is possible to specify that the file is to be created if it
does not exist ({\sc pfa\_create}), or to indicate that the file will
be opened read only ({\sc pfa\_ro}). {\bf pfs\_access} returns {\sc
psuccess} (0) or {\sc pmc\_delete\_on\_close} on success.  A return
value of {\sc pmc\_delete\_on\_close} indicates that the file has been
cached on the local system and that the calling application should
delete the cached copy when done with it.  Any other return code
indicates failure.

{\bf Warning:} As of this writing, the {\sc pfa\_create} flag has not
been fully implemented.  

\end{document}
