RIP - REBOL Self Extracting Binary Archives
1. OVERVIEW
Here is a script for creating REBOL self-extracting file
archives that are BINARY rather than textual. The binary
format of the archive provides extra speed when downloading
applications from websites or ftp.
Each archive begins with a valid REBOL header followed by its
extraction code. Because the extraction code never gets
separated from the data, the archive is time-enduring (it
"rests in peace" because it contains the algorithm to revive
itself).
2. STANDARD
This archive format will become a standard for distributing
REBOL applications that require multiple files, such as image
files. The current standard will be posted on WWW.REBOL.COM.
Improvements to the standard can be contributed, see below.
3. OPERATION
Provide a directory name at the prompt or just press enter to
archive the current directory. Only REBOL related text and
image files will be archived (see the file-types block in the
code). The output file will be given the suffix .rip if you
do not provide a suffix.
To extract an archive, you can simply "do" it. This can be
executed from your OS shell by typing:
REBOL archive.rip
(where archive.zip is the name of your file) or from the
REBOL shell with:
do %archive.rip
or directly extract from a web site with:
do http://www.rebol.com/archives/demo.rip
In addition you can add a .RIP association to your OS to make
this action automatic.
4. IMPROVEMENTS
The benefit of the archive containing its own extraction code
is that it is consistent with its data format. An archive
can always extract its data, regardless of what changes are
made to the RIP standard later. This is the primary rule for
any future enhancements.
This script will be posted as the official archive standard
on our web site. However, it is open to your improvements.
If you want to improve it, here's how:
1. Make your changes to the script.
2. Review, optimize, and clean your changes.
3. Test your changes.
4. Document precisely what you did and why.
5. Send your new script to [EMAIL PROTECTED]
I'll accept or reject your changes. If accepted, I'll update
the header history to include your name, date, version, and a
summary of the change. The new script will be posted to our
REBOL.com web site. If your changes are rejected, I'll let
you know why. It could be that your changes don't meet the
primary objectives of the script or that they make it overly
complex and difficult to understand.
The REBOL,
-Carl
PS: Script below has only been tested with REBOL/View.
REBOL [
Title: "RIP - REBOL Binary Archiver"
Date: 22-Feb-2000
File: %rip.r
Author: "Carl Sassenrath"
Email: [EMAIL PROTECTED]
Version: 1.0.0
Purpose: {
Gathers and compresses files into a self extracting
archive file that has a REBOL header. Note that
resulting archive is BINARY for minimal size.
}
History: [
1.0.0 22-Feb-2000 "Carl Sassenrath" {Original code.}
]
]
file-types: [%.r %.txt %.html %.htm %.bmp %.jpg %.jpeg %.gif]
path: to-file ask {
Enter the directory path.
Press RETURN key for current directory,
or type a path in the form: dir/dir/dir
Directory? }
if empty? trim path [path: %./]
if (last path) <> #"/" [append path #"/"]
if not exists? path [print [path "does not exist"] halt]
file-list: []
archive: make binary! 32000
print "Archiving:"
foreach file read path [
if find file-types find/last file "." [
prin [tab file " "]
data: read/binary path/:file
prin [length? data " -> "]
data: compress data
print [length? data]
append archive data
append file-list reduce [file length? data]
]
]
print [newline "Total size:" length? archive "Checksum:" checksum archive newline]
filename: to-file ask "Output file name? "
if empty? trim filename [filename: %archive.rip]
if not find filename "." [append filename ".rip"]
if all [exists? filename not confirm reform ["Overwrite file" filename "? "]] [
print "stopped" halt
]
header: mold compose/deep [
REBOL [
Title: "REBOL Self-extracting Binary Archive (RIP)"
Date: (now)
File: (filename)
Note: (reform [{To extract, type REBOL} filename {or run REBOL and type: do}
filename])
]
file: (filename)
size: (length? archive)
path: (path)
files: (reduce [file-list])
check: (checksum archive)
secure none
if not exists? path [make-dir path]
archive: read/binary file
archive: next find/case/tail archive to-binary probe join "!DATA" ":"
if check <> checksum archive [print ["Checksum failed" check checksum archive]
halt]
print "Reviving:"
foreach [file len] files [
print [tab file]
data: decompress copy/part archive len
archive: skip archive len
either any [
not exists? path/:file
confirm reform [file "already exists - overwrite? "]
][write/binary path/:file data][print "skipped"]
]
]
insert archive reduce [header newline "!DATA:" newline]
write/binary filename archive
quit