/* An example of FUNCDEF'ing various functions in the Info-Zip * ZIP compression library (ZIP32.DLL). You need to obtain the * DLL from the web page. * * NOTE: Assumes REXX Dialog is autoloaded. * * This example assumes that there is a zip file named TEST.ZIP * in the current directory. This will read that ZIP file and * extract the files to TEMP directory. */ OPTIONS "WINFUNC NOSOURCE C_CALL" NUMERIC DIGITS 10 /* ============== FUNCDEF some needed ZIP functions ============ */ LIBRARY rexxgui DO /* ZIPFUNCS struct must be initialized and passed to UnZipAll */ ZIPPRINT = '32, void, 32u' ZIPPASSWORD = '32, void, 32, void, void' ZIPREPLACE = '32, void' ZIPSERVICE = '32, void, 32u' ZIPLIST = ", 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, char, str *, str *, 32u, char" ZIPFUNCS = "func ZIPPRINT, void, func ZIPREPLACE, func ZIPPASSWORD, func ZIPLIST, func ZIPSERVICE, 32u, 32u, 32u, 32u, 32u" /* ZIPFLAGS struct must be initialized and passed to UnZipAll ZIPFLAGS.1 = 1 for "update" without interaction (extract only newer/new files, without queries). 0 otherwise. ZIPFLAGS.2 = 1 if convert space to underscore ZIPFLAGS.3 = 1 if prompt to overwrite is wanted ZIPFLAGS.4 = 1 for few feedback messages, 2 for no messages, 0 for all messages ZIPFLAGS.5 = 1 to write to messages to console window ZIPFLAGS.6 = 1 to test zip file (not actually unzip) ZIPFLAGS.7 = 1 for verbose listing ZIPFLAGS.8 = 1 for "freshen" (replace existing files by newer versions) ZIPFLAGS.9 = 1 to display zip file comment ZIPFLAGS.10 = Sets whether to retain (create) subdirectories when extracting as so: 0 = junk paths from filenames 1 = "safe" usage of paths in filenames (skip "../") 2 = allow also unsafe path components (dir traversal) ZIPFLAGS.11 = 1 if you are to always over-write files, false if not ZIPFLAGS.12 = 1 for end-of-line translation of text files ZIPFLAGS.13 = 1 to get zip info ZIPFLAGS.14 = 1 for case-insensitive filenames on sensitive systems ZIPFLAGS.15 = 1 to restore Acl's, or 2 for use privileges ZIPFLAGS.16 = The name of the file to unzip ZIPFLAGS.17 = The name of the directory to extract to. DROP this if you are extracting to the current directory. */ ZIPFLAGS = "32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, str *, str *" /* Register the UNZIP32.DLL function Wiz_SingleEntryUnzip() as UnzipAll. This unzips a file */ FUNCDEF("UnzipAll", "32, 32u, 32u, 32u, 32u, struct ZIPFLAGS, struct ZIPFUNCS", "unzip32", "Wiz_SingleEntryUnzip") /* These 2 are useful if you wish to extract one file from the ZIP archive and * put it into some RAM. ZIPBUFFER = '32u, void *' FUNCDEF("UnzipToMemory", "32, str, str, struct ZIPFUNCS, struct ZIPBUFFER stor", "unzip32", "Wiz_UnzipToMemory") FUNCDEF("FreeZipMemory", ", struct ZIPBUFFER", "unzip32", "UzpFreeMemBuffer ") Here's how to extract the file REGINALD.DLL from REGINALD.ZIP and then assign it to the variable "Reginald": ZipFuncs. = 0 ZipFuncs.1 = 'ZipPrint' ZipFuncs.3 = 'ZipReplace' ZipFuncs.4 = 'ZipPassword' ZipFuncs.5 = 'ZipList' retcode = UnzipToMemory("reginald.zip", "reginald.dll", zipFuncs, zipBuffer) IF retcode == 0 THEN SAY "Error unzipping..." ELSE DO CONVERTDATA(zipBuffer.2, 'Reginald', 'char[' || zipBuffer.1 || ']') FreeZipMemory(zipBuffer) END */ CATCH FAILURE CONDITION("M") RETURN END /* Present the dialog */ err = GuiFile('FN', 'EXISTING', 'Pick out file to unzip', 'Zip files (*.zip)|*.zip|All files (*.*)|*.*') IF err = '' THEN DO /* Initialize a ZIPFLAGS struct */ ZipFlags. = 0 ZIPFLAGS.10 = 1 /* Recreate directories */ ZIPFLAGS.11 = 1 /* Over-write all files */ ZIPFLAGS.16 = FN ZIPFLAGS.17 = SEARCHPATH('%TEMP%') /* If you want to unzip to the current directory, don't set ZIPFLAGS.17 */ /* Initialize a ZIPFUNCS struct */ ZipFuncs. = 0 ZipFuncs.1 = 'ZipPrint' ZipFuncs.3 = 'ZipReplace' ZipFuncs.4 = 'ZipPassword' ZipFuncs.5 = 'ZipList' ZipFuncs.6 = 'ZipService' retcode = UnzipAll(, , , , zipFlags, zipFuncs) IF retcode \== 0 THEN SAY "Error unzipping..." retcode END RETURN /* ================================================================== * ZIP Password callback - We don't bother with passwords. */ ZipPassword: RETURN 1 /* ================================================================== * ZIP List callback. This function lets you do a listing of an * archive's contents. For each file inside the ZIP archive, UNZIP32 * calls this with information about that file. * * This example script never actually does a listing (ie, ZipFlags.13 is * not set to 1). But a function has to be supplied, so this shows a very * basic procedure to format and display information about the file. * * ARG(1) = Uncompressed size. * ARG(2) = Compressed size. * ARG(3) = Compression ratio. * ARG(4) = File creation month (1 - 12). * ARG(5) = File creation day (1 - ??). * ARG(6) = File creation year. * ARG(7) = File creation hour (1 - 24). * ARG(8) = File creation minute (0 - 59). * ARG(9) = First char of filename. * ARG(10) = Filename. */ ZipList: IF ARG(3) = 100 THEN compFactor = "100%" ELSE DO IF ARG(2) > ARG(1) THEN sgn = '-' ELSE sgn = ' ' compFactor = sgn || ARG(3) || '%' END SAY ARG(1) ARG(2) compFactor ARG(4) || '-' || ARG(5) || '-' || ARG(6) ARG(7) || ':' || ARG(8) ARG(9) || ARG(10) RETURN /* ================================================================== * ZIP Print callback. Prints any text that the UNZIP32.DLL functions * want displayed. We print to a console window. * * ARG(1) = The text to print. * ARG(2) = The number of characters of text. * * RETURNS: The number of characters printed. */ ZipPrint: IF ARG(2) > 0 THEN DO /* ARG(1) needs to be in a format suitable for REXX to handle. * We didn't know ahead of time how many chars it would be, so * we had to declare it as void type. Now that we know how many * chars, we can construct a Definition string and use CONVERTDATA() * to get it into the format we really want -- a char[] array. */ def = 'char[' || ARG(2) || ']' IF CONVERTDATA(ARG(1), 'text', def) \== "" THEN SAY text END /* Return the number of chars printed */ RETURN ARG(2) /* ================================================================== * ZIP Replace callback. This callback lets you tell UNZIP32 whether * to replace, rename etc existing files. * * ARG(1) = The name of the file that will be replaced. * * RETURNS: 1 to replace the file, or 0 to skip. */ ZipReplace: RETURN 1 /* ================================================================== * ZIP Service callback. This callback lets you tell UNZIP32 whether * to abort. * * ARG(1) = The name of the file that was last unzipped. * * RETURNS: 0 to continue, or any other value to abort. */ ZipService: RETURN 0