Info-ZIP's UnZip REXX Interface

From EDM2
Revision as of 19:34, 21 November 2016 by Ak120 (Talk | contribs)

Jump to: navigation, search

By Richard K. Goran

Info-ZIP has released an updated version of their OS/2 ZIP and UNZIP programs along with a DLL for processing ZIP files in a REXX program. This free API was developed by Scott Maxwell and is named unzipapi.dll and it is available via anonymous FTP. The only documentation relating to the API is contained in the file containing the ZIP source code at the same site in /pub/archiving/zip/zip21.zip. The API contains seven functions: UZLoadFuncs() and UZDropFuncs() function like SysLoadFuncs() and SysDropFuncs() in REXXUTIL. They are used to register and deregister UNZIPAPI. Typical use of UZLoadFuncs is:

call RxFuncAdd 'UZLoadFuncs', 'UNZIPAPI', 'UZLoadFuncs'
call UZLoadFuncs

UZVer()

The UZVer( [option] ) function returns the version / modification level and, optionally the creation date, of unzipapi.dll. The function has one optional parameter of L. The data returned by the function is:

say UZVer()
5.20
say UZVer('L')
5.20 of 30 April 1996

The source documentation, such as it is, that accompanies the source code for rexxapi.c indicates that there is an UzAPIVer( [option] ) function, but this does not appear to be the case.

UZUnZip()

The UZUnZip( parameters[, stem]) function is equivalent to running unzip.exe from the command line. The first parameter to the function is a string which contains all of the parameters you would use to launch unzip.exe from the command line. If a second, optional parameter is specified, it must contain the name of a stem variable where all of the lines of output from UNZIP are assigned, on a one-for-one basis.

UZFileTree()

The UZFileTree( ZIP_file_name, 'stem'[, include][, exclude][, option] ) function, which appears to be modeled after the SysFileTree() function in REXXUTIL, permits a ZIP-style file to be scanned for all files within the zipped file. The criteria governing what files within the zipped file are to be returned, and what information about each file is returned, are specified in optional, positional parameters in the call to UZFileTree(). The similarity to SysFileTree() ends with the positional parameters for the include and exclude masks. The options parameter would have been better placed as the third parameter for consistency. The format of all of the parameters is:

call UZFileTree ZIP_file_name, 'stem'
     [, 'include_stem']
     [, 'exclude_stem']
     [, 'options']

Again, the double commas are used here because of continuation caused by the space limitations of this column. The ZIP_file_name parameter is the file name of the zipped file. UZFileTree(), like SysFileTree(), returns 0 indicating success or 1 indicating failure. The only failure that is indicated is insufficient memory which appears to be a relic from 16-bit, real addressing. The return code gives no indication of the validity of the contents of zipped_file_name. Stem.0, which is always initialized, must be used to determine whether any files were returned in stem.1 through stem.n. The default contents of stem.n is the file name contained within the zipped file. If the zipped file was created with subdirectories, the contents of stem.1 through stem.n will contain the path and file name. Since the ZIP / UNZIP code is intended to be universal across platforms, the DOS and OS/2 use of a backslash (\) to separate file system elements is replaced with a slash (/) in the ZIP file and the data returned by UZFileTree(). Therefore, it is necessary to replace slashes with backslashes in the file information returned by the function. This REXX TRANSLATE instruction accomplishes this task easily. For example,

