--- /dev/null
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin vfs-filesystems n 1.0]
+[copyright {2001-2003 Vince Darley <vincentdarley@users.sourceforge.net>}]
+[copyright {2003 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Tcl-level Virtual Filesystems}]
+[titledesc {Filesystems provided by tclvfs}]
+[require Tcl 8.4]
+[require vfs [opt 1.2]]
+[require vfs::zip [opt 1.0]]
+[require vfs::mk4 [opt 1.6]]
+[require vfs::tar [opt 0.9]]
+[require vfs::ftp [opt 1.0]]
+[require vfs::ns [opt 1.0]]
+[require vfs::webdav [opt 0.1]]
+[require vfs::http [opt 0.5]]
+[require vfs::urltype [opt 1.0]]
+[description]
+
+The package [package vfs] provides not only the means to implement a
+virtual filesystem at the tcl level, but also a number of ready to be
+used filesystems as well.
+
+[para]
+
+Each of these filesystem exists as its own package, and can be
+accessed through [cmd {package require vfs::NAME}].
+
+The whole set of these virtual filesystems is known informally as
+'[term vfslib]'.
+
+[section {SUPPORTED VFS TYPES}]
+
+Currently supported are ftp, tar, http, zip, mk4, ns, and webdav.
+
+In addition there is the ability to mount any 'urltype' as a new
+directory, provided an appropriate vfs is supported. This means that
+you can treat urls based on the schmes [emph ftp://], [emph http://]
+and [emph file://] as files. To do this, simply evaluate the command
+
+[cmd {vfs::urltype::Mount ftp}]
+
+for example. Any access inside the new volume will result in an
+attempt to require a package through
+
+[cmd {package require vfs::${type}}], which must therefore exist, or
+errors will be thrown.
+
+If a filesystem is loaded, use the associated command listed below to
+mount a source for that filesystem as a tcl directory.
+
+[list_begin definitions]
+[call [cmd vfs::zip::Mount] [arg path] [arg to]]
+
+Mount the zip file [arg path] as directory [arg to].
+
+[call [cmd vfs::mk4::Mount] [arg path] [arg to]]
+
+Mount the metakit database file file [arg path] as directory [arg to].
+
+[call [cmd vfs::tar::Mount] [arg path] [arg to]]
+
+Mount the tar file [arg path] as directory [arg to].
+
+[call [cmd vfs::ftp::Mount] [arg path] [arg to]]
+
+Mount the ftp url [arg path] as directory [arg to].
+
+[call [cmd vfs::ns::Mount] [arg path] [arg to]]
+
+Mount the tcl namespace [arg path] as directory [arg to].
+
+[call [cmd vfs::webdav::Mount] [arg path] [arg to]]
+
+Mount the webdav url [arg path] as directory [arg to].
+
+[call [cmd vfs::http::Mount] [arg path] [arg to]]
+
+Mount the http url [arg path] as directory [arg to].
+
+[call [cmd vfs::urltype::Mount] [arg path] [arg to]]
+
+Mount the url [arg path], of type [arg urltype] as directory [arg to].
+
+[list_end]
+
+
+[section LIMITATIONS]
+
+Most of the vfs types listed above have not been very well debugged as
+yet. Please test them!
+
+
+[see_also vfs vfs-fsapi]
+[keywords vfs filesystem file vfslib zip tar webdav ftp http namespace metakit]
+[manpage_end]
--- /dev/null
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin vfs-fsapi n 1.0]
+[copyright {2001-2003 Vince Darley <vincentdarley@users.sourceforge.net>}]
+[copyright {2003 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Tcl-level Virtual Filesystems}]
+[titledesc {API for the implementation of a filesystem in Tcl}]
+[require Tcl 8.4]
+[require vfs [opt 1.2]]
+[description]
+
+This document explains the API used by the package [package vfs]
+to communicate with filesystem implementations written in tcl.
+
+[section {HANDLER OVERVIEW}]
+
+The package [package vfs] intercepts every filesystem operation which
+falls within a given mount point, and passes the operation on to the
+mount point's [cmd vfshandler] command in the interpreter which
+registered it.
+
+[para]
+
+If the handler takes appropriate action for each of the cases it is
+called for, a complete, perfect virtual filesystem will be achieved,
+indistinguishable to Tcl from the native filesystem.
+
+(CAVEATS: Right now [package vfs] does not expose to Tcl all the
+permission-related flags of [cmd glob]).
+
+[para]
+[list_begin definitions]
+
+[call [cmd vfshandler] [arg subcmd] [arg root] [arg relative] [arg actualpath] [arg args]...]
+
+The first argument specifies the operation to perform on behalf of the
+filesystem code in the tcl core, the remainder specify the file path
+on which to operate, in different forms, and parts, and any additional
+arguments which may be required to carry out the action.
+
+[nl]
+
+To demonstrate the treatment of a path by the generic layer we use
+[file C:/foo/bar/mount.zip/xxx/yyy] as an example and additionally
+assume that the following conditions are true:
+
+[list_begin enum]
+[enum]
+[file mount.zip] is a zip archive which has been mounted on top of
+itself,
+[enum]
+said zip archive contains a file with path [file xxx/yyy],
+[enum]
+the current working directory of the application is inside of
+directory [file xxx],
+[enum]
+and the command executed is [cmd {file exists yyy}].
+[list_end]
+
+The file separator between [arg root] and [arg relative] is omitted.
+Most filesystem operations need only the [arg relative] argument for
+their correct operation, but some actually require the other parts of
+the path.
+
+
+[list_begin definitions]
+
+[lst_item [arg subcmd]]
+
+This argument of the handler can be one of the following
+[method access], [method createdirectory], [method deletefile],
+[method fileattributes], [method matchindirectory], [method open],
+[method removedirectory], [method stat], or [method utime].
+
+[nl]
+
+The generic layer expects that the subcommands of a handler signal
+error conditions by calling [cmd {vfs::filesystem posixerror}] with
+the appropriate posix error code instead of throwing a tcl error. If
+the latter is done nevertheless it will be treated as an unknown posix
+error.
+
+[nl]
+
+There are three exceptions to the rule above: If any of [method open]
+(when an interpreter is given), [method matchindirectory], and
+
+[method fileattributes] (for a set or get operation only) throw a tcl
+error, this error will be passed up to the caller of the filesystem
+command which invoked the handler. Note that this does not preclude
+the ability of these subcommands to use the command
+
+[cmd {vfs::filesystem posixerror}] to report more regular filesystem
+errors.
+
+
+[lst_item [arg root]]
+
+Part of the specification of the path to operate upon. It contains the
+part of the path which lies outside this filesystem's mount point. For
+example outlined above its value will be [file C:/foo/bar/mount.zip].
+
+[lst_item [arg relative]]
+
+Part of the specification of the path to operate upon. It contains the
+part of the path which lies inside this filesytem. For example
+outlined above its value will be [file xxx/yyy].
+
+[lst_item [arg actualpath]]
+
+Part of the specification of the path to operate upon. It contains the
+original (unnormalized) name of the path which was used in the current
+command wherever it originated (in Tcl or C). For example outlined
+above its value will be [file yyy].
+
+[list_end]
+[list_end]
+
+[section {HANDLER METHODS}]
+[list_begin definitions]
+
+
+[call [cmd vfshandler] [method access] [arg root] [arg relative] [arg actualpath] [arg mode]]
+
+Signal a posix error if the specified access [arg mode] (an integer
+number) is not compatible with the file or directory described by the
+path. The generic layer will ignore any non-empty return value.
+
+[nl]
+
+The command [cmd vfs::accessMode] (see section
+
+[sectref {HANDLER ENVIRONMENT}]) can be used to convert the integer
+[arg mode] into an easier to check string value.
+
+
+[call [cmd vfshandler] [method createdirectory] [arg root] [arg relative] [arg actualpath]]
+
+Create a directory with the given name. The command can assume that
+all sub-directories in the path exist and are valid, and that the
+actual desired path does not yet exist (Tcl takes care of all of that
+for us).
+
+
+[call [cmd vfshandler] [method deletefile] [arg root] [arg relative] [arg actualpath]]
+
+Delete the given file.
+
+
+[call [cmd vfshandler] [method fileattributes] [arg root] [arg relative] [arg actualpath] [opt [arg index]] [opt [arg value]]]
+
+The command has to return a list containing the names of all
+acceptable attributes, if neither [arg index] nor [arg value] were
+specified.
+
+[nl]
+
+The command has to return the value of the [arg index]'th attribute if
+the [arg index] is specified, but not the [arg value]. The attributes
+are counted in the same order as their names appear in the list
+returned by a call where neither [arg index] nor [arg value] were
+specified. The first attribute is has the index [const 0].
+
+[nl]
+
+The command has to set the value of the [arg index]'th attribute to
+[arg value] if both [arg index] and [arg value] were specified for the
+call.
+
+
+[call [cmd vfshandler] [method matchindirectory] [arg root] [arg relative] [arg actualpath] [arg pattern] [arg types]]
+
+Return the list of files or directories in the given path which match
+the glob [arg pattern] and are compatible with the specified list of
+[arg types]. The specified path is always the name of an existing
+directory.
+
+[nl]
+
+[emph Note:] As Tcl generates requests for directory-only matches from
+the filesystems involved when performing any type of recursive
+globbing this subcommand absolutely has to handle such (and file-only)
+requests correctly or bad things (TM) will happen.
+
+[nl]
+
+The commands [cmd vfs::matchDirectories] and [cmd vfs::matchFiles]
+(see section [sectref {HANDLER ENVIRONMENT}]) can aid the
+implementation greatly in this task.
+
+
+[call [cmd vfshandler] [method open] [arg root] [arg relative] [arg actualpath] [arg mode] [arg permissions]]
+
+Either returns a list describing the sucessfully opened file, or
+throws an error describing how the operation failed.
+
+[nl]
+
+The list returned upon success contains at least one and at most two
+elements. The first, obligatory, element is always the handle of the
+channel which was created to allow access to the contents of the
+file. If specified the second element will be interpreted as a
+callback, i.e. a command prefix. This prefix will always be executed
+as is, i.e. without additional arguments. Any required arguments have
+to be returned as part of the result of the call to [method open].
+
+[nl]
+
+If present the specified callback will be evaluated by the generic
+filesystem layer just before the channel whose handle was returned as
+the first element of the list is closed. Additionally all available
+data will have been flushed into it. This means, for example, that the
+callback can seek to the beginning of the said channel, read its
+contents and then store the gathered data elsewhere. In other words,
+this callback is not only crucical to the cleanup of any resouces
+associated with an opened file, but also for the ability to implement
+a filesystem which can be written to.
+
+[nl]
+
+Under normal circumstances return code and any errors thrown by the
+callback itself are ignored. In that case errors have to be signaled
+asychronously, for example by calling [cmd bgerror].
+
+However if, through a call of the subcommand [method internalerror],
+an error handling script has been specified for the file system, all
+errors thrown here will be passed to that script for further action.
+
+
+[list_begin definitions]
+
+[lst_item [arg mode]]
+can be any of [const r], [const w], [const a], [const w+], or [const a+].
+
+[lst_item [arg permissions]]
+determines the native mode the openend file is created with. Relevant
+only of the open [arg mode] actually requests the creation of a
+non-existing file, i.e. is not [const r].
+
+[list_end]
+[nl]
+
+[call [cmd vfshandler] [method removedirectory] [arg root] [arg relative] [arg actualpath] [arg recursive]]
+
+Delete the given directory. Argument [arg recursive] is a boolean. If
+the specified value is [const true] then even if the directory is
+non-empty, an attempt has to be made to recursively delete it and its
+contents. If the spcified value is [const false] and the directory is
+non-empty, a posix error ([const ENOTEMPTY]) has to be thrown.
+
+
+[call [cmd vfshandler] [method stat] [arg root] [arg relative] [arg actualpath]]
+
+The result has to be a list of keys and values, in a format acceptable
+to the builtin command [cmd {array set}]. It describes the contents of
+a stat structure. The order of the keys in the list is not important.
+
+[nl]
+
+Given this the subcommand should use something like
+
+[example {return [list dev 0 type file mtime 1234 ...].}]
+
+as the last command of its implementation.
+
+[nl]
+
+The following keys and their values have to be supplied by the
+filesystem:
+
+[list_begin definitions]
+[lst_item [const dev]]
+
+A long integer number, the device number of the path stat was called for.
+
+[lst_item [const ino]]
+
+A long integer number, the inode number of the path stat was called for.
+
+Each path handled by the filesystem should be uniquely identified by
+the combination of device and inode number. Violating this principle
+will cause higher-level algorithms which(have to) keep track of device
+and inode information to fail in all manners possible.
+
+[nl]
+
+An example of such an algorithm would be a directory walker using
+device/inode information to keep itself out of infinite loops
+generated through symbolic links. Returning non-unique device/inode
+information will most likely cause such a walker to skip over paths
+under the wrong assumption of having them seen already.
+
+[lst_item [const mode]]
+
+An integer number, the access mode of the path. It is this mode which
+is checked by the subcommand [method access].
+
+[lst_item [const nlink]]
+
+A long integer number, the number of hard links to the specified path.
+
+[lst_item [const uid]]
+
+A long integer number, the id of the user owning the virtual path.
+
+[lst_item [const gid]]
+
+A long integer number, the id of the user group the virtual path
+belongs to.
+
+[lst_item [const size]]
+
+A long integer number, the true size of the virtual path, in bytes.
+
+[lst_item [const atime]]
+
+A long integer number, the time of the latest access to the path, in
+seconds since the epoch. Convertible into a readable date/time by the
+command [cmd {clock format}].
+
+[lst_item [const mtime]]
+
+A long integer number, the time of the latest modification of the
+path, in seconds since the epoch. Convertible into a readable
+date/time by the command [cmd {clock format}].
+
+[lst_item [const ctime]]
+
+A long integer number, the time of the path was created, in seconds
+since the epoch. Convertible into a readable date/time by the command
+[cmd {clock format}].
+
+[lst_item [const type]]
+
+A string, either [const directory], or [const file], describing the
+type of the given path.
+
+[list_end]
+[nl]
+
+[call [cmd vfshandler] [method utime] [arg root] [arg relative] [arg actualpath] [arg actime] [arg mtime]]
+
+Set the access and modification times of the given file (these are
+read with [method stat]).
+
+[list_end]
+
+
+[section {HANDLER ENVIRONMENT}]
+
+The implementation of a filesystem handler can rely on the
+existence of the following utility commands:
+
+[list_begin definitions]
+[call [cmd vfs::accessMode] [arg mode]]
+
+This commands converts an access [arg mode] given as integer into a
+string, one of [const F], [const X], [const W], [const XW], [const R],
+[const RX], and [const RW].
+
+
+[call [cmd vfs::matchDirectories] [arg types]]
+
+Checks if the glob types specification ask for the inclusion of
+directories. Returns a boolean result. [const true] is returned if
+types does ask for directories, else [const false].
+
+
+[call [cmd vfs::matchFiles] [arg types]]
+
+Checks if the glob types specification ask for the inclusion of
+files. Returns a boolean result. [const true] is returned if types
+does ask for directories, else [const false].
+
+
+[call [cmd vfs::matchCorrectTypes] [arg types] [arg filelist] [opt [arg inDir]]]
+
+Returns that subset of the [arg filelist] which are compatible with
+the [arg types] given. The elements of [arg filelist] are either
+absolute paths, or names of files in the directory [arg indir]. The
+latter interpretation is taken if and only if the argument [arg indir]
+is specified.
+
+
+[list_end]
+
+[section {FILESYSTEM DEBUGGING}]
+
+To debug a problem in the implementation of a filesystem use code as
+shown below. This registers the command [cmd report] as the error
+handler for the filesystem, which in turn prints out the error stack
+provided by tcl.
+
+[para]
+[example {vfs::filesystem internalerror report
+
+proc report {} {
+ puts stderr $::errorInfo
+}}]
+
+[see_also vfs vfs-filesystems]
+[keywords vfs filesystem file]
+[manpage_end]
+
--- /dev/null
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin vfs n 1.0]
+[copyright {2001-2003 Vince Darley <vincentdarley@users.sourceforge.net>}]
+[copyright {2003 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc {Tcl-level Virtual Filesystems}]
+[titledesc {Filesystem management in Tcl}]
+[require Tcl 8.4]
+[require vfs [opt 1.2]]
+[description]
+
+The package [package vfs] provides commands to query, mount and
+unmount virtual filesystems implemented in Tcl. This is further
+facilitated through the provison of helper commands in a tcl script
+library. See section "HANDLER ENVIRONMENT" of [cmd vfs-fsapi] for
+more information.
+
+[para]
+
+Once a virtual filesystem is in place, the standard Tcl commands, like
+[cmd file], [cmd glob], [cmd cd], [cmd pwd], [cmd open], including all
+their C APIs in the Tcl library (e.g.
+
+[fun Tcl_FSOpenFileChannel], [fun Tcl_FSMatchInDirectory],
+...), can be used within the filesystem (and indeed, properly written
+extensions such as [package Tk] which may open or read files will also
+transparently access the virtual filesystem).
+
+[para]
+
+Because all of Tcl's filesystem activity passes through a single
+layer, every operation can be intercepted. This package does just
+that.
+
+This is also quite different from simply overloading the [cmd file]
+command in Tcl. We are actually providing replacements for C commands
+like [syscmd access], [syscmd stat], etc.
+
+By implementing a small number of low-level commands we ensure that
+all commands at higher levels will function irrespective of what is
+going on inside the filesystem layer.
+
+[para]
+
+Tcl's filesystem hooks operate on a per-process basis. This means
+every Tcl interpreter in the same process/application will see the
+same filesystem, including any virtual filesystems.
+
+[para]
+
+To access this package use the command [cmd {package require vfs}].
+
+This automatically registers the vfs hooks into Tcl's filesystem and
+provides the command [cmd vfs::filesystem]. The latter allows the
+registration of actual virtual filesystems. More in the upcoming
+section [sectref API].
+
+The hooks will not be removed until Tcl exits. If desired, control
+over this could be exposed to Tcl in the future.
+
+By and in itself the command above will have no further effect. Only
+after filesystem implementations have been registered and filesystems
+using them been mounted filesystem commands will actually be
+intercepted, and handled by the Tcl code of the mounted virtual
+filesystem.
+
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd vfs::filesystem] [method mount] [opt [option -volume]] [arg path] [arg command]]
+
+[term Mount]s a virtual filesystem at [arg path], making it
+useable. After completion of the call any access to a subdirectory of
+[arg path] will be handled by that filesystem. The filesystem is
+represented here by the [arg command] prefix which will be executed
+whenever an operation on a file or directory within [arg path] has to
+be performed.
+
+[nl]
+
+Whether the [arg command] is implemented in C or Tcl is of no
+relevance as long as it adheres to the API specified in
+
+[cmd vfs-fsapi] and is present in the interpreter where the mount
+operation is executed.
+
+[nl]
+
+If the option [option -volume] is specified the new mount point is
+also registered with Tcl as a new volume and will therefore from then
+on appear in the output of the command [cmd {file volumes}]. This is
+useful (and required for reasonable operation) for mounts like
+
+[const ftp://]. It should not be used for paths mounted inside the
+native filesystem.
+
+[nl]
+
+The new filesystem mounts will be observed immediately in all
+interpreters in the current process. If the interpreter is later
+deleted, all mounts which are intercepted by it will be automatically
+removed (and will therefore affect the view of the filesystem seen by
+all interpreters).
+
+
+[call [cmd vfs::filesystem] [method unmount] [arg path]]
+
+This unmounts the virtual filesystem which was mounted at
+[arg path]. An error is thrown if no filesystem was mounted there.
+
+After the completion of the operation the filesystem is not visible
+anymore, and any previous filesystem accessible through this path
+becomes accessible again.
+
+
+[call [cmd vfs::filesystem] [method info] [opt [arg path]]]
+
+A list of all filesystems mounted in all interpreters is returned, if
+no [arg path] argument was specified.
+
+Else the filesystem responsible for that [arg path] is examined and
+the command prefix used to handle all filesystem operations returned.
+
+An error is thrown if no filesystem is mounted for that [arg path].
+
+[nl]
+
+There is currently no facility for examining in which interpreter each
+command will be evaluated.
+
+
+[call [cmd vfs::filesystem] [method fullynormalize] [arg path]]
+
+Performs a full expansion of [arg path], (as per [cmd {file
+normalize}]). This includes the following of any links in the last
+element of [arg path].
+
+
+[call [cmd vfs::filesystem] [method posixerror] [arg int]]
+
+This command can be called by filesystem implementations during the
+execution of a filesystem operation to signal the posix error code of
+a failure. See also [syscmd vfs-fsapi].
+
+
+[call [cmd vfs::filesystem] [method internalerror] [arg command]]
+
+When used the specified [arg command] is registerd as the command to
+trap and report any internal errors thrown by filesystem
+implementations.
+
+[list_end]
+
+[section LIMITATIONS]
+
+The code of the package [package vfs] has only a few limitations.
+
+[para]
+
+[list_begin enum]
+
+[enum]
+
+One subtlety one has to be aware of is that mixing case-(in)sensitive
+filesystems and application code may yield unexpected results.
+
+[nl]
+
+For example mounting a case-sensitive virtual filesystem into a
+case-insensitive system (like the standard Windows or MacOS
+filesystems) and then using this with code relying on
+case-insensitivity problems will appear when accessing the virtual
+filesystem.
+
+[nl]
+
+Note that application code relying on case-insensitivity will not
+under Unix either, i.e. is inherently non-portable, and should be
+fixed.
+
+
+[enum]
+
+The C-API's for [method link] and [method lstat] are currently not
+exposed to the Tcl level. This may be done in the future to allow
+virtual filesystems implemented in Tcl to support the reading and
+writing of links.
+
+[enum]
+
+The public C-API filesystem function [fun Tcl_FSMatchInDirectory] is
+given a variety of type information in a [term Tcl_GlobTypeData]
+structure. Currently only the [term type] field of said strcuture is
+exposed to the tcl-level. Fields like [term permissions] and MacOS
+[term type/creator] are ignored.
+
+[list_end]
+
+
+[see_also vfs-filesystems vfs-fsapi]
+[keywords vfs filesystem file]
+[manpage_end]