TIP #430: ADD BASIC ZIP ARCHIVE SUPPORT TO TCL ================================================ Version: $Revision: 1.6 $ Author: Sean Woods Donal Fellows Poor Yorick Harald Oehlmann State: Draft Type: Project Tcl-Version: 8.6.3 Vote: Pending Created: Wednesday, 03 September 2014 URL: https://tip.tcl-lang.org430.html Post-History: ------------------------------------------------------------------------- ABSTRACT ========== This proposal will add basic support for mounting zip archive files as virtual filesystems to the Tcl core. TARGET TCL-VERSION ==================== This TIP targets TCL Version 8.7 or 9.0, whatever comes first. RATIONALE =========== Tcl/Tk relies on the presence of a file system containing Tcl scripts for bootstrapping the interpreter. When dealing with code packed in a self-contained executable, a chicken-and-egg problem arises when developers try to provide this bootstrap from their attached VFS with extensions like TclVfs. TclVfs runs in the Tcl interpreter. The interpreter needs /init.tcl/, which would mean that the filesystem containing /init.tcl/ is not present until after TclVfs mounts it yet that mount cannot happen until after /init.tcl/ has been loaded. Bootstrap filesystem mounts require built-in support for the filesystem that they use. With the inclusion of Zlib in the core (starting with 8.6, [TIP #244]), all that is required to implement a zip file system based VFS is to add a C-level VFS implementation to decode the zip archive format. Thus: this project. Note that we are prioritizing the zip archive format also because it is practical to generate the files without a Tcl installation being present; it is a format with widespread OS support. This makes it much easier to bootstrap a build of Tcl that uses it without requiring a native build of tclsh to be present. SPECIFICATION =============== There shall be new commands added to safe interpreters withing Tcl. All of which shall be in the *::zvfs* namespace. These commands shall include: * *zvfs::mount* ?/archive/? ?/mountpoint/? Mounts the ZIP file /archive/ at the location given by /mountpoint/, which will default to *zipfs:///archive/ if absent. With no arguments this command describes all current mounts, returning a list of pairs. * *zvfs::unmount* /archive/ Unmounts the ZIP file /archive/, which must have been previously mounted. Safe interpreters will not be given the mount or unmount commands. Already mounted file systems will be available via the *glob* and *file* commands. These commands, and any commands related to building archives will be marked with the unsafe bit within the *zipfs* ensemble, and will be removed from any interpreter through the normal mechanism to hide unsafe commands within the core. IMPLEMENTATION ================ I have adapted Richard Hipp's work on Tcl As One Big Executable (TOBE) to operate inside of a modern Tcl. That implementation consists of one C file (/tclZipvfs.c/). I have also prepared new behaviors for inside of Tcl_AppInit() to detect if a zip filesystem is attached to the current executable, and how to extract a "/main.tcl/" as well as the initial file systems for both Tcl and Tk. This work is checked in as the "/core_zip_vfs/" branch on both Tcl and Tk. C API ======= * *int TclZipfsInit(Tcl_Interp *interp);* > Initializes the C API for Zipfs. If called with a non-null /interp/, adds the commands for the zipfs Tcl API to the interpreter. Returns *TCL_OK* on success, and *TCL_ERROR* in all other cases. * *int TclZipfsMount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd);* > Mounts a zip file /zipname/ to the mount point /mntpt/. If /passwd/ is non-null, that string is utilized as the password to decrypt the contents. /mnpnt/ will always be relative to *zipfs:* * *int TclZipfsUnmount(Tcl_Interp *interp, const char *zipname);* > Unmount the file system created by a prior call to *TclZipfsMount()* BOOTSTRAPING ============== The mount and unmount commands are usable within the core as just another feature engine. A call to TclZipfsInit() will be inserted into tclBasic.c, immediately after the code to initialize zlib. A modified shell (tclkit.exe) will be generated by Make. This shell will: * Check if the executable has a zip archive attached. If so, that archive shall be mounted as *zipfs:/app*. * If /zipfs:/app" is present the interpreter will look for *boot/tcl/init.tcl*. If that file is present, the location for *$tcl_library* will be set to *zipfs:/app/boot/tcl*. * If /zipfs:/app/ is present the interpreter will look for *boot/tk/tk.tcl'. If present the location for *$tk_library* will be set to *zipfs:/boot/tk*. * If the file *pkgIndex.tcl* is present, the *$dir* variable will be set to *zipfs:/app* and the file will be sourced as if it were a package index. * If the file *main.tcl* is present, the file *zipfs://app/main.tcl* will be registered with *Tcl_SetStartupScript()* COPYRIGHT =========== This document has been placed in the public domain. ------------------------------------------------------------------------- TIP AutoGenerator - written by Donal K. Fellows