FSIO API Functions
pr_fs_t *pr_register_fs(pool *pool, const char *name, const char *path); pr_fs_t *pr_create_fs(pool *pool, const char *name); pr_fs_t *pr_get_fs(const char *path, int *exact); int pr_insert_fs(pr_fs_t *fs, const char *path); int pr_unregister_fs(const char *path);
The pr_register_fs()
function is the one that FSIO modules should
use primarily, for it handles the creation and registration of an
pr_fs_t
in one shot. The pr_fs_t *
returned allows
the caller to store that pointer for other, module-specific, purposes. The
name argument is merely a descriptive label for the created
pr_fs_t
. The path argument declares where the created
pr_fs_t
is to be registered in the filesystem, and is specific
only to the created pr_fs_t
; an FSIO module may call
pr_register_fs()
multiple times for multiple paths. Functionally,
pr_register_fs()
is equivalent to calling
pr_create_fs()
and pr_insert_fs()
.
The pr_fs_t *
returned by both pr_register_fs()
and
pr_create_fs()
has all of its function pointers initialized
to the system defaults. To put the FSIO module's custom versions into effect,
merely overwrite the appropriate function pointer. Note that the FSIO access
functions will check for NULL
function pointers and return
EPERM
if need be, meaning that a given filesystem operation can
easily be disabled by setting its pr_fs_t
function pointer to
NULL
.
The pr_create_fs()
function instantiates an pr_fs_t
with the given name. This pr_fs_t *
could then be used
multiple times, passing the same pointer to pr_insert_fs()
for multiple paths.
The pr_insert_fs()
function inserts the given
pr_fs_t *
into a mapping of pr_fs_t
s maintained by
the FSIO layer. This mapping is sorted and searched according to the given
path; it is highly recommended that the path
field
of a created pr_fs_t
be left alone. If the given path
argument ends in a trailing slash, then that path will be treated a little
differently than non-trailing-slash paths by pr_get_fs()
.
Deferred-resolution paths, e.g. relative paths, and "~" and
"." prefixed paths (but not ".." prefixed paths),
are allowed. They will be resolved into full paths at login time, after
successful authentication by the user. This function will return
TRUE
upon successful insertion of the pointer into the map,
FALSE
otherwise. At this point, the FSIO layer does not handle
layering of FSIO modules, multiple modules that register identical paths; this
function returns FALSE
if there is already an pr_fs_t
in the map for handling the requested path.
The pr_get_fs()
function serves as the pr_fs_t
lookup/retrieval function, searching for the pr_fs_t
that should
handle the given path. If the returned pr_fs_t *
is
an exact match for the given path, meaning that there was an
pr_fs_t
in the FSIO layer's map whose path member matches
the given path exactly, then *exact
will have a
TRUE
when pr_get_fs()
returns. Otherwise,
*exact
will be FALSE
, meaning that the returned
pr_fs_t *
is a best-match pr_fs_t
that
probably handles paths higher up the filesystem hierarchy from the given
path. This function never returns NULL
, for there
is always a root pr_fs_t
to handle /
, meaning
all paths.
When searching for an pr_fs_t
to handle path,
pr_get_fs()
searches the map, starting at the root of
path and looking for more path-specific pr_fs_t
s. It
keeps tracks of pr_fs_t
s for directories, as opposed to specific
files, and distinguishes between them by looking for a trailing slash. For
example, if there was only two pr_fs_t
s in the FSIO map, the root
pr_fs_t
and one registered to handle
/path/to/dirand the path given to
pr_get_fs()
is
/path/to/dir/file1then the root
pr_fs_t
will be returned, as that is the
best-matching path. /path/to/dir
is considered to be a file, not
a directory, by this function. However, if instead of:
/path/to/dirthe other
pr_fs_t
was registered to handle:
/path/to/dir/then that
pr_fs_t
would be considered best-matching by the lookup
algorithm.
Finally, the pr_unregister_fs()
function does just that -- it
searches the FSIO layer's map for pr_fs_t
s whose paths match,
removes them from the map, and destroys them. It returns TRUE
upon
removing any matching pr_fs_t
s, FALSE
if there was
no matching pr_fs_t
in the map, if the given path was
NULL
, or if there is an attempt to remove the root
pr_fs_t
.
Custom FSIO Functions
The following are the function prototypes to which any custom FSIO functions
must adhere:
File function prototypes
int (*stat)(pr_fs_t *fs, const char *filename, struct stat *sbuf); int (*lstat)(pr_fs_t *fs, const char *filename, struct stat *sbuf); int (*rename)(pr_fs_t *fs, const char *oldpath, const char *newpath); int (*unlink)(pr_fs_t *fs, const char *path); int (*open)(pr_fs_t *fs, const char *path, int flags); int (*creat)(pr_fs_t *fs, const char *path, mode_t mode); int (*close)(pr_fs_t *fs, int fd); int (*read)(pr_fs_t *fs, int fd, char *buf, size_t count); int (*write)(pr_fs_t *fs, int fd, const char *buf, size_t count); off_t (*lseek)(pr_fs_t *fs, int fd, off_t offset, int whence); int (*link)(pr_fs_t *fs, const char *oldpath, const char *newpath); int (*symlink)(pr_fs_t *fs, const char *oldpath, const char *newpath); int (*readlink)(pr_fs_t *fs, const char *path, char *buf, size_t buflen); int (*truncate)(pr_fs_t *fs, off_t length); int (*chmod)(pr_fs_t *fs, const char *path, mode_t mode); int (*chown)(pr_fs_t *fs, const char *path, uid_t owner, gid_t group);
The
Directory function prototypes
Note that the
FSIO Access Functions
open()
and creat()
prototypes are a little
different because, in the system version, they return and operate on file
descriptors. As the FSIO abstraction layer uses pr_fh_t
s instead
of ints as "file handles", these functions return
pr_fh_t
s, which must be captured by the caller for later use with
the other custom FSIO functions.
int (*chroot)(pr_fs_t *fs, const char *path);
int (*chdir)(pr_fs_t *fs, const char *path);
void *(*opendir)(pr_fs_t *fs, const char *name);
int (*closedir)(pr_fs_t *fs, void *dir);
struct dirent *(*readdir)(pr_fs_t *fs, void *dir);
int (*mkdir)(pr_fs_t *fs, const char *path, mode_t mode);
int (*rmdir)(pr_fs_t *fs, const char *path);
opendir(3)
function returns a DIR *
,
while the corresponding FSIO access function returns a void *
.
This is to allow FSIO modules to use their own data types for directory
listings.
The FSIO access functions, the functions the present the unified front to
the core code (and to any modules who care to use the FSIO layer), are
divided into two groups, file-oriented functions and directory-oriented
functions. The difference is simply whether the function is intended to
act on a file, or a directory. The access arguments are similar to their
normal system or library counterpart functions. These functions are listed
in include/fsio.h.
Author: $Author: castaglia $
Last Updated: $Date: 2003/10/22 06:31:40 $
© Copyright 2000-2002 TJ Saunders
All Rights Reserved