stem.i = TRANSLATE( stem.i, '\', '/' )

The include and exclude parameters are stem variables which specify files, including those indicated by the wild card characters * and ?, to be included and excluded in the decompression, respectively. Each 0 tail of the stem variable must contain the number of elements to be considered in each list.

The option parameter may contain O (return file names only), F (return file names preceded by the file's statistics - the equivalent of unzip -l from the command line), or Z (return ZIP statistics - the equivalent of unzip -v from the command line).

If the F option parameter is specified, the contents of each element within the stem variable returned by UZFileTree() contains six fields (unlike SysFileTree() which contains five). The fields are: Length - the length of the uncompressed file, EAs - the length of any extended attributes attached to the file or 0, ACLs - the size of Access Control list data, Date - the file's date in the same format as it existed on the original file, Time - the file's time stamp in 24-hour notation, and Name - the file system name including directory information separated by forward slashes if it was included when the ZIP file was created.

If the Z option parameter is specified, the contents of each element within the stem variable returned by UZFileTree() contains: Length, Method, Size, Ratio, Date, Time, CRC-32, and Name.

The PARSE instruction should be used to separate the individual fields similarly to the technique used to extract the fields returned by SysFileTree(). Fragments [#Fragment 1 1] and [#Fragment 2 2] contain an example of REXX code which can be used to assign the values returned by the F and Z options, respectively. In either case, if the ZIP file was created with path information, directory entries always have a trailing slash (which you must translate to a backslash as noted above).

UZUnZipToVar()

The UZUnZipToVar( ZIP_file_name, file_name[, 'stem'] ) function permits uncompressing a specific file from a zipped file into a stem variable or a single variable. If the optional third parameter is not specified, the file being extracted and uncompressed is returned by the function. This is equivalent to unzipping a file from a zipped archive and reading the entire contents of that uncompressed file with the built-in CHARIN() function. If the optional third parameter is specified, it indicates a stem variable which will be assigned the lines of file_name on a one-for-one basis. Obviously, this option is not meaningful for files other than text oriented files. Stem.0 will contain the number of lines assigned to the elements of the stem variable. This is equivalent to unzipping a file from a zipped archive and then reading the contents of that uncompressed file into a stem variable with the built-in LINEIN() function.

UZUnZipToStem()

The UZUnZipToStem( ZIP_file_name, 'stem'[, include][, exclude][, mode] ) function has parameters similar to those described above for the UZFileTree() function with the exception of the mode parameter which may contain either F (flat) or T (tree). In flat mode, each file is decompressed and assigned to the variable whose stem is the stem name specified in the call to the function and whose tail is the file's name. Assuming abc.zip contains def/ghi/xyz.doc then stem/def/ghi/xyz.doc would contain the contents of the uncompressed file. In the unzipapi.dll author's words, "Umm, this is hard to explain so I'll give an example, too."; therefore, I have followed suit and included the example and explanation given in rexxapi.c in [#Fragment 3 Fragment 3].

Resources

Fragment 1

parse value stem.i with,
   file_uncompressed_size,
   file_eas,
   file_acls,
   file_date,
   file_time,
   file_path_and_name
file_path_and_name = TRANSLATE( STRIP( file_path_and_name ), '\', '/' )

Fragment 2

parse value stem.i with,
   file_uncompressed_size,
   file_method,
   file_compressed_size,
   file_ratio,
   file_date,
   file_time,
   file_CRC,
   file_path_and_name
file_path_and_name = TRANSLATE( STRIP( file_path_and_name ), '\', '/' )

Fragment 3

mode - Specifies 'F'lat or 'T'ree mode.  Umm, this is
       hard to explain so I'll give an example, too.
       Assuming a file unzip.zip containing:
               unzip.c
               unshrink.c
               extract.c
               os2/makefile.os2
               os2/os2.c
               os2/dll/dll.def
               os2/dll/unzipapi.c

       -- In flat mode, each file is stored in
          stem.fullname i.e. stem."os2/dll/unzipapi.c"
          A list of files is created in stem.

       Flat mode returns:
               stem.0 = 7
               stem.1 = unzip.c
               stem.2 = unshrink.c
               stem.3 = extract.c
               stem.4 = os2/makefile.os2
               stem.5 = os2/os2.c
               stem.6 = os2/dll/dll.def
               stem.7 = os2/dll/unzipapi.c

       And the following contain the contents of the
       various programs:
               stem.unzip.c
               stem.unshrink.c
               stem.extract.c
               stem.os2/makefile.os2
               stem.os2/os2.c
               stem.os2/dll/dll.def
               stem.os2/dll/unzipapi.c

       -- In tree mode, slashes are converted to periods
          in the pathname thus the above file would have
          been stored in stem.os2.dll.unzipapi.c
          The index would then be stored in stem.OS2.
          DLL..

       NOTE: All path names are converted to uppercase

       Tree mode returns:
               stem.0 = 4
               stem.1 = unzip.c
               stem.2 = unshrink.c
               stem.3 = extract.c
               stem.4 = OS2/

               stem.OS2.0 = 3
               stem.OS2.1 = makefile.os2
               stem.OS2.2 = os2.c
               stem.OS2.3 = DLL/

               stem.OS2.DLL.0 = 2
               stem.OS2.DLL.1 = def
               stem.OS2.DLL.2 = unzipapi.c

       And the following contain the contents of the
       various programs:
               stem.unzip.c
               stem.unshrink.c
               stem.extract.c
               stem.OS2.makefile.os2
               stem.OS2.os2.c
               stem.OS2.DLL.dll.def
               stem.OS2.DLL.unzipapi.c