LZ 1.01 8th February, 1991 Written by Jonathan Forbes Copyright © 1990, 1991, Xenomiga Technology About LZ LZ is NOT freeware! If you use it and like it, please send a shareware registration of $10 (Cdn.$ or U.S.$) to the address given below. Note that source code is NOT available for LZ 1.01 at this time. Send shareware contributions to: Xenomiga Technology 1132 Bay Street, Suite #1101 Toronto, Ontario M5S 2Z4 Canada Distribution LZ is a freely distributable, copyrighted piece of software. You may upload it wherever you choose, but you are not allowed to sell LZ for profit, or include LZ on a disk which is sold for profit, without the author's (Jonathan Forbes) permission. The LZ package (LZ101.LZH) consists the following files: LZ - The archiver/extractor itself LZ101.doc - LZ documentation (this file) Update.doc - Information on changes to previous versions None of these files is to be altered in any way whatsoever, or removed! The package may be recompressed with another archiver, however, such as Zoo, Zip, etc. And, as mentioned above, LZ is shareware. Disclaimer I am in no way responsible for anything this program does; you are using it entirely at your own risk! If you are using a hacked, edited, tampered with, or pirated version of LZ, you are even more at risk. What is LZ? Currently, LZ is by far the fastest .LZH archiver and extractor available for the Amiga! LZ is compatible with MS-DOS version 1.13c of Lharc and Amiga Lharc 1.3. Acknowledgements The original Lharc (MS-DOS) was written by Haruyasu Yoshizaki. I took his freely distributable source code "Lzhuf.c", and rewrote it in assembly language (very highly optimised assembly language, I might add). I used "lharc.c" (which is full of MS-DOS specific code) as a reference, but did not use it as a base for the Amiga version, which I wrote from scratch. LZ 1.0 is a significant improvement over the original .LZH algorithm in that it employs modern data compression technology to provide better compression while doubling or tripling encoding speed and retaining 100% compatibility with the .LZH format. How fast is LZ? LZ is currently the fastest .LZH utility for the Amiga. No other available Amiga archiver even comes close to LZ's legendary performance for either compressing or decompressing. LZ 1.0 can achieve peak compression speeds of up to three times those of LZ 0.91. Speedwise, LZ outperforms Lharc 1.3, LharcA .99d, Pkazip 1.01, and just about any other Amiga archiving utility in existence, excepting Zoo 2.01. In terms of degree of compression, LZ, on average, outperforms every other archiver (including the other .LZH archivers) currently available for the Amiga. Note, this is on average; once in a blue moon Pkazip will outperform LZ on a text file, and will produce an output file a slightly smaller than that produces by LZ. However, since this ocurrance is about as frequent as a total solar eclipse, it shouldn't worry you. The files being compressed and decompressed in the test, were those on Fred Fish disk #245. * - Different algorithm/encoding scheme * | (1.01) | (.91) | (1.0) | (.99d) | (1.01) | LZ | LZ | Lharc | LharcA | PkaZip Fish245.LZH | 5:33 | 11:33 | 26:29 | ? | 10:31 compressing | 1:38 | 1:43 | 5:12 | 2:34 | 2:53 decompressing File LZ LZ Lharc LharcA Pkazip Zoo Arc Ape Name 1.0 0.91 1.3 .99d 1.01 2.01 0.23 1.0 ---------- ----- ----- ----- ------ ------ ----- ----- ----- UserManual 88 244 268 211 164 42 112 614 <- compress 19 19 35 27 21 12 19 116 <- extract 64066 66693 66683 66682 61796 78279 80469 66329 <- size AmigaBASIC 47 48 90 74 91 30 129 ... <- compress 20 21 33 25 16 9 10 ... <- extract 66877 67801 67804 67804 69121 83527 85355 ... <- size LZ is consistently faster than all other archivers by the margins shown here. LZ also creates output files up to 5% smaller than those produced any other .LZH archiver. Although there have been many disputes over the compression achieved by .ZIP files and .LZH files, this difference may well tip the balance towards .LZH files. Invokation Typing "LZ" from the CLI, without any parameters, will reveal a help screen similar to the following (with copyright and shareware information.) Summary of commands: a Add file(s) to archive f Freshen file(s) in archive e,x Extract file(s) from archive u Update file(s) in archive l,v Display archive contents t Test archive integrity d Delete file(s) from archive m Move file(s) to archive Summary of options: -a Preserve file attributes -N No console output -A Set archive flag -p Pause after loading -b Set input/output buffer -P Set task priority -c Confirm files -r Archive subdiectories -D Alternative display -u Upper case filenames -f Ignore filenotes -U Update rate -i Read file list from file -w Set work directory -l Lower case filenames -x Preserve path names -L Create list file -z Store files -m Disable message query -Z Compress archives -n No progress indicator The usage line below is also displayed: Usage: LZ [-options] [FilePatterns] [DestPath] While items in square brackets are optional, items in angle brackets are mandatory. LZ will append a .LZH to the parameter if the name of the archive you supply does not already end in .LZH, but ONLY if there isn't already a dot ( . ) in the name. This extra clause is for the benefit of FidoNet users who have their mail archived in the .LZH format. i.e.: MyFile becomes MyFile.LZH MyFile.LZH remains MyFile.LZH 01234567.SA0 remains 01234567.SA0 A detailed description of each of LZ's commands follows: Commands a Add file(s) to archive The add command will add files to a .LZH archive. If the specified archive does not already exist, then it will automatically be created. It is not possible to add a file which is already present in archive; if this is attempted, then an error message will be displayed. By default, only filenames are stored in the archive; if you wish to store path names also, then you will have to use the -x option (explained later). If you wish to store entire subdirectories (i.e. descend recursively through a directory tree), then you will have to use the -r option (explained later). Multiple files may be added with one command. In addition, both AmigaDOS and ARP wildcards are also supported. Examples: 1) To add "BLAH" to "myarchive.LZH", you would enter the following command: Lz a myarchive.LZH blah 2) To add "THEFILE", "HI", and "KING" to "myarchive.LZH", you would enter the following command: Lz a myarchive.LZH thefile hi king 3) To add everything ending in ".INFO" to "myarchive.LZH", you would enter: Lz a myarchive.LZH #?.info e,x Extract file(s) from archive The extract command will extract files from an archive. If you wish to extract files from multiple archives, then you will have to use a wildcard. By default, all files in the archive will be extracted. If you wish only specific files to be extracted, then the names of these files should follow the archive name (wildcards are accepted here.) If any file following the archive name ends in a '/' or a ':', then that directory will be used as the destination directory in which all extracted files will be stored. By default, existing files will not be overwritten; instead, you will be presented with the following: File 'whatever' already exists -overwrite? (Yes/No/All/Quit): Your response is hotkeyed, so it is not necessary to hit return. If you enter "Y", then the file will be overwritten. If you enter "N", then it will not be extracted. If "A" is entered, then all files from then on will automatically be overwritten without prompting you. This includes files in other archives, if you asked Lz to extract multiple archives, using a wildcard. If you do not wish to be prompted for existing files, then use the -m option (explained later.) Please note that if you wish to extract files from multiple archives with one command, it can only be done with wildcards; you cannot enter the name of each archive on the command line. For example: Lz x arc1.LZH arc2.LZH arc3.LZH The above command would attempt to extract "arc2.LZH" and "arc3.LZH" from "arc1.LZH". The way to get around this is to type: Lz x arc#?.LZH However, there are often times when a single wildcard cannot cover all of the files you wish to extract; if this is the case, you will have to invoke Lz more than once. Examples: 1) To extract all files from "myarchive.LZH", you would enter the following command: Lz x myarchive.LZH 2) To extract "BLAH" from "myarchive.LZH", you would enter the following command: Lz x myarchive.LZH blah 3) To extract all ".INFO" files from all archives, you would enter the following command: Lz x #?.LZH #?.info 4) To extract "BLAH", "WHATEVER", and all ".INFO" files from myarchive.LZH to the destination directory "HDISK:ArchiveOutput/", you would enter any of the following commands (they all perform exactly the same function, since the destination directory may be placed anywhere after the archive name): Lz x myarchive.LZH blah whatever #?.info HDISK:ArchiveOutput/ Lz x myarchive.LZH HDISK:ArchiveOutput/ blah whatever #?.info Lz x myarchive.LZH blah whatever HDISK:ArchiveOutput/ #?.info l,v List files in archive The list command will display a verbose listing of the files within the specified archive(s) (wildcards are allowed). The listing will be in the following format: Original Packed Ratio Date Time CRC Name -------- ------ --- --------- -------- ---- ------------ 3026 851 71% 11-Jun-90 19:01:48 E7A9 diskspeed.a3000 841 524 37% 11-Jun-90 19:01:50 1309 si.a3000 937 586 37% 11-Jun-90 19:01:52 AE7B speed.a3000 -------- ------ --- 4804 1961 59% 3 file(s) Heading Meaning Original - The size of the file before compression Packed - The size of the file after compression Ratio - Compression degree; the higher the better Date - The file's creation date Time - The file's creation time CRC - 16-bit Cyclic Redundancy Check Name - File name (including directory path, if present) Examples: 1) To list all files in "myarchive.LZH", you would enter the following command: Lz v myarchive.LZH 2) To list all files in all archives ending in "e", you would enter the following command: Lz v #?e.LZH Please note that since Lz automatically appends a .LZH to the archive name if it does not already end in .LZH (with one exception mentioned earlier), the following command is equally valid to the one shown above: Lz v #?e d Delete file(s) from archive The delete command will remove files from the archive. The names of the files to be deleted should follow the archive name. Wildcards are allowed. Please note that items in subdirectories are also checked, so #?.info will delete all .info files in the archive, wherever they may be. Examples: 1) To delete "BADFILE" from myarchive.LZH, you would enter the following command: Lz d myarchive.LZH badfile 2) To delete "BADFILE" and all ".INFO" files from myarchive.LZH, you would use the following command: Lz d myarchive.LZH badfile #?.info 3) To delete all "README.BBS" files from ALL of your archives, it is only necessary to type: Lz d #?.LZH README.BBS m Move file(s) to archive The move command behaves in exactly the same way as the add command, except that files are deleted after they are added to the archive. Examples: 1) To move "MYFILE" to myarchive.LZH, you would enter the following command: Lz m myarchive.LZH myfile 2) To move all files ending in ".INFO" to myarchive.LZH, you would enter the following command: Lz m myarchive.LZH #?.info f Freshen file(s) in archive The freshen command will replace a file in the archive only if the file is already present in the archive, and the file to be added has a later date. u Update file(s) in archive The update command behaves in exactly the same way as the add command, unless a file to be added is already present in the archive, in which case LZ will compare the dates of both files, and will make sure that the newer file is added to/retained in the archive. t Test archive integrity The test command will test every file in the archive (by extracting it internally), and will inform you of any corrupted files (i.e. files which fail their CRC.) Examples: 1) To test all files in myarchive.LZH, you would enter the following command: Lz t myarchive.LZH 2) To test all files in all archives, you would enter the following command: Lz t #?.LZH 3) To test the file named "boing" in the archive "splat.lzh", you would enter the following command: Lz t splat.LZH boing Options -a Preserve file attributes When this option is used, any files added to the archive will have their attributes preserved (the default is for all files to be rwed). The eight possible attributes are listed below, but will not be explained here (a full explanation should be present in any AmigaDOS manual): r: Read w: Write e: Execute d: Delete s: Script a: Archive p: Protect h: Hidden If this option is not specified, then all files archived or extracted will automatically be "rwed." If this flag is used, then all attributes (rwedsaph) will be preserved. Please note that in order for attributes to be preserved, the -a option must be used both when archiving and extracting. When extracting, use -a only on files which have been compressed by Amiga .LZH archivers; if you don't, you'll end up with files with strange attributes, although no harm will be done. Similarly, if you know that your archive might be extracted on an IBM system, you should not use the -a option, since they will have similar problems. -A This option will set the archive flag of any archive LZ creates or adds files to. It will also unset the executable flag. Thus, your archive will have the following flags set: ---arw-d -b Set i/o buffer size This option will set the i/o buffer size to the number immediately following the option, which must be expressed in K. For example, -b32 would give you a 32k i/o buffer. LZ's i/o buffer size is limited only by available memory, so very large buffer sizes (128k+) are acceptable. Note that changing the i/o buffer size on an 68000 Amiga when all work is being done in a RAM drive doesn't speed things up; these options are mainly for floppy drive users and 68020-68040 users. -c Confirm file names This option will cause LZ to prompt you with yes/no/all/quit for every file to be added to or extracted from an archive. This option can be useful when used in conjunction with wildcards. -D Alternate display mode This options alters the layout of LZ's screen updates. For example, -D1 will use the characters -\|/ to mimic MS-DOS pre 1.10 Pkzip, while -D2 will mimc MS-DOS Pkzip 1.10's percentage update. -D0 is the default, and activates the standard LZ display. -f Ignore filenotes The -f flag will cause LZ to ignore filenotes when archiving or extracting files. -i Read file list from file This option allows you to specify that LZ read a list of files to be archived, from a text file. Entering -iRAM:FileList will cause LZ to read the names of the files stored in RAM:FileList. -l Lower case filenames This option forces all file names to lower case. If used when archiving, all files added will have their names converted to lower case. If used when extracting, all files extracted will have their names converted to lower case. -L Create list file This option causes LZ to create a text file containing a list of all files added to an archive. For example: LZ -LRAM:ListFile a RAM:Archive.lzh hello/blah1 blah2 will cause LZ to create a file named "ListFile" containing: hello/blah1 blah2 If you insert a + after the -L, LZ will output the full path name of the files added. -m No message query Invoking this option will prevent LZ from prompting you for input. It will also cause files to be automatically overwritten if they already exist. This is often useful in conjunction with scripts and BBS's. -n No progress indicator This option will prevent LZ from displaying a byte count as it extracts or archives files. This can be useful if you are redirecting the output of LZ to a file. -N No console output (or "absolutely no progress indicator") If this option is invoked, LZ will not display any text to the screen. This option automatically turns on the -m option, so that if LZ ever does require input from you, it won't just sit there. This option is useful in conjunction with BBS software. Note the differences between this option and the -n option. Also note that this option is incompatible with Amiga Lharc, which will take -N to mean -n. -p Pause after loading This option will cause LZ to prompt you for a keypress after it has loaded. This can be useful if you have only one floppy drive, and LZ is on another disk. -P Set task priority The -P option enables you to set the task priority of LZ. The task priority must immediately follow the -P; for example, -P1, or -P-1. This can be useful if wish to set LZ to a negative priority and leave it running in the background while you are calling BBS's. -r Archive subdirectories This option will cause LZ to recursively collect files from subdirectories, and is usually used in conjunction with the -x option. For example, to add all files on drive df0: (including subdirectories) to mydisk.LZH, you would use: LZ -x -r a mydisk.LZH DF0:#? -u Upper case filenames This option forces all file names to upper case. If used when archiving, all files added will have their names converted to upper case. If used when extracting, all files extracted will have their names converted to upper case. This option is provided for compatibility with MS-DOS Lharc. -U Update rate This option sets the rate (in bytes) at which LZ updates its byte count (or alternate display, if set with -D). It currently defaults to 1024 bytes. The following example sets the update rate to 4096 bytes: -U4096 -w Set work directory When creating archives, individual files are compressed in the work directory, which defaults to T: if it exists, or the current directory otherwise. The -w option allows the location of the work directory to be changed; the name of the new work directory should immediately follow the -w. -x Preserve path names This option forces LZ to preserve the full path names of any files added, and is most commonly used in conjunction with the -r option. -z Zero compression This option is only valid when adding files, and, if invoked, will cause all files added to be merely stored in the archive, not compressed. This is not a very useful option, but has been included for the sake of completeness. -Z Compress archives By default, LZ will NOT attempt to compress files ending in .lzh, .lhw, .zip, .zoo, .arc, .pak, .wrp, .zap, .dms, or .arj, since these files are already compressed. If the -Z option is used, then files with these extensions WILL be compressed. Conclusion LZ does not yet have all of its commands implemented; the commands not implemented are: move, freshen, and update. Like Amiga Lharc, LZ uses the decimal address of its task structure for creating temporary filenames, so that multiple copies can run simultaneously without conflict (and no, LZ is not reentrant; I *like* global variables). If you find yourself using certain options with LZ most of the time, you might want to make them an alias. For example, if you find yourself typing "Lhunarc" all the time: alias lhunarc LZ -b32 [] The above two command works only with shells which support aliases. Your shell might have a different way of doing it; I use AmigaDOS 1.3 and Arp 1.3. Acknowledgements Haruyasu Yoshizaki - For lharc.c and lzhuf.c (the algorithm) Steve Tibbett - For showing me how to speed up Lhunarc 0.96 by 3% For RawDoFmt(), and __tinymain For finding the bug in the view command For Raw() and Cooked() For suggesting a user configurable buffer Rob Collinsworth - For finding the bugs in the algorithm when it was in Lhwarp Chris Larcombe - For finding the zero length file bug in version 0.81 Robert Jung - For all the information on file compression. Timothy C. Bell - For explaining everything from semiadaptive dictionary John G. Cleary techniques and statistical encoding to digital hash Ian H. Witten tries and finite context models.