Entry points:¯ atalloc, atfree, atlfree, vlalloc, vlfree, vllfree, add_vlink,
del_vlink, p_get_dir, mk_vdir, pget_am, pget_at, rd_vdir,
rd_vlink, pfs_open, and pfs_fopen.
PATTRIB atalloc( void), FILTER flalloc( void), TOKEN tkalloc( char *s), ACL acalloc( void), and VLINK vlalloc( 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 gl_internal_err.h which currently raises an error condition and aborts program execution. Its behavior may be changed by resetting the value of the global variable internal_error_handler (defined in gl_internal_err.h to be a function with some alternative behavior (such as popping up a window with a failure message and offering to restart the application or exit). Since the only failure condition for these functions is running out of available memory, they do not set perrno.
atfree( PATTRIB at), flfree( FILTER fl), acfree( ACL ac), and vlfree( VLINK vl) free the storage allocated to at, fl, ac, and vl. They also free any standard Prospero memory structures referenced by the members of these structures; for example, freeing a VLINK will also free any Prospero string referenced by the VLINK's host member. They also free any memory referred to by the structure's app.ptr member, using whatever function the user set via atappfree(), flappfree(), acappfree(), or vlappfree(), as appropriate. The user can disable this feature, if it has already been enabled, by calling the appropriate xx appfree() function with a null pointer as its argument. xx free() is a guaranteed no-op.
atlfree( at) and vllfree( vl) free at and vl and all successors in a linked list of such structures. They do not return error codes nor do they set perrno, since they cannot fail. tkalloc( s) initializes the token member of the TOKEN structure it allocates to be a copy of s.
FILTER flcopy( FILTER fl, int recurse) will return a copy of the filter fl. If the recurse flag is non-zero, then it will also recursively copy the linked list of filters that fl points to the head of.
char * stcopy( char *s) allocates an area of memory large enough to hold the string s and copies 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 stsize( char * string). An alternative interface to stcopy is char * stalloc( size_t nbytes). stalloc allocates an area of uninitialized memory large enough to hold nbytes bytes of data and returns a pointer to it. Another interface is char *stcopyr( char *source, char *dest). The sequence:
a = stcopyr("string", a);will yield results functionally equivalent to the sequence:
stfree(a); a = stcopy("string");The only difference is that stcopyr() attempts to reuse the already allocated space, if available. This avoids the overhead of extra calls to malloc() and free(), and is therefore frequently more efficient than the equivalent longer sequence of calls. The existing Prospero libraries and utilities make frequent use of stcopyr() for this purpose.
Also note that
a = stcopyr("foo", (char *) NULL) is equivalent to
a = stcopy("foo");
Memory allocated by all of these interfaces should be freed with
stfree( st). stfree( (char *) NULL) is a guaranteed
no-op. The various interfaces to stcopy() all call
out_of_memory() when appropriate.
A frequent cause of problems when using memory allocation functions is freeing the same chunk of memory twice. By default, there is consistency checking code in the allocators and freeing functions.
(This may be turned off by undefining P_ALLOCATOR_CONSISTENCY_CHECK in gostlib.h.) If any double freeing is detected, internal_error_handler() will be called.
A programmer may also easily check for memory leaks by looking at the global variables 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.
add_vlink( direct,lname,l,flags) adds a new link l to the directory named direct with the new link name lname. direct is a string naming the directory that is to receive the link. If flags is AVL_UNION, then the link is added as a union link. add_vlink returns 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 p_add_nlink(), with a corresponding p_add_link that takes a VLINK instead of a string for the direct argument.
del_vlink( path,flags) deletes the link named by path. At present, flags is unused. del_vlink returns 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 p_del_nlink(), with a corresponding p_del_link() that takes a VLINK instead of a string for the path argument.
p_get_dir( VLINK dlink,char *components,VDIR dir,int flags,TOKEN acomp) contacts the Prospero server on host dlink->host to read the directory dlink->hsoname, resolving union links that are returned and applying dlink->filters, if set.
If components is a null pointer, all links in the directory are returned. If components is a non-null string, only those links with names matching the string. The string may be a wildcarded name containing the * and ? 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.
p_get_dir() will always, in addition to any other links it might return, return any link whose literal name is the 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 components string (ba*na), in addition to matching banana and banananana, also (as an important special case) matches the component whose literal name is (ba*na).
dir is a Prospero directory structure that is filled in. flags can suppress the expansion of union links (GVD_UNION), force their expansion (GVD_EXPAND), request the return of link attributes on the VLINK structure's lattrib member (GVD_ATTRIB), and suppress sorting of the directory links (GVD_NOSORT). acomp should normally be NULL. For many applications, one does not need to call this procedure, and should use rd_vdir and rd_vlink instead. p_get_dir returns 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 p_get_dir with the dlink argument pointing to the directory in which the link is located and the components argument being the name of the link whose attributes are to be retrieved.
Compatability note: p_get_dir was named get_vdir or 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 PreAlpha.5.3 and later releases of p_get_dir() will not inappropriately modify the dlink, but that previous releases did corrupt the dlink while expanding a union lnk.
mk_vdir( char path, int flags) creates a new virtual directory with the new name path in the currently active virtual system. flags should usually be 0; the only flag currently defined is MKVD_LPRIV, which causes the directory to be created with very limited permissions available to the creator. See the documentation of the CREATE-OBJECT command in the protocol specification if you want a better explanation of this option. mk_vdir returns 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 p_mk_ndir(), with a corresponding p_mk_dir that takes a VLINK referring to the directory and a string which is the new link name.
pget_am( VLINK link,TOKEN *ainfop, int methods) returns the access method that should be used to access the object referenced by link. *ainfop is a pointer to a variable of type TOKEN. When 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 ACCESS-METHOD attribute associated with the object referenced by link if appropriate methods were available. When more than one appropriate access method is available, pget_am attempts to choose the least expensive one.
methods is a bit-vector identifying the methods that are acceptable to the application. The methods presently supported are: the local filesystem (P_AM_LOCAL), anonymous FTP (P_AM_AFTP), regular FTP (P_AM_FTP), Sun's Network File System (P_AM_NFS), the Andrew File System (P_AM_AFS), the Gopher distributed directory service binary and text file retrieval protocols (P_AM_GOPHER), and telnettable services (P_AM_TELNET). Note that to effectively use the (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. pget_am returns P_AM_ERROR (0) on failure and leaves an error code in perrno. Upon success, 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 pfs_open or pfs_fopen interfaces instead. The only exception is the TELNET access methods
PATTRIB pget_at( VLINK link,char atname) returns a list of values of the atname attribute for the object referenced by link. If atname is NULL, all attributes for the referenced object are returned. If atname is a string, it is a string which is just a plus-separated list of attribute specification options to the EDIT-OBJECT-INFO protocol message. pget_at returns NULL on failure, or when no attributes are found. On failure, an error code is left in perrno. On success, perrno is explicitly set to 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 link so that the link's host and 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 p_get_at.
rd_vdir( dirarg,comparg,dir,flags) lists the directory named by dirarg (relative to the current working directory or the root of the active virtual system) returning the links whose names match comparg. dir is a Prospero directory structure that is filled in. flags can suppress the expansion of union links (RVD_UNION), force their expansion (RVD_EXPAND), request the return of link attributes (RVD_ATTRIB), suppress sorting of the directory links (RVD_NOSORT), suppress use of cached data when resolving names (RVD_NOCACHE), or request the return of a reference to the named directory, suppressing the return of its contents (RVD_DFILE_ONLY). rd_vdir returns PSUCCESS (0) on success and an error code on failure.
As a special case, if the comparg is a null pointer or the empty string and the dirarg refers to a link that is not a DIRECTORY, then a directory entry containing a single link to the vlink named by comparg is returned; in that special case, this interface behaves similarly to rd_slink.
This function's interface will change; it will probably be renamed p_get_ndir().
VLINK rd_vlink( path) is an alternative interface for resolving names. rd_vlink returns the single link named by path. Its function is equivalent to calling rd_vdir with comparg set to the last component of the path and dirarg set to the prefix. rd_vlink returns NULL on failure leaving an error code in perrno. rd_vlink() will also expand symbolic links it encounters, whereas rd_vdir() returns the symbolic links in a directory unexpanded.
VLINK rd_slink( path) works just like rd_vlink, except it will not expand symbolic links.
pfs_open( VLINK vl,int flags) and FILE *pfs_fopen( VLINK vl, char *type) are identical to open and 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. pfs_open does not take the third optional mode argument that open takes; Prospero's access control list mechanism does not map well onto the UNIX protection modes.
For files which are not already mapped into the local 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 pfs_open() and pfs_fopen() return file references which you can run lseek() or fseek() on, respectively.
Until Prospero release Alpha.5.2, the pfs_open and pfs_fopen calls were in libpcompat, not in libpfs.