From NISC.SRI.COM!unix!Teknowledge.COM!uw-beaver!rice!cs.utexas.edu!hellgate.utah.edu!helios.ee.lbl.gov!pasteur!cory.Berkeley.EDU!fadden Wed Nov 15 01:07:53 PST 1989 Article 397 of comp.binaries.apple2: Path: NISC.SRI.COM!unix!Teknowledge.COM!uw-beaver!rice!cs.utexas.edu!hellgate.utah.edu!helios.ee.lbl.gov!pasteur!cory.Berkeley.EDU!fadden >From: fadden@cory.Berkeley.EDU (Andy McFadden) Newsgroups: comp.binaries.apple2 Subject: NuLib v2.1.1 NuFX archiver DOCS Message-ID: <19354@pasteur.Berkeley.EDU> Date: 9 Nov 89 09:12:36 GMT Sender: news@pasteur.Berkeley.EDU Reply-To: fadden@cory.Berkeley.EDU (Andy McFadden) Organization: University of California, Berkeley Lines: 786 This is the documentation for NuLib v2.1.1, a NuFX (ShrinkIt-compatible) archiver written entirely in C. ----- NuFile eXchange (NuFX) Archive Utility NuLib v2.1.1 Documentation By Andy McFadden Updated November 8, 1989 Overview -------- NuLib is a shell-based NuFX archive utility, based loosely on "ARC" for the IBM PC and "ar" under UNIX. It allows you to perform certain operations on the same archives used by ShrinkIt (hence the name), including view archive contents, add to archive, extract from archive, and delete from archive. In addition, it will list and unpack files from Binary II archives. This program is primarily targeted at users of non-Apple II computer systems, from IBM PC compatibles to Sun workstations to DEC Vaxen. It will also be of use to people who use a GS/OS shell on the Apple //gs, such as APW, ORCA, or ECP-16 (although it is considerably slower than ShrinkIt). NuLib may require up to 256K of free RAM to function properly. Background ---------- An archive is a collection of one or more files stored as a single file. This allows groups of related files to be stored under a single filename, reducing directory clutter, and makes it possible to transfer groups of files without the use of a batch transfer utility. To reduce the space required to store the archives and the time it takes to transfer archives, most popular archiving programs automatically compress files as they are stored. Two popular compression methods are Huffman (variable-size codes are used, with smaller codes assigned to bytes that appear frequently) and Lempel-Ziv-Welch (LZW; finds common substrings in the file). Popular archiving programs include "BLU" (Apple II), "ShrinkIt" (Apple II), "ARC"/"PKARC" (MS-DOS), "PKZIP" (MS-DOS), "lharc" (MS-DOS/Amiga), "zoo" (MS-DOS/Amiga), "PackIt" (Macintosh), "StuffIt" (Macintosh), "tar" (UNIX), and "ar" (UNIX). UNIX archivers don't generally compress files; a separate program (called "compress" of all things) is usually used. NuLib works with archives that ShrinkIt produces (NuFX). New Features/Bug Fixes ---------------------- Major changes since last release: + UNIX and MS-DOS versions. + Some compression code (unsqueeze, unshrink). + Binary II operations. + Printing of archived files. How to Use NuLib ------------------ Usage: nulib option[suboption] archive [filespec1] [filespec2] [...] "option" is a single character, as specified below. "suboption" is one or more characters, which modify the performance of the option (see each specific option for details). "archive" is the name of a NuFX archive. It doesn't need to exist for the add, create, and move options. "filespecN" is the name of a file, either on disk or in the archive. More than one file may be named on the command line. The option/suboption string may be entered in upper or lower case, and may be preceeded by a hyphen (ex: "nulib -XT0 ..." is equivalent to "nulib -xt0 ..." and "nulib xt0 ..."). Suboptions may be entered in any order. Side note: Under APW, both the archive filename and all file specifications relating to files ON DISK are expanded by NuLib (device names, wildcards, etc). Under UNIX, all filename expansion and wildcards are handled by the shell or the kernal. The filenames of files in the ARCHIVE do not undergo wildcard expansion on any system. Examples: $ nulib av foo.shk file1 subdir/file2 Adds "file1" and "subdir/file2" to "foo.shk", listing each file as it is archived. $ nulib av foo.shk subdir Recursively adds all files in subdir and all files in subdirectories of subdir. $ nulib mv foo.shk =.doc (APW) $ nulib mv foo.shk *.doc (UNIX) $ nulib mv foo.shk *.doc (MS-DOS) Adds all files with the suffix ".doc" to the archive "foo.shk", listing them as it goes, then deletes them from the disk. $ nulib d+ foo.shk work/ Deletes all files in "foo.shk" that start with "work/"; this would likely be used to delete all files archived from the directory "work". No output is produced. The various options are: *** Add/Append files: nulib A[V][U|C|S][R][F[/]] archive files Quickly appends the specified files to the end of the archive. This option does not scan the archive to see if the files already exist, and will create a new archive file if one is not found. This option corresponds roughly to A)dd files on the ShrinkIt menu. If you add files from the current directory or a subdirectory of the current directory, then the entire partial pathname is stored (ex: "nulib av fubar.shk foo/bar/filename" will store "foo/bar/filename" in the archive "fubar.shk.") If you add files from directory that is not a subdirectory of the current directory, only the filename will be stored (ex: "nulib av fubar.shk ../zip/bang/filename" will store "filename" in the archive). Unfortunately, this does not work under UNIX, since filenames are expanded by the kernal instead of by NuLib. Wildcards are allowed, and subdirectories are recursively descended (the depth is limited only by the maximum length of a pathname and the number of files in the subdirectories), unless the R suboption is used. The R suboption will prevent subdirectories from being processed, so that "nulib av fubar.shk *" under UNIX will add all files in the current directory, but will not descend into any subdirectories. The V suboption displays the filenames as they are added. The U suboption adds a file without compressing it. The C suboption allows you to insert a file in the archive with a specific compression algorithm (specified by the argument "value", which must immediately follow the suboption - no spaces between. Ex: "nulib ac0v fubar.shk file1" would store "file1" in "fubar.shk" without compressing it). "value" corresponds to the appopriate thread_format as specified in the section on compression methods. The S suboption does not compress the file, but will store it as if it were by setting the thread_format field to "value". One use for this is adding compressed files without having to uncompress them first (ex: "nulib as1 foo.shk file1.qq" adds a squeezed file). This suboption could conceivably cause a NuFX extractor to crash; please don't use it unless you are sure of what you are doing. Note also that some compression methods (like ShrinkIt LZW) require both the "compressed length" and "uncompressed length" values to be correct; use of this suboption will (incorrectly) set them both to the current file length. Only one of U, C, or S may be specified. The F suboption allows specification of the filetype attribute. It should be three characters long, and will be matched against a list of standard ProDOS file types. Common ones are "BIN" (binary), "TXT" (text), "SRC" (source code), "OBJ" (object code), "EXE" (executable), and "NON" (typeless, the default). Both upper and lower case letters will match. If the filetype is followed by a "/", then the auxtype field will also be set. NuLib expects the auxtype to be a four-byte hexadecimal number; entering less than four digits could cause the auxtype to be misinterpreted. A good example is storing APW C source files: "nulib cvfSRC/000a nulib.shk file1.c file2.c ...". *** Binary II Operations nulib B[X][V][T][I] binary2-archive [archived-files] This option is included for compatibility with the older Binary II standard, since it is still in use by many communications programs. With no suboptions, this will list the information on the archived files specified by "archived-files". The X suboption extracts the named files from the archive, unsqueezing them if necessary. If the archived-files parameter is omitted, then all files will be listed or extracted. Note that matches are case-independent. When the V suboption is used in conjunction with the X suboption, the names of the archived files are printed as they are extracted. The V suboption has no effect otherwise. The T suboption will perform a text substitution as it works; see the section of conversion of line terminators for more information. If the filename of an extracted file would conflict with an existing file, the file will be overwritten and a message will be printed. If the "I" suboption is used, then NuLib will give an "overwrite (y/n)?" prompt. An affirmative answer overwrites the file; a negative answer will skip the file and continue processing. Attempting to perform NuFX operations on a Binary II archive will fail. If the file appears to be Binary II format, then a message indicating this will be printed. Providing transparent support for Binary II archives is not impossible, but isn't needed often enough to be worth doing. *** Create Archive nulib C[V][U|C|S][R][F[/]] archive files This is identical to the A option, but the "creating archive" message is suppressed. *** Delete from Archive nulib D[V][+] archive archived-files Deletes the named files from the archive. NuLib scans the archive, marking all records that start with the characters in the file specification (case-independent). If all files are marked for deletion, then the archive file itself is deleted. Otherwise, a new archive is created, the unmarked records are transferred, and the old archive is deleted. An error during this process will leave the original archive unmodified. Note that this does not require an exact match if the "+" suboption is used; "nulib d+ fubar.shk foo" will delete "foo", "Foozle", "food/recipies" and "food/stock." The V suboption prints the list of marked records. *** Freshen Archive nulib F[V][U|C|S][R][F[/]] archive files Updates files in the archive, but doesn't add any new files. Creates a new archive file, and either transfers the old record or adds the file depending on which is more recent. Only exact filename matches are allowed (case-independent), including partial paths. The archive being updated must already exist. Wildcards are allowed, and subdirectories are automatically expanded unless the R suboption is used. The V suboption displays the filenames as they are added. The U/C/S/F suboptions, explained under A)dd, only apply to files being added to the archive or being updated (files that aren't updated are left unaltered). Files that are updated will retain their previous filetype. New files will get either the default filetype, the filetype specified by the F suboption, or the actual filetype (under APW only) in that order. *** Command Help nulib H[NW] Displays the option help screen. Actually, running the program without specifying an archive name will print the help screen no matter what (with an exception made for the W option). The N suboption gives help with numbers; it lists the known compression methods and text translation types. The W suboption gives a brief listing of contributors, and how to contact me. *** Integrity Check nulib I[V] archive Verifies that the archive is intact. Does not modify the archive in any way. The V suboption prints a list of CRCs for each entire record (this is different from those listed by the Z option, which are only for the record headers, threads, and filename; this includes not only the headers but *all* threads as well). Note: There was a strange problem for a little while where deleting a record would change the CRC for the next record in the archive. I added debugging code, and it worked fine. I removed the debugging code, it it worked fine. I dunno. If you get a repeatable glitch please let me know. *** Move Files to Archive nulib M[V][U|C|S][R][F[/]] archive files This is identical to the A option, but the files are deleted after they are added to the archive. Note that the actual directory files are NOT deleted, unless they were given distinct record entries (NuLib and P8 ShrinkIt don't). *** Print an Archived File nulib P[V][T][+] archive files Print the contents of an archived file without extracting it. Useful for viewing archived text files without having to actually unpack them. Note this only allows viewing of data_threads; resource forks and disk images will not be displayed. I take no responsibility for pagination or filtering if funky control characters... The V suboption will print the file's name right before it is extracted. The + suboption allows you to specify the first part of a pathname; see the D or X options for details. The T suboption will perform a text substitution as it works; see the section on conversion of line terminators for more information. *** Table of Contents nulib T[VZ] archive With no suboptions, this lists only the filenames of the archived files. Not only does this make it easier to view the archive contents (the ShrinkIt output format is about 20 characters wide; this is 80), but the output is suitable for transmission via a pipe to other utilities. Using the V suboption will make it use ShrinkIt output format (same as using the V option); it is included mainly for people used to "ar". Using the Z suboption will dump everything known about the archive, including all information in headers, CRCs, relative file position, sizes of individual threads, etc. *** Update Archive nulib U[V][U|C|S][R][F[/]] archive files Updates files in the archive, keeping the archived file or the file listed on the command line, whichever is most recent (or exists). Creates a new archive file, and either transfers the old record or adds the file. Only exact filename matches are allowed (case-independent), including partial pathnames. The archive being updated must already exist. Wildcards are allowed, and subdirectories are automatically expanded unless the R suboption is used. The V suboption displays the filenames as they are added. The U/C/S/F suboptions, explained under A)dd, only apply to files being added to the archive (files that aren't updated are left unaltered). Note that the order of files in the archive will be preserved. Files that are updated will retain their previous filetype. New files will get either the default filetype, the filetype specified by the F suboption, or the actual filetype (under APW only) in that order. *** Verbose Archive Listing nulib V archive Lists the archive contents in a format indentical to that used by the ProDOS 8 ShrinkIt L)ist archive contents option. *** Extract from Archive nulib X[V][T][U][I][+] archive [archived-files] nulib E... The X and E options are synonymous. Extract the archived-files from the archive. If the file already exists, you are asked if you want to overwrite it. If part of a partial pathname does not exist, the subdirectory will be created. Omitting the "archived-files" specification will cause the entire archive to be unpacked. When files are archived, a pathname separator is stored (e.g., "/" for ProDOS and UNIX, "\" for MS-DOS, ":" for Mac HFS). During extraction, the pathnames are broken down into component file names, converted to names legal under the current operating system, and then recombined using the pathname separator for the current OS. This facilitates extraction of files archived under any OS, but can lead to filename conflicts that didn't exist when the files were added (e.g., a UNIX file that contained a backslash is unpacked under MS-DOS). If the filename of an extracted file would conflict with an existing file, the file will be overwritten and a message will be printed. If the "I" suboption is used, then NuLib will give an "overwrite (y/n)?" prompt. An affirmative answer overwrites the file; a negative answer will skip the file and continue processing. Note that extraction does not require an exact match if the "+" suboption is specified; "nulib x+ fubar.shk foo" will extract "FOO", "Foozle", "food/recipies" and "food/stock." This makes it possible to extract entire subdirectories at a time. The V suboption prints the list of marked records. The T suboption will perform a text substitution as it extracts; see the section on converson of line terminators for more information. The U suboption will extract the files without uncompressing them. This is rarely useful, but is easy to implement and is present for the curious. Non-NuFX files -------------- NuLib will only work with Binary II and NuFX archives. If you try to view some other kind of file, you will get an error message and an indication of what kind of file NuLib thinks it is. NuLib can recognize files processed with compress, Zip, StuffIt, ar, shar, GIF, and many others. Compression Methods ------------------- The following methods are defined in the NuFX documentation: (# = method number, Name = method name [abbreviation], Pack? and Unpack? refer to the ability of NuLib to perform that operation using the given compression method. # Name Pack? Unpack? 00 Uncompressed [unc] Y Y 01 SQueezed [squ] N Y 02 Dynamic LZW (ShrinkIt) [shk] * Y Attempting to use a compression method that does not exist will result in an error message like "[can't squeeze; storing]...". This means that the compression method you requested is unavailable, and it simply stored the file without compression. If you try to extract a file that has been compressed with an algorithm that NuLib is not familiar with, an error message will be printed and the file will not be extracted. NOTE: The '*' under packing ShrinkIt LZW is there because NuLib can't really do ShrinkIt compression yet, but it will fake it. It creates an archive with files that ShrinkIt will think are compressed with LZW, but are actually only processed with non-repeat coding. This can achieve a decent level of compression with some files (read: they don't get bigger), but is not generally very good. Converting Line Terminators --------------------------- Different operating systems use different line terminators in text files. The table below shows them for some popular systems: Operating System Line Terminator Apple ProDOS CR ($0d) UNIX LF ($0a) MS-DOS CRLF ($0d0a) While NuLib will know what kind of terminators the operating system it is running under uses, it cannot reliably determine what kind an archived file uses. Thus, the terminator used on the system where the file was created must be specified. Note that text translation should *not* be performed on non-ASCII files (non-ASCII means anything other than pure text; word processing files and executables are two examples of files that should *never* have text translation performed on them). Doing so will probably ruin the file, causing strange errors. Because of the wide range of files that NuLib must handle, it is impossible to automatically determine which files are binaries and which are text. In order to tell NuLib what format to expect, you have to specify a value parameter (although it will default to zero if you don't). The following examples illustrate their usage: nulib xt0 ... Convert from CR (Apple II -> current system) nulib xt1 ... Convert from LF (UNIX -> current system) nulib xt2 ... Convert from CRLF (MS-DOS -> current system) Shell Variables --------------- NuLib looks for a shell variable called "NULIBOPT" to get default values for certain things. This must be an environment variable ("setenv" using csh, "set" and "export" using sh or APW), and may contain the following: verbose Default to Verbose output (otherwise Silent). type=xxx Default type for storing files (under UNIX or MS-DOS). "xxx" should match the 3-letter ProDOS abbreviation (NON, BIN, TXT, SRC). Normally "NON". aux=xxxx Default auxtype for storing files (under UNIX or MS-DOS). "xxxx" is a four-character hex number (000a, 8002, abcd). Normally "0000". interactive Default to Interactive mode (prompt before overwriting files). Note that the type= and aux= settings do NOT apply to APW. Files will be stored with their actual filetypes, regardless of the variable setting. Also, the 'F' suboption will override this settings. Error Handling -------------- Many errors simply cause the program to exit, leaving the archive in an uncertain state (which sounds fairly evil). If you were extracting, deleting, viewing, or updating when the error occurred, the worst that can happen is you will be left with a bogus temporary file in the current directory (something like "nulib.tmp5610"). If you were adding to an existing archive, the files that were there will be unharmed, but additional files will not appear, and the archive will be oversized. This is because the master header block (which keeps a count of the number of records in the archive) is written last. If you were creating a new archive, the file will be guano. This is because, as mentioned before, the Master Header Block is not written until the very end. Since NuLib identifies NuFX archives by looking at certain bytes in the MHB, the file will not be identifiable as NuFX. Note that the M)ove option is safer than it looks, because files on disk are not deleted until the archive is safely closed. Revision History ---------------- NuLib v2.1.1 (Nov 1989): - First wide NuLib distribution. - Revised suboption processing bug. NuLib v2.1 (Nov 1989): - Yet another name change (thanks, L&L). - ShrinkIt LZW uncompression added. - ShrinkIt RLE compression added. - MS-DOS code added. - Shell variable used for defaults. - CRLF translation. CShrink v2.08 (Oct 1989): - Altered help screens, some commands. - Added recognition of other kinds of files (compressed, shar, etc). CShrink v2.07 (Sep 1989): - Another name change (legal reasons). - UNIX port completed. - Binary II operations are fully functional. - some compression code added (unSQueeze, fake ShrinkIt pack). - '+' suboption added. - text translation improved. - printing of archived files (P option) is functional. NuARC v2.03 (Aug 1989): - added subdirectory expansion. - added suboption processing. - replaced buffered I/O (fopen(), fread(), etc) on files with lower-level read()/write() routines. - added automatic byte-order determination. - implemented move, extract all, and update/freshen. - added Print archived file option. - added Verbose, Text translation, and Uncompressed storage suboptions. - wrote this documentation. NuARC v2.0 (Aug 1989): - added archive manipulation routines (EXtract, Add and Delete for uncompressed archives). - added filename-only output format. - added CRC verification. - added byte order and data element size checks. - the LAMESEEK option has been removed. NuView v1.2 (July 1989): - major overhaul of all source code to make it work under APW C. - new //gs-specific routines added. - minor alterations to output format. NuView v1.1 (June 1989): - major rewrite of the way archives are read (had problems with machines requiring word alignment). - added thread file position storage to internal archive structure. - fixed non-(void) sprintf() bug. NuView v1.0 (May 1989): - initial release. - works only on a Sun 3/50 running BSD UNIX. Limitations ----------- This program has been tested with the output of ProDOS 8 ShrinkIt. When ProDOS 8 ShrinkIt packs a file, it always uses records with one thread (of type data_thread). I have tried to make the code flexible, but since I can't generate proper archives with multiple threads and resource forks until GS/OS ShrinkIt is available, I can't honestly say that it will work when presented with such an archive [Scheduled for release late 1989]. The big problem this program has is speed. Since it is meant to be portable first and efficient second, it won't run as fast as something like ShrinkIt (written entirely in assembly). What I envision is people using ShrinkIt at home on their Apple //s, but NuLib on UNIX systems or other microcomputers. This will facilitate transfers of large compressed files, which can then be quickly unpacked on the destination system (which will likely have greater computing power, or a C compiler more advanced than APW). System Dependencies ------------------- When compiling this on a Sun 3/50, I noticed something unfortunate: the byte ordering for the //gs (65816) and the Sun (68020) are backward. The present version of NuLib will automatically determine the byte ordering and treat data appropriately (although this may fail if the data size definitions are wrong). There are definitions for one byte, two byte, and four byte variable types; my compiler uses char, short, and long. If these are different for your compiler, be sure to change the typedefs in "nudefs.h". If you don't have 8-bit bytes, though, it may not work (most machines do). Notes on UNIX implementation: If this is being run under UNIX, you should #define UNIX in "nudefs.h". This will enable certain UNIX functions (like system() calls and time routines), and disable others (like file types and binary mode). If this is being run under BSD UNIX, you should also #define BSD43 in "nudefs.h"; certain small differences were unavoidable (strrchr() vs rindex()). Under APW, breaking down the full pathnames into relative pathnames is easy (and should be under MS-DOS as well...). Under UNIX ".." is an actual directory link, so obtaining a fully expanded pathname with no redundancies is difficult. Thus, storing "dir1/../dir1/foo" would appear as "dir1/foo" under APW but "dir1/../dir1/foo" under UNIX. Care must be taken when extracting such files on non-UNIX systems; they are best avoided entirely. One nasty pitfall is using "~/..." under the C shell... If the UNIX owner access permissions include write permission, the file will be stored as unlocked. If write permission is denied, it will be stored as locked. As far as dates are concerned, the modification and access times will both be set to the modification time. Notes on //gs implementation: There is very little //gs-specific code, except where absolutely necessary (time routines, file type handling, etc). GS/OS support is absent (extended files are not handled yet, different file systems are not recognized, and pseudo-mixed-case ProDOS filenames are stored as upper case), and disk support is a long way off. Some of the faults belong to APW... At any rate, the program is linked with the compression routines in dynamic load segments, so that simple operations should run faster. Additionally, it should be restartable from memory. There is a bug (not my fault) when using the P option to print a file. The file gets printed on one line for some reason... If you redirect the I/O to a file, everything comes out fine. Weird. APW shell-specific code has been avoided where possible. Places where I couldn't easily work around it include wildcard expansion and ERROR(). It was deliberately used in several places to allow the user to STOP() processing with Apple-period. Notes on MS-DOS implementation: Coming along smoothly, but not quite finished. The user interface may be different from the UNIX and APW versions, so that MS-DOS users will feel more at home when using the program. The only major deviation expected is in the handling of wildcards and subdirectory expansion. Bugs / Glitches --------------- The output of the verbose integrity check is messy for large files. I will probably stick with individual CRCs for each 64K section, but may put several of them on a line. I dunno. I'm open to suggestions. UNIX seek uses longs, which are usually four bytes. Signed. If an archive is larger than 2 gigabytes, there may be a problem (cough). Pathnames longer than the #defined maximum (1024 bytes) will not be processed. This is the limit on most machines, and is well in excess of most people's sanity. Pathnames with a null ('\0') in them should generally be avoided. Some partial pathname comparisons may fail because pathname separators vary between operating systems (ex: "foo+" and "foo~" are unpacked under ProDOS, where both are translated to "foo."). Also, you will probably need to be in the same directory each time you U)pdate an archive, or else the partial pathnames won't match (update requires an EXACT match), and you'll end up with two different copies of the same file. A maximum of 255 files may be added/deleted/whatever at at time. Expanded subdirectories count. This is an arbitrary number and is easy to change if someone can convice me that you'd need to archive more than 255 files at a time. The same file may be added/extracted/whatever more than once if the user enters multiple file selectors on the command line ("nulib av foo.shk file1 file1 file1"). This means that U)pdate could insert the same file twice, etc. The ProDOS three-letter filetype names may or may not be the offical Apple versions. Some users may have problems with things like "$00" because '$' is a csh metacharacter (job control). Error output is informative but ugly (mostly debugging-type messages). Error handling is somewhat fatal in most cases. In the Works ------------ To Do: - Add ShrinkIt LZW compress routines. - Improve GS/OS handling. Need to handle resource forks and file system IDs. Would probably help if I had a GS/OS reference... - Add to thread methods (insert ASCII messages, etc). - Add different compression methods (UNIX compress, LZH). - Add disk support (this will probably be *very* limited). Author Info ----------- I'm presently a Junior in Electrical Engineering and Computer Science (EECS) at the University of California, Berkeley. fadden@cory.berkeley.edu (Andy McFadden) ...!ucbvax!cory!fadden No relation to the author of ShrinkIt and NuFX, Andy Nicholas. This was and continues to be my idea; throw all kudos and blame in my general direction. All code herein is mine, developed from the NuFX Documentation Final Revision Three (2/3/89), except as noted below. Dynamic LZW (ShrinkIt) by Kent Dickey. MS-DOS code by Robert B. Hess. The Binary II routines and the unSQueeze code were adapted from the C source by Marcel J.E. Mol (usq.c based on usq2/sq3 by Don Elton). If you have suggestions or comments, you can send US mail to: Andy McFadden 1474 Saskatchewan Dr. Sunnyvale, CA 94087 The author of ShrinkIt and affiliated products (ShrinkIt ][+, UnshrinkIt ][+, GS/ShrinkIt) may be contacted at: Andy Nicholas Internet: shrinkit@moravian.edu Box 435 UUCP: rutgers!liberty!batman!shrinkit Moravian College GEnie: shrinkit Bethlehem, PA 18018 AM Online: shrinkit CIS:70007,3141 Legal Stuff ----------- (I'm not sure about all of these, but I'd like to cover all the bases): ShrinkIt is a trademark of L&L Productions, Inc. ARC is owned by SeaWare. Apple is a tradmark of Apple Computer, Inc. MS-DOS is (probably) a trademark of Microsoft, Inc. PKZIP is (probably) a trademark of PKWare. I have not seen source code for ShrinkIt(tm) or for the compression routines used within it, except as provided to me by Kent Dickey. Disclaimers, borrowed from Dave Whitney and Andy Nicholas: This program is FREEWARE; both source and binaries may be distributed freely, but not sold. If you wish to include NuLib in the distribution of a commercial product, you will need to get my permission beforehand. Distribute as widely as possible, but please include this documentation with the binaries and/or sources. Copyright (C) 1989 by Andy McFadden. All rights reserved. I (Andy McFadden) MAKE NO WARRANTY ON THIS MANUAL OR SOFTWARE, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO QUALITY, MANUAL'S ACCURACY, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL I BE HELD RESPONSIBLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT OF THE SOFTWARE OR INACCURACY IN THE MANUAL. In other words, I have tested the program to the best of my ability, and I find that as distributed by me, it is safe for general use. It isn't necessarily bug-free, and as a result, loss of data, however unlikely, is entirely possible. Use at your own risk, but also for your own enjoyment.