From 18a5198fe760295f644e7a31a78fd6d1dd36d809 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Thu, 28 Jun 2018 14:22:06 +0900 Subject: [PATCH] Imported Upstream version 610c12 Change-Id: I1405d82744757b94b0d41c6551d7ff324054abb1 Signed-off-by: DongHun Kwak --- History.610 | 32 +- INSTALL | 39 +- UNZIP.HLP | 1727 +++++++++ UNZIP_CLI.HLP | 1342 +++++++ extract.c | 13 +- fileio.c | 26 +- globals.h | 6 +- mod/win32/w32cfg.h | 674 ++++ mod/win32/win32.c | 5050 +++++++++++++++++++++++++++ process.c | 2 +- unzip.c | 10 +- unzpriv.h | 8 +- unzvers.h | 4 +- vms/INSTALL_VMS.txt | 25 +- vms/build_unzip.com | 79 +- vms/descrip.mms | 240 +- vms/descrip_mkdeps.mms | 68 +- vms/descrip_src.mms | 104 +- win32/vc10/funzip/funzip.vcxproj | 63 + win32/vc10/libbz2/libbz2.vcxproj | 57 +- win32/vc10/unzip.sln | 18 + win32/vc10/unzip/unzip.vcxproj | 71 +- win32/vc10/unzipsfx/unzipsfx.vcxproj | 67 + win32/w32cfg.h | 16 +- win32/win32.c | 356 +- windll/vc10/libbz2/libbz2.vcxproj | 55 + windll/vc10/unzip32_dll.sln | 19 +- windll/vc10/unzip32_dll/unzip32_dll.vcxproj | 79 +- windll/vc10/unzipstb/unzipstb.vcxproj | 71 + windll/vc10/uzexampl/uzexampl.vcxproj | 65 + windll/windll.c | 3 +- zipinfo.c | 3 +- 32 files changed, 9926 insertions(+), 466 deletions(-) create mode 100644 UNZIP.HLP create mode 100644 UNZIP_CLI.HLP create mode 100644 mod/win32/w32cfg.h create mode 100644 mod/win32/win32.c diff --git a/History.610 b/History.610 index 6b5ca97..4a04e35 100644 --- a/History.610 +++ b/History.610 @@ -536,7 +536,7 @@ Features added (or removed): (fileio.c, unzip.c, unzip.h, man/man1/unzip.1, vms/cmdline.c, vms/unzip_cli.help, vms/unz_cli.cld) [SMS, JBCarpen] - A Bzip2 source kit (version 1.0.6, modified for better VMS support) - is now included in the kit. (Old bzip2/descrbz2.mms removed. + is now included in the kit. (Old bzip2/descrbz2.mms removed. bzip2/README_bz2.txt, bzip2/) [SMS] - Changed Unix and VMS builders: - Enable bzip2, LZMA, and PPMd compression support by default. @@ -551,6 +551,25 @@ Features added (or removed): vms/descrip.mms, vms/descrip_mkdeps.mms, vms/descrip_src.mms, vms/INSTALL_VMS.txt) [SMS] +6.10c12 (31 Oct 2014): + - Changed Windows (win32\vc10) and Windows DLL (windll\vc10) builders: + - Enabled bzip2 compression support by default. + - Added x64 platform to projects, disabling 32-bit assembly code + explicitly (ASM_CRC). + (win32/vc10/unzip.sln, win32/vc10/funzip/funzip.vcxproj, + win32/vc10/libbz2/libbz2.vcxproj, win32/vc10/unzip/unzip.vcxproj, + win32/vc10/unzipsfx/unzipsfx.vcxproj, windll/vc10/unzip32_dll.sln, + windll/vc10/libbz2/libbz2.vcxproj, + windll/vc10/unzip32_dll/unzip32_dll.vcxproj, + windll/vc10/unzipstb/unzipstb.vcxproj, + windll/vc10/uzexampl/uzexampl.vcxproj) [SMS] + - Minor code changes to accommodate Windows x64 builds: + - Changed some types and added some type casts. + - Changed system identification text in the "-v" report. + - Disabled 32-bit assembly code (ASM_CRC) when _WIN64 is defined. + (extract.c, fileio.c, globals.h, process.c, unzpriv.h, + win32/w32cfg.h, win32/win32.c, windll/windll.c, zipinfo.c) [SMS] + Bugs fixed: @@ -1503,16 +1522,21 @@ Bugs fixed: later tests, causing erroneous configuration related to wide characters and Unicode. (unix/configure) [EG, SMS] -6.10c11 (09 Oct 2014): +6.10c11 (03 Nov 2014): - Windows DLL interface/entry functions Wiz_SingleEntryUnzip() and Wiz_UnzipToMemory() were not setting the global flag has_win32_wide, - causing problems with Unicode/wide file/member names. + causing problems with Unicode/wide file/member names. (windll/windll.c) [Andreas Schniertshauer, SMS] - Work around MS compiler quirk which caused bad behavior in the Windows DLL. Forum topic: http://www.info-zip.org/phpBB3/viewtopic.php?f=4&t=447 (windll/windll.c) [JBCarpen, SMS] - - ZipInfo displayed wrong data for MD5 extra block (ID = 0x4b46). + - ZipInfo displayed wrong data for MD5 extra block (ID = 0x4b46). (zipinfo.c) [Wojtek Michalski] + - A corrupt (or crafted) archive could cause memory access problems. + Forum topic: http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=450 + (extract.c) [Michal Zalewski, SMS] +6.10c12 (11 Nov 2014): + - No news. diff --git a/INSTALL b/INSTALL index ceadad3..e9ba2c0 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ INSTALL -- Info-ZIP UnZip Installation Instructions =================================================== - UnZip version 6.10. Revised: 2014-10-06 + UnZip version 6.10. Revised: 2014-11-08 ------------------------------------------------------------------------ @@ -69,15 +69,16 @@ options.) This should create an "unzip61" directory which contains the UnZip source kit, and that is where the rest of the work is done. - Some unzip programs, such as the Extraction Wizard in Windows, may -want to add another add another "unzip61" directory above the top-level -directory in the Zip archive. This extra, top-level directory is not -needed, and probably makes finding the archive's top-level directory -harder. (With the Windows Extraction Wizard, this extra directory can -easily be deleted manually.) Many of the instructions below assume that -you're in the archive's main (top-level) directory, that is, the -directory which contains this INSTALL file (and many other UnZip files -and directories). + Some unzip programs, such as the Extraction Wizard ("Extract +Compressed (Zipped) Folders") in Windows, may want to add another add +another "unzip61" directory above the top-level directory in the Zip +archive. This extra, top-level directory is not needed, and probably +makes finding the archive's top-level directory harder. (With the +Windows Extraction Wizard, this extra directory can easily be deleted +manually from the default destination path before letting the extraction +proceed.) Many of the instructions below assume that you're in the +archive's main (top-level) directory, that is, the directory which +contains this INSTALL file (and many other UnZip files and directories). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -240,7 +241,7 @@ control the corresponding optional features: is present). Support requires a separate IZ_AES_WG source kit, as described above ("Optional Source Kits"), but is enabled by - default if that source kit is present. + default if that source kit is present. BINS=[L][M][U] Binaries build list: L: object library (libizunzip.a) @@ -544,11 +545,7 @@ Windows (XP, Vista, 7, and so on) Preprocessor Definitions (C macros). Some popular macros are included but disabled by "x_" prefixes, which are easy to remove. The solution file, unzip.sln, includes the "libbz2" project, which is - marked as a prerequisite for the "unzip" and "unzipsfx" projects. If - there is no bzip2 source kit in the bzip2\ directory, then the - "libbz2" project build will fail, but the "unzip" and "unzipsfx" - project builds should still work (so long as the BZIP2_SUPPORT macro - is not defined). + marked as a prerequisite for the "unzip" and "unzipsfx" projects. Symbolic link support (C macro SYMLINKS) requires Windows Vista or newer. @@ -565,10 +562,7 @@ Windows (XP, Vista, 7, and so on) UnZip itself, optional features are controlled by Preprocessor Definitions (C macros). Also similarly, the solution file, unzip32_dll.sln, includes the "libbz2" project as as a prerequisite - for the "unz32dll" and "uzexampl" projects, and if there is no bzip2 - source kit in the bzip2\ directory, then the "libbz2" project build - will fail, but the other project builds should still work (so long as - the BZIP2_SUPPORT macro is not defined). + for the "unz32dll" and "uzexampl" projects. Currently, Microsoft Visual Studio 2010 (Visual C++ v10.0), VS 2012 (VC++ v11.0), and VS 2013 (VC++ 12.0) are the only tested versions. @@ -894,9 +888,8 @@ BZIP2_SUPPORT (requires bzip2 object library) MSDOS 32-bit (DJGPP), Unix, VMS, and Windows. Compilation: - - MSDOS, Windows: You have to supply the macro definition - "USEBZ2=1" on the command line when you invoke the "make" - program. + - MSDOS: You have to supply the macro definition "USEBZ2=1" on the + command line when you invoke the "make" program. - Unix: The target "generic" automatically enables bzip2 support when its unix/configure script detects bzip2 sources in the "bzip2" subdirectory. See the Unix section below for details on diff --git a/UNZIP.HLP b/UNZIP.HLP new file mode 100644 index 0000000..600d5e8 --- /dev/null +++ b/UNZIP.HLP @@ -0,0 +1,1727 @@ +1 UnZip + + UnZip lists, tests, or extracts files from a ZIP archive (an archive + format commonly used on many different systems). The default + behavior (with no options) is to extract into the current directory + (and subdirectories below it) all files from the specified ZIP + archive. A companion program, Zip, creates ZIP archives. + + Info-ZIP UnZip and Zip were intended to be compatible with archives + created by PKWARE's PKZIP and PKUNZIP programs (originally for + MS-DOS), but in many cases the program options or default behaviors + differ. Nowadays, many other programs are available which work with + ZIP archives. + + This help file describes the Unix-style command-line edition of + UnZip. A VMS CLI edition is also available, with a separate help + file. + + Format + + unzip [ unzip_options ] [ file[.zip] ] [ member ... ] + unzip -Z [ zipinfo_options ] [ file[.zip] ] [ member ... ] + + Note: Beginning with UnZip version 6.10, the old command-line + parser has been replaced by one like the one used in Zip. One + significant change is that option negation now uses a TRAILING + hyphen ("-"), so, for example, -B- negates the -B option. This + change was made because a double hyphen ("--") now introduces a long + option. + + To display the basic built-in help, use the command: + unzip -h + + To display the extended built-in help, use the command: + unzip -hh + + The built-in help may be more current than this help file, + especially between full product releases. + + To list all available options for a particular UnZip program, use + the command: + unzip --show-options + + This report will not include any options which are available only on + other system types, or options which must be enabled at build-time + but were not enabled in the particular UnZip program being used. +2 Command_Parameters + +file[.zip] + + File path/name of a ZIP archive. A wildcard name may be used to + specify multiple ZIP archives to be processed in one command. On + VMS systems, any of the standard wildcards for a directory/file + specification may be used: "...", "*", or "%" (or, since VMS V7.2, + "?"). The default archive file specification is ".ZIP". + + Note that a ".zip" or ".ZIP" file type on an archive is merely a + convention, not a requirement. For example, a self-extracting ZIP + archive named "fred" or "fred.exe" could be processed as if it were + an ordinary archive; just specify the actual file name with its + actual name ending (if any), whatever that may be. + +member ... + + An optional list of archive members to be processed, separated by + spaces. If no member list is specified, then all archive members + are processed. Unix-like ("globbing") wildcard patterns may be used + to match multiple members: + + * Matches a sequence of 0 or more characters. + ? Matches exactly 1 character. + [...] Matches any single character found inside the brackets. + Ranges are specified by a beginning character, a hyphen, and + an ending character. If an exclamation point ("!") or a + caret ("^") follows the left bracket, then the range of + characters within the brackets is complemented. That is, + anything except the characters inside the brackets is + considered a match. To specify a literal left bracket, use + the three-character sequence "[[]". +2 Options_Primary_Mode + Options in this group specify the primary mode of operation of + UnZip. Only one of these primary mode options may be specified. + + Note that uppercase options (like -T) must be specified in quotes + (unless SET PROCESS/PARSE_STYLE=EXTENDED is set). For example: + + unzip "-VX" -a zipfile +3 -c +-c +--to-stdout + + Primary Mode. Extract files to stdout/screen. This option is + similar to the -p option except that the name of each file is + displayed as it is extracted, and the -a option is allowed, which + can provide automatic ASCII-EBCDIC conversion, where appropriate. +3 -f +-f +--freshen + + Primary Mode. Freshen existing files. That is, extract only those + files that already exist on disk and that are newer than the disk + copies. By default UnZip queries before overwriting, but the -o + option may be used to suppress the queries. +3 -h +-h +--help + + Primary Mode. Display brief (roughly 24 lines) usage instructions. + See also -hh. +3 -hh +-hh +--long-help + + Primary Mode. Display extended help (more complete usage + instructions). See also -h. +3 -l +-l +--list + + Primary Mode. List archive members. By default, a brief format is + used, which includes the following items: member name, uncompressed + file size ("Length"), and modification date-time of the member. A + summary is included at the end of the report, showing total size and + count for all the members in the report. Specifying a member list + limits the report to those members. + + Adding -v (--verbose) to an "unzip -l" command line adds the + following items to the report: compression method, compressed size + ("Size"), compression ratio, and 32-bit CRC. + + In contrast to some other programs, UnZip does not include the + 12-byte encryption header in the compressed size values for a + Traditionally encrypted member. Therefore, compressed size and + compression ratio figures are independent of the member's encryption + status and show the correct compression performance. (The complete + size of the encrypted compressed data stream for archive members is + reported by the more verbose ZipInfo reports. See ZipInfo. + + If UnZip was built with OS2_EAS enabled, then the -l report also + includes the sizes of stored OS/2 extended attributes (EAs) and OS/2 + access control lists (ACLs). In addition, the archive comment and + individual member comments (if any) are displayed. + + If a file was archived from a single-case file system (for example, + the old MS-DOS FAT file system) and the -L option was given, the + filename is converted to lowercase and is shown prefixed with a + caret (^). + + Note: If only -v (--verbose) is specified with an archive name, + then UnZip acts as if "-l -v" were specified, and a detailed listing + is generated. +3 --license + + Primary Mode. Display the Info-ZIP license. +3 -p +-p +--pipe-to-stdout + + Primary Mode. Extract files to stdout (pipe). Only the actual file + data for the members are sent to stdout (no file names, or other + information, as would be displayed with -c, and the files are always + extracted in binary format, just as they are stored (no + conversions). +3 -T +-T +--timestamp-new + + Primary Mode. Set the timestamp on the archive(s) to that of the + newest file in each one. This corresponds to Zip's -go option, + except that it can be used on wildcard archives (for example, "unzip + -T *.zip"), and is much faster. +3 -t +-t +--test + + Primary Mode. Test archive members. Testing means that each + archive member is extracted in memory (expanding and decrypting, as + needed), but not written to a file. The resulting CRC (cyclic + redundancy check, an enhanced checksum) of the extracted data is + then compared with the original file's stored CRC value, and an + error message is emitted if a CRC mismatch is detected. + + Adding -v to -t adds some diagnostic information to the report for + archive members with LZMA or PPMd compression. +3 -u +-u +--update + + Primary mode. Update existing files and create new ones if needed. + This mode performs the same function as the Freshen (-f) mode, + extracting (with query) files that are newer than those with the + same name on disk, but it also extracts those files that do not + already exist on disk. +3 -v +-v +--verbose + + Primary mode (when alone) or option. When used as a primary mode + (alone), and no archive is specified, an "unzip -v" command + generates a report showing the program version, build options, and + relevant envrironment variables. + + When used with some other primary mode option, -v can make output + more verbose (detailed). + + If no other primary mode is specified, and an archive is specified, + then UnZip acts as if "-l -v" were specified, and a detailed listing + is generated. See -l. +3 -z +-z +--zipfile-comment + + Primary mode. Display only the archive comment. +2 Options_Ordinary + Options in this group modify the operation of UnZip. + + Note that uppercase options (like -V) must be specified in quotes + (unless SET PROC/PARSE=EXTEND is set). For example: + + unzip "-VX" -a zipfile + +3 -2 +-2 +--force-ods2 + + [VMS] Convert extracted file names to ODS2-compatible names, even on + an ODS5 file system. By default, if the destination file system is + ODS5, case is preserved, and extended file name characters are + caret-escaped as needed, while if the destination file system is + ODS2, invalid characters are replaced by underscores. +3 -A +-A +--api-help + + [OS/2, Unix DLL] Print extended help for the DLL's application + programming interface (API). +3 -a +-a +--ascii + + Convert text files. Ordinarily, all files are extracted exactly as + they are stored, byte-for-byte. With -a, line endings in a text + file are adjusted to the local standard as the file is extracted. + When appropriate, ASCII<-->EBCDIC conversion is also done. + + Zip (or a similar archiving program) identifies files as "binary" or + "text" when they are archived. (A short-format ZipInfo report + denotes a binary file with a "b", and a text file with a "t".) Zip's + identification of text files may not be perfect, so UnZip prints + "[binary]" or "[text]" as a visual check for each file it extracts + with -a. The -aa option forces all files to be extracted (and + converted) as text, regardless of the supposed file type. + + [VMS] On VMS, for archives with VMS attribute information (made with + "zip -V"), files are always created with their original record + formats. For archives without VMS attribute information (not made + with "zip -V"), all files are normally created with Stream_LF record + format. With -a, text files are normally created with + variable-length record format, but adding -S gives them Stream_LF + record format. With -aa, all files are treated as text files. See + also -b and -S. +3 -B +-B +--backup + + [when built with UNIXBACKUP enabled] Save a backup copy of each + overwritten file. The backup file gets the name of the target file + with a tilde and optionally a unique sequence number (up to 5 + digits) appended. The sequence number is appended whenever another + file with the original name plus tilde already exists. When used + together with the "overwrite all" option, -o, numbered backup files + are never created. In this case, all backup files are named as the + original file with an appended tilde, and existing backup files are + deleted without notice. This feature works similarly to the default + behavior of emacs(1) in many locations. + + Example: the old copy of "foo" is renamed to "foo~". + + Warning: Users should be aware that the -B option does not prevent + loss of existing data under all circumstances. For example, when + UnZip is run in overwrite-all mode, an existing "foo~" file is + deleted before UnZip attempts to rename "foo" to "foo~". When this + rename attempt fails (because of a file lock, insufficient + privileges, or any other reason), the extraction of "foo~" gets + cancelled, but the old backup file is already lost. A similar + scenario takes place when the sequence number range for numbered + backup files gets exhausted (99999, or 65535 for 16-bit systems). + In this case, the backup file with the maximum sequence number is + deleted and replaced by the new backup version without notice. +3 -b +-b +--binary + + [Tandem, VMS] Selects the file record format used when extracting + binary files. -b may conflict or interact with -a in different ways + on different system types. -b is ignored on systems other than + Tandem and VMS. + + Zip (or a similar archiving program) identifies files as "binary" or + "text" when they are archived. (A short-format ZipInfo report + denotes a binary file with a "b", and a text file with a "t".) + + [Tandem] Force the creation files with filecode type 180 ('C') when + extracting archive members marked as "text". (On Tandem, -a is + enabled by default, see above). + + [VMS] On VMS, for archives with VMS attribute information (made with + "zip -V"), files are always created with their original record + formats. For archives without VMS attribute information (not made + with "zip -V"), files are normally created with Stream_LF record + format. With -b, binary files are created with fixed-length, + 512-byte record format. With -bb, all files are created with + fixed-length, 512-byte record format. When extracting to standard + output (-c or -p option in effect), the default conversion of text + record delimiters is disabled for binary files (with -b), or for all + files (with -bb). +3 -C +-c +--ignore-case ([CMS, MVS] --CMS-MVS-lower) + + Use case-insensitive name matching for names in the member list and + the -x excluded-member list on the command line. By default, + case-sensitive matching is done. For example, specifying "makefile" + on the command line will match only "makefile" in the archive, not + "Makefile" or "MAKEFILE". On many systems, the local file system is + case-insensitive, so case-insensitive name matching would be more + natural. With -C, "makefile" would match "makefile", "Makefile", or + "MAKEFILE". + + -C does not affect the search for the ZIP archive file(s), nor the + matching of archive members to existing files on the extraction + path. So, on a case-sensitive file system, UnZip will never try to + overwrite a file "FOO" when extracting a member named "foo"! +3 -c +-c +--to-stdout + + Primary Mode. Extract files to stdout/screen. For details, see + Options_Primary_Mode. +3 -D +-D +--dir-timestamps + + Control timestamps on extracted files and directories. By default, + UnZip restores timestamps for extracted files, but not for + directories it creates. Specifying -D tells UnZip not to restore + any timestamps. Specifying -D- tells UnZip to restore timestamps + for directories as well as other items. -D- works only on systems + that support setting timestamps for directories (currently ATheOS, + BeOS, MacOS, OS/2, Unix, VMS, Win32). On other systems, -D- has no + effect. + + [Non-VMS] Timestamp restoration behavior changed between UnZip + versions 6.00 and 6.10. The following table shows the effects of + various -D options for both versions. + + UnZip version | + 6.00 | 6.10 | Restore timestamps on: + -----------+-----------+------------------------ + -DD | -D | Nothing. + -D | (default) | Files, not directories. + (default) | -D- | Files and directories. + + [VMS] The old behavior on VMS was the same as the new behavior on + all systems. (The old negated --D option is now -D-, because of + changes to the command-line parser.) +3 -d +-d dest_dir +--extract-dir dest_dir + + Specifies a destination directory for extracted files. By default, + files are extracted (and subdirectories created) in the current + directory. With "-d dest_dir", extraction is done into the + specified directory, instead. See also -da. + + The option and directory may be concatenated without any white space + between them, but this may cause normal shell behavior to be + suppressed. For example, "-d ~" (tilde) is expanded by Unix shells + into the name of the user's home directory, but "-d~" is treated as + a literal "~" subdirectory of the current directory. + + [VMS] On VMS, only a VMS-style device:[directory] specification is + permitted. +3 -d +-da[=reuse] +--auto-extract-dir[=reuse] + + Specifies a destination directory for extracted files which is + derived from the base name of the archive. By default, files are + extracted (and subdirectories created) in the current default + directory. With -da, UnZip automatically derives a subdirectory + name from the archive name, creates that subdirectory, and extracts + files into that subdirectory. + + For example, with -da, extraction of "fred.zip" is done into + subdirectory "[.fred]" instead of into the current directory. (On + non-VMS, systems, subdirectory "fred".) + + For greater safety, by default, UnZip will refuse to extract into an + automatic extraction directory which already exists. Specifying the + optional keyword "reuse" will allow an existing directory to be + used. + + If -da is specified as a default option in an environment variable, + it can be overridden by either a negated -da- option or an explicit + "-d dest_dir" option. See also -d. +3 -f +-f +--freshen + + Primary Mode. Freshen existing files. For details, see + Options_Primary_Mode. +3 -h +-h +--help + + Primary Mode. Display brief (roughly 24 lines) usage instructions. + For details, see Options_Primary_Mode. +3 -hh +-hh +--long-help + + Primary Mode. Display complete usage instructions. For details, + see Options_Primary_Mode. +3 -i +-i +--no-mac-ef-names + + [MacOS (pre-OS-X)] Ignore filenames stored in MacOS extra fields. + Instead, the most compatible filename stored in the generic part of + the member's header is used. +3 -J +-J +--junk-attrs + + [BeOS] Junk file attributes. The file's BeOS file attributes are + not restored, only the file's data. + + [MacOS] Ignore MacOS extra fields. All Macintosh-specific info is + skipped. AppleDouble files are restored as separate files. +3 -j +-j[=depth] +--junk-dirs[=depth] + + Junk directories on extracted files. With -j, all directory + information is stripped from an archive member name, so all files + are extracted into the destination directory. (See also -d.) + + If a depth ("=depth", where "depth" is a positive integer) is + specified, then that number of directory levels will be stripped + from an archive member name. For example, an archive member like + "a/b/c/d/ee.txt" would normally be extracted as "[.a.b.c.d]ee.txt". + With -j, it would be extracted as "ee.txt". With -j=2, the first + two directory levels would be stripped, so it would be extracted as + "[.c.d]ee.txt". +3 --jar + + Treat archive(s) as Java JAR. Over-simplification in Java JAR + archives can cause UnZip to transform UTF-8 file names according to + inappropriate (MS-DOS) rules, yielding corrupt names on extracted + files (typically those with ASCII codes 128-255). Archives + containing a Java "CAFE" extra field should be detected + automatically, and handled correctly, but not all JAR archives + include that extra field. Specifying --jar tells UnZip to expect + UTF-8 file names, regardless of whether the archive contains a + "CAFE" extra field. +3 -K +-K +--keep-s-attrs + + [AtheOS, BeOS, Unix] Retain SUID/SGID/Tacky permission bits. By + default, these permission bits are cleared, for security reasons. +3 -k +--keep-permissions + + [AtheOS, BeOS, Unix, VMS] Control how archived permissions or + protections are restored on extracted files and directories. + + By default, archived permissions are restored with some limitations. + On AtheOS, BeOS, and Unix, the current umask value is applied (to + the normal user/group/other permissions). On VMS, the current + default protection is applied to the UIC-based (SOGW) protections. + + With -k, the archived permissions are restored without regard to the + Unix umask or VMS default protection. (This was the default + behavior in UnZip versions before 6.10.) + + With -k-, the archived permissions are ignored, so only the Unix + umask or VMS default protection is effective. (On VMS, directories + are always created without any Delete access.) + + On AtheOS, BeOS, and Unix, the SUID/SGID/Tacky permission bits are + controlled by the -K/--keep-s-attrs option, regardless of the + -k/--keep-permissions setting. +3 -ka +--keep-acl [VMS] Restore ACLs on extracted files and directories. +3 -L +-L +--lowercase-names + + Convert to lowercase any filename originating on an uppercase-only + operating system or file system. (This was UnZip's default behavior + in versions before 5.11. The current default behavior is the same + as the old behavior with the -U option. -U is now used for another + purpose.) + + Depending on the archiver, files archived from single-case file + systems (old MS-DOS FAT, VMS ODS2, and so on) may be stored as + all-uppercase names; this can be ugly or inconvenient when + extracting to a case-preserving file system such as OS/2 HPFS or a + case-sensitive one such as on Unix. By default UnZip lists and + extracts such filenames exactly as they're stored (excepting + truncation, conversion of unsupported characters, an so on). With + -L, the names of all files from certain systems will be converted to + lowercase. With -LL, all file names will be down-cased, regardless + of the originating file system. +3 -l +-l +--list + + Primary Mode. List archive members. For details, see + Options_Primary_Mode. +3 -M +-M ([CMS,MVS] Or: " -m ) +--more + + Pipe all output through an internal pager similar to the Unix + more(1) command. At the end of a screenful of output, UnZip pauses + with a "--More--" prompt; the next screenful may be viewed by + pressing the Enter (Return) key or the space bar. UnZip can be + terminated by pressing the "q" key and, on some systems, the + Enter/Return key. Unlike Unix more(1), there is no + forward-searching or editing capability. Also, UnZip doesn't notice + if long lines wrap at the edge of the screen, effectively resulting + in the printing of two or more lines and the likelihood that some + text will scroll off the top of the screen before being viewed. If + the actual number of lines on the screen can not be determined, 24 + lines will be assumed. +3 -mc +-mc +--member-counts + + Control inclusion of separate member counts for directories, files, + and links, after the totals summary at the end of the report. By + default, they are included. Use "-mc-" or "--member-counts-" to + suppress them. See also -t. +3 -N +-N +--comment-to-note + + [Amiga] Extract member comments as Amiga filenotes. Member comments + are created with the -c option of Zip, or with the -N option of the + Amiga port of Zip, which stores filenotes as comments. +3 -n +-n +--never-overwrite + + When extracting, never overwrite existing files. If a file already + exists, skip the extraction of that file without asking. See also + -o (--overwrite). + + By default, UnZip queries the user before extracting any file that + already exists. The user may choose to overwrite only the current + file, overwrite all files, skip extraction of the current file, skip + extraction of all existing files, or rename the current file (choose + a new name for the extracted file). + + [VMS] On VMS, the usual query choices are to create a new version of + an existing file, to skip extraction, or to rename the current file. + In the case where an archive member name includes a version number, + and -V ("retain VMS file version numbers") is in effect, then an + additional query choice is offered: to overwrite the existing file. +3 -O +-O +--oem-char-set char_set + + [Unix] Select OEM character set char_set. +3 -o +-o +--overwrite + + Always overwrite existing files without prompting. This is a + dangerous option, so use it with care. (It is often used with -f, + however, and is the only way to overwrite directory EAs on OS/2.) + + By default, UnZip queries the user before extracting any file that + already exists. + + [Non-VMS] On non-VMS systems, the user may choose to overwrite only + the current file, overwrite all files, skip extraction of the + current file, skip extraction of all existing files, or rename the + current file (choose a new name for the extracted file). + + [VMS] On VMS, the usual query choices are to create a new version of + an existing file, to skip extraction, or to rename the current file. + In the case where an archive member name includes a version number, + and -V ("retain VMS file version numbers") is in effect, then an + additional query choice is offered: to overwrite the existing file. + In this case, -o selects the "new version" choice, and -oo (or "-o + -o") selects the "overwrite" choice. +3 -P +-P password +--password password + + Use "password" to decrypt encrypted archive members (if any). THIS + IS INSECURE! Many multi-user operating systems provide ways for any + user to see the current command line of any other user. Even on + stand-alone systems, there is always the threat of over-the-shoulder + peeking. Storing the plaintext password as part of a command line + in an automated script can be even less secure, Whenever possible, + use the non-echoing, interactive prompt to enter passwords. Where + security is truly important, use a strong encryption method, such as + AES, instead of the relatively weak encryption provided by + Traditional ZIP encryption. Or, use an external encryption program, + such as GnuPG, before archiving the file. (Note that Zip will + probably not be able to do significant compression on a file which + has already been encrypted.) +3 -p +-p +--pipe-to-stdout + + Primary Mode. Extract files to stdout (pipe). For details, see + Options_Primary_Mode. +3 -q +-q +--quiet + + Perform operations quietly. (-qq: even more quietly). By default, + UnZip prints the names of the files it's extracting or testing, the + extraction methods, any member or archive comments that may be + stored in the archive, and possibly a summary when finished with + each archive. The -q[q] options suppress the printing of some or + all of these messages. +3 -r +-r +--remove-exts + + [Tandem] Remove file extensions. +3 -S +-S +--streamlf + + [VMS] Use Stream_LF record format when converting extracted text + files (-a, -aa), instead of the text-file default, variable-length + record format. + + [VMS] On VMS, for archives with VMS attribute information (made with + "zip -V"), files are always created with their original record + formats. For archives without VMS attribute information (not made + with "zip -V"), all files are normally created with Stream_LF record + format. With -a, text files are normally created with + variable-length record format, but adding -S gives them Stream_LF + record format. With -aa, all files are treated as text files. See + also -a and -b. +3 -s +-s +--space-to-uscore + + [OS/2, NT, MS-DOS] Convert spaces in filenames to underscores. + Because all these operating systems allow spaces in filenames, UnZip + normally extracts filenames with spaces intact (for example, "EA + DATA. SF"). Working with such file names can be awkward, however, + so -s can be used to replace spaces with underscores. +3 -sc +-sc +--show-command + + Show processed command line (options, arguments), and then exit. + + Strictly speaking this is a primary-mode option, but it's intended + for use in program development, not in normal use. +3 -si +-si +--show-pid + + [Non-VMS] Show the UnZip program's process ID (pid) before + performing any other work. This value can then be used in a "kill + -USR1 pid" command to trigger a user-triggered progress report. +3 -so +-so +--show-options + + Display all valid program options, then exit. + + Strictly speaking this is a primary-mode option, but it's intended + for use in program development, not in normal use. +3 -T +-T +--timestamp-new + + Primary Mode. Set the timestamp on the archive(s) to that of the + newest file in each one. For details, see Options_Primary_Mode. +3 -t +-t +--test + + Primary Mode. Test archive members. For details, see + Options_Primary_Mode. +3 -U +-U +--unicode + + [UNICODE_SUPPORT] Control UTF-8 handling. When UNICODE_SUPPORT is + available, -U forces UnZip to escape all non-ASCII characters from + UTF-8 coded filenames as "#Uxxxx' (for UCS-2 characters, or + "#Lxxxxxx" for Unicode codepoints needing 3 octets). This option is + mainly provided for debugging purpose when the fairly new UTF-8 + support is suspected to mangle up extracted filenames. + + -UU disables the recognition of UTF-8 encoded filenames. The + handling of filename codings within UnZip falls back to the behavior + of previous versions. + + [old, obsolete usage] Leave filenames uppercase if created on + MS-DOS, VMS, and so on. See -L. +3 -u +-u +--update + + Primary mode. Update existing files and create new ones if needed. + For details, see Options_Primary_Mode. +3 -V +-V +--keep-versions + + [Non-CMS-MVS] Retain VMS file version numbers. VMS files can be + stored with a version number, in the format "file.type;##", where + "##" is a decimal number. By default the ";##" version numbers are + stripped, but this option allows them to be retained. (On file + systems that limit filenames to particularly short lengths, the + version numbers may be truncated or stripped regardless of this + option.) + + [Non-VMS] Note that before UnZip version 6.10, on a non-VMS system, + a file with a name like "fred;123" would, by default, be extracted + as "fred", even if the file did not originate on a VMS system (so + that ";123" was probably not really a VMS version number). + Beginning with UnZip version 6.10, the default behavior is to strip + VMS version numbers only from files which were archived on a VMS + system. To restore the old behavior, and always strip apparent VMS + version numbers, explicitly negate the option: "-V-". +3 -v +-v +--verbose + + When used with some primary mode option, -v can make output more + verbose. See also Primary Mode options, and -l in particular. + + Note: If only -v (--verbose) is specified with an archive name, + then UnZip acts as if "-l -v" were specified, and a detailed listing + is generated. +3 -W +-W +--wild-no-span + + [WILD_STOP_AT_DIR] (Valid when the program was built with the C + macro WILD_STOP_AT_DIR defined.) By default, the wildcard characters + "?" (single-character wildcard) and "*" (multi-character wildcard) + match any character in a member path/name. "-W" modifies the + pattern-matching behavior for archive members so that both "?" + (single-character wildcard) and "*" (multi-character wildcard) do + not match the directory separator character "/". (The two-character + sequence "**" acts as a multi-character wildcard that includes the + directory separator in its matched characters.) For example, with + "-W": + + "*.c" matches "foo.c" but not "mydir/foo.c" + "**.c" matches both "foo.c" and "mydir/foo.c" + "*/*.c" matches "bar/foo.c" but not "baz/bar/foo.c" + "??*/*" matches "ab/foo" and "abc/foo" + but not "a/foo" or "a/b/foo" + + This modified behavior is equivalent to the pattern matching style + used by the shells of some of UnZip's supported target OSs (one + example is Acorn RISC OS). This option may not be available on + systems where the Zip archive's internal directory separator + character "/" is allowed as regular character in native operating + system filenames. + + [non-VMS] Currently, UnZip uses the same pattern matching rules for + both wildcard archive file name specifications and archive member + selection patterns on most system types. For systems allowing "/" + as regular filename character, the -W option would not work as + expected on a wildcard file name specification. +3 -X +-X +--restore-info + + [VMS, Unix, OS/2, NT, Tandem] Restore owner/protection info (UICs + and ACL entries on VMS, or user and group info (UID/GID) on Unix, or + access control lists (ACLs) on certain network-enabled versions of + OS/2 (Warp Server with IBM LAN Server/Requester 3.0 to 5.0; Warp + Connect with IBM Peer 1.0), or security ACLs on Windows NT.) In most + cases this will require special system privileges, and doubling the + option (-XX) on NT instructs UnZip to use privileges for extraction; + but on Unix, for example, a user who belongs to several groups can + restore files owned by any of those groups, so long as the user IDs + match the user's own. Note that ordinary file attributes are always + restored. This option applies only to optional, extra ownership + info available on some operating systems. (NT's access control + lists do not appear to be especially compatible with OS/2's, so no + attempt is made at cross-platform portability of access privileges. + It is not clear under which conditions this would ever be useful + anyway.) +3 -x +-x member ... +--exclude member ... + + An optional list of archive members to be excluded from processing. + Because wildcard characters normally match "/" directory separators + (for exceptions see the option -W), this option may be used to + exclude any files that are in subdirectories. For example, "unzip + foo *.[ch] -x */*" would extract all C source files (*.c, *.h) in + the main directory, but none in any subdirectories. Without the -x + option, all C source files in all directories within the archive + would be extracted. + + When the program sees -x (--exclude) on a command line, it stops + scanning for options, and treats every succeeding item as an archive + member name. To avoid confusion between member names and command + options, it's simplest to specify -x (--exclude) and its member list + as the last items on a command line. Alternatively, the special + name "@" can be used to terminate the member list (and cause the + program to resume scanning for options). That is, the following two + commands are equivalent: + + unzip fred.zip -b -x file1 file2 file3 + unzip fred.zip -x file1 file2 file3 @ -b +3 -Y +-Y +--dot-version + + [VMS] Treat archive member name endings of ".nnn" (where "nnn" is a + decimal number) as if they were VMS version numbers (";nnn"). (The + default is to treat them as file types.) For example: + + "a.b.3" -> "a.b;3" +3 -Z +-Z +--zipinfo-mode + + ZipInfo mode. If the first option on the command line is -Z, then + the program runs in ZipInfo mode, which is used to display + information about an archive and its members. Remaining options are + interpreted as ZipInfo options. See ZipInfo_mode. +3 -z +-z +--zipfile-comment + + Primary mode. Display only the archive comment. For details, see + Options_Primary_Mode. +3 -$ +-$ +--volume-labels + + [MS-DOS, OS/2, NT] Restore the volume label if the extraction medium + is removable (for example, a diskette). Doubling the option (-$$) + allows fixed media (hard disks) to be labeled as well. By default, + volume labels are ignored. +3 -/ +-/ +--extensions + + [Acorn] Overrides the extension list supplied by the Unzip$Ext + environment variable. During extraction, filename extensions that + match one of the items in this extension list are swapped in front + of the base name of the extracted file. +3 -: +-: +--do-double-dots + + [all but Acorn, VM/CMS, MVS, Tandem] Allows UnZip to extract archive + members into locations outside of the current extraction destination + directory (and its subdirectories). + + For security reasons, UnZip normally removes "parent directory" path + components ("../") from the path names of archive members as they + are extracted. This safety feature (new for version 5.50) prevents + UnZip from accidentally writing files to directories outside the + current destination directory tree. The -: option sets UnZip back + to its previous, more liberal behavior, allowing exact extraction of + archives that use "../" path components to create multiple directory + trees at or above the level of the destination directory. + + This option does not enable writing explicitly to the root directory + ("/"). To achieve this, it is necessary to set the extraction + target folder to "/" (by using an option like "-d /"). However, + when the -: option is specified, it is still possible implicitly to + write to the root directory if member paths specifying enough "../" + path components. + + Use this option with extreme caution. +3 -^ +-^ +--control-in-name + + [Unix] Allow control characters in file names of extracted ZIP + archive members. On Unix, a file name may contain any (8-bit) + character code with the two exceptions of "/" (the directory + delimiter) and NUL (0x00, the C string-termination character), + unless the specific file system has more restrictive conventions. + Generally, this allows embedding ASCII control characters or escape + sequences in file names. However, this feature allows the use of + malicious file names which can cause various kinds of bad trouble + when displayed on a user's terminal/emulator. (Even a file name + with unprintable but otherwise harmless characters can cause + problems for users.) + + For these reasons, by default, UnZip applies a filter that removes + potentially dangerous control characters from the extracted file + names. The -^ option overrides this filter in the rare case that + embedded filename dangerous control characters are to be + intentionally restored. +2 Environment_Options + UnZip's default behavior may be modified by placing command-line + options in an environment variable. This can be done with any + option, but it is probably most useful options like -a (auto-convert + text files), -L (downcase file names from systems with all uppercase + file names), -C (use case-insensitive name matching), -q (quiet), -o + (always overwrite), or -n (never overwrite). + + For UnZip, the environment variable name on VMS is UNZIP_OPTS + (non-VMS: UNZIP). The name on VMS is different to avoid conflict + with a foreign-command DCL symbol, UNZIP. For compatibility with + Zip, if UNZIP_OPTS is not defined, then UnZip will use UNZIPOPT the + same way. + + For ZipInfo ("unzip -Z"), the environment variable name on VMS is + ZIPINFO_OPTS (non-VMS: ZIPINFO). For compatibility with Zip, if + ZIPINFO_OPTS is not defined, then ZipInfo will use ZIPINFOOPT the + same way. + + For example, to make UnZip act as quietly as possible, only + reporting errors, one could use commands like the following: + + Unix Bourne (or similar) shell: + UNZIP='-q -q'; export UNZIP + + Unix C shell: + setenv UNZIP '-q -q' + + OS/2 or MS-DOS: + set UNZIP="-q -q" + + VMS (with quotation to preserve lower case in DCL): + define UNZIP_OPTS "-q -q" ! Logical name, or + UNZIP_OPTS = "-q -q" ! DCL symbol. (Either works.) + + Environment options are treated the same as any other command-line + options, except that they are effectively the first options on the + command line. To override an environment option, one may use an + explicit option to cancel or override it. For example, to override + one of the "quiet" flags in the example above, use a command like: + + unzip -q- [other options] archive.zip + + The leading hyphen is the normal option character, and the trailing + one negates the option, canceling one level of quietness. To cancel + multiple "quiet" flags, use multiple -q- options: + + unzip -t -q- -q- archive + unzip -q- -q- -t archive + + Note that multiple one-character options like "-q" and "-q" can be + combined into a single "-qq", but it's generally clearer to keep + each instance of each option separate. Similarly, negated + one-character options can be combined, as with "-q-q-", but "-q- + -q-" is generally clearer. + + The examples show short (one-character) options, but long ("--") + options are also allowed. +2 Encryption_Decryption + Zip and UnZip have long supported a relatively weak encryption + method, which we call Traditional ZIP encryption. The source code + for Traditional encryption is included in the source kits, and + support for Traditional encryption is enabled by default. + (Build-time C macro: CRYPT_TRAD.) + + Beginning with UnZip version 6.10 and Zip version 3.1, these + programs also offer a stronger, Advanced Encryption Standard (AES) + encryption method, which we call AES WinZip/Gladman (AES_WG) + encryption. (The encryption code was supplied by Brian Gladman, and + the archive format is intended to be compatible with that used by + the WinZip program. WinZip is a registered trademark of WinZip + International LLC.) The source code for AES_WG encryption is + distributed in a separate kit (for export control reasons), and + support for AES_WG encryption must be enabled explicitly at build + time. (Build-time C macro: CRYPT_AES_WG.) See the INSTALL file in + the source kit for details on how to enable AES_WG encryption (or + how to disable Traditional encryption). + + For details on the WinZip AES scheme, see: + http://www.winzip.com/aes_info.htm + + For information on the separate AES_WG source kit, see: + ftp://ftp.info-zip.org/pub/infozip/crypt/ + ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt + + Normally, encryption passwords are supplied by the user + interactively when requested by the program. See the -P option for + a (less secure) method of specifying a password on the command line. + + With Traditional encryption, when decrypting, a password will be + checked against header data, and used if it appears to be correct. + The correct password will always check out against the header data, + but there is a 1-in-256 chance that an incorrect password will as + well. (This is a security feature of the PKWARE archive format; it + helps prevent brute-force attacks that might otherwise gain a large + speed advantage by testing only the header.) In the case that an + incorrect password is given but it passes the header test anyway, + either an incorrect CRC will be generated for the extracted data or + else UnZip will fail during the extraction because the "decrypted" + bytes do not constitute a valid compressed data stream. + + If the first password fails the header check on some file, UnZip + will prompt for another password, and so on until all files are + extracted. If a password is not known, entering a null password + (that is, just a carriage return or "Enter") is taken as a signal to + skip all further prompting. Only unencrypted files in the + archive(s) will thereafter be extracted. (The situation is actually + a little more complicated. Some old versions of Zip and ZipCloak + allowed null passwords, so UnZip checks each encrypted file to see + if the null password works. This may result in "false positives" + and extraction errors, as noted above.) + + Archives encrypted with 8-bit-character passwords (for example, + passwords with accented European characters) may not be portable + across systems or to other archivers. This problem stems from the + use of multiple encoding methods for such characters, including + Latin-1 (ISO 8859-1) and OEM code page 850. DOS PKZIP 2.04g uses + the OEM code page; Windows PKZIP 2.50 uses Latin-1 (and is therefore + incompatible with DOS PKZIP; Info-ZIP uses the OEM code page on DOS, + OS/2 and Win3.x ports but ISO coding (Latin-1 etc.) everywhere else; + and Nico Mak's WinZip 6.x does not allow 8-bit-character passwords + at all. UnZip 5.3 (or newer) attempts to use the default character + set first (e.g., Latin-1), followed by the alternate one (e.g., OEM + code page) to test passwords. On EBCDIC systems, if both of these + fail, EBCDIC encoding will be tested as a last resort. (EBCDIC is + not tested on non-EBCDIC systems, because there are no known + archivers that encrypt using EBCDIC encoding.) ISO character + encodings other than Latin-1 are not supported. The new addition of + (partial) Unicode (UTF-8) support in UnZip 6.0 has not yet been + adapted to the encryption password handling in UnZip. On systems + that use UTF-8 as native character encoding, UnZip simply tries + decryption with the native UTF-8 encoded password; the built-in + attempts to check the password in translated encoding have not yet + been adapted for UTF-8 support and will consequently fail. +2 Examples + To use UnZip to extract all members of the archive letters.zip into + the current directory and subdirectories below it, creating any + subdirectories as necessary: + + unzip letters + + To extract all members of letters.zip into the current directory + only: + + unzip -j letters + + To test letters.zip, printing only a summary message indicating + whether the archive is OK or not: + + unzip -t -q letters + + To test all ".zip" archives in the current directory, printing only + the summaries: + + unzip -t -q *.zip + + (On a Unix system, the wildcard archive name would typically need to + be quoted to keep a a Unix shell from expanding ("globbing") it. + This is not necessary on VMS.) + + The following command extracts to standard output all members of + letters.zip whose names end in ".tex", auto-converting to the local + end-of-line convention, in Stream_LF record format, and piping the + output into TYPE /PAGE: + + pipe unzip -c -a -S letters *.tex | type /page sys$input + + To extract from source.zip all Fortran and C source files (*.f, *.c, + *.h) and Makefile into the SYS$SCRATCH directory: + + unzip source.zip *.[fch] Makefile -d sys$scratch + + To extract all FORTRAN and C source files, regardless of case (for + example, both *.c and *.C, and any makefile, Makefile, MAKEFILE or + similar): + + unzip -C source.zip *.[fch] makefile -d sys$scratch + + The following command extracts only newer versions of the files + already in the current directory, without querying. (Note: Be + careful of extracting in one timezone an archive created in another. + ZIP archives created by Zip versions before 2.1 contain no timezone + information, and a "newer" file from an eastern timezone may, in + fact, be older): + + unzip -f -o sources + + To extract newer versions of the files already in the current + directory and to create any files not already there (same caveat as + previous example): + + unzip -u -o sources + + To display a configuration report showing the program version, the + OS and compiler used to build it, a list of optional features + enabled at build time, and the values of all the relevant + environment variables: + + unzip -v + + In the last five examples, assume that UNZIP_OPTS is set to -q. To + do a (singly) quiet listing: + + unzip -l file.zip + + To do a doubly quiet listing: + + unzip -l -q file.zip + + (Note that the ".zip" is generally not necessary.) To do a standard + listing: + + unzip -l -q- file.zip + + or: + + unzip -lq- file.zip + + or: + + unzip -q-l file.zip + +2 Exit_Status + UnZip's exit status approximates the exit codes defined by PKWARE. + On VMS, UnZip's UNIX-style exit values are translated into VMS-style + status codes with facility code 1954 = %x7A2, and with the + inhibit-message (%x10000000) and facility-specific (%x00008000) bits + set: + + %x17A28001 normal exit + %x17A28000 + 16*UnZip_error_code warnings + %x17A28002 + 16*UnZip_error_code normal errors + %x17A28004 + 16*UnZip_error_code fatal errors + + Note that multiplying the UNIX-style UnZip error code by 16 places + it conveniently in the hexadecimal representation of the VMS exit + code, "__" in %x17A28__s, where "s" is the severity code. For + example, a missing archive might cause UnZip error code 9, which + would be transformed into the VMS exit status %X17A28092. + + The UnZip VMS exit codes include severity values which approximate + those defined by PKWARE, as shown in the following table: + + VMS UnZip + severity err code Error description + ----------+----------+---------------------------------------------- + Success 0 Normal. No errors or warnings detected. + Warning 1 One or more warnings were encountered, but + processing completed successfully. This + includes archives where one or more (but not + all) files were skipped because of an + unsupported compression or encryption method, + or a bad encryption password. + Error 2 Error in the archive format. Processing may + or may not have completed successfully. + Fatal 3 Severe error in the archive format. + Processing probably failed immediately. + Fatal 4 Memory allocation failed in program + initialization. + Fatal 5 Memory allocation or terminal I/O failed in + password processing. + Fatal 6 Memory allocation failed while decompressing + to disk. + Fatal 7 Memory allocation failed while decompressing + in memory. + Fatal 8 Memory allocation failed. (Currently not + used.) + Error 9 Specified archive files were not found. + Error 10 Invalid command-line options or parameters. + Error 11 No matching files were found. + Fatal 50 Disk (file system) filled during extraction. + Fatal 51 Unexpected end-of-file while reading the + archive. + Error 80 User interrupt (Ctrl/C). + Error 81 No files were processed, because of + unsupported compression or encryption + methods. + Error 82 No files were processed, because of bad + encryption password(s). + Fatal 83 Large-file archive could not be processed by + this small-file program. +2 Bugs + Multi-part archives are not yet supported, except in conjunction + with Zip. (All parts must be concatenated together in order, and + then "zip -F" (for Zip 2.x) or "zip -FF" (for Zip 3.x) must be + performed on the concatenated archive in order to "fix" it. Also, + zip 3.0 and later can combine multi-part (split) archives into a + combined single-file archive using "zip -s- inarchive -O + outarchive". See the zip manual page for more information.) This + may be corrected in the next major release. + + Archives read from standard input are not yet supported, except with + UnZip (and then only the first member of the archive can be + extracted). + + Archives encrypted with 8-bit-character passwords (such as passwords + with accented European characters) may not be portable across + systems and/or other archivers. See also Encryption_Decryption. + + UnZip's -M ("--more") option tries to take into account automatic + wrapping of long lines. However, the code may fail to detect the + correct wrapping locations. First, TAB characters (and similar + control sequences) are not taken into account, they are handled as + ordinary printable characters. Second, depending on the actual + system type, UnZip may not detect the true terminal/emulator + geometry, but instead may rely on "commonly used" default + dimensions. The correct handling of tabs would require the + implementation of a query for the actual tab setup on the output + terminal/emulator. + + [Unix] Unix special files such as FIFO buffers (named pipes), block + devices and character devices are not restored even if they are + somehow represented in the archive, nor are hard-linked files + relinked. Basically, the only file types restored by UnZip are + regular files, directories, and symbolic (soft) links. + + [OS/2] Extended attributes for existing directories are only updated + if the -o ("--overwrite") option is given. This is a limitation of + the operating system; because directories only have a creation time + associated with them, UnZip has no way to determine whether the + stored attributes are newer or older than those on disk. In + practice this may mean a two-pass approach is required: first + unpack the archive normally (with or without freshening/updating + existing files), then overwrite just the directory entries (for + example, "unzip -o foo */"). + + Note that uppercase options (-C, -D, -L, -M, -P, -S, -T, -V, -X, -Y, + and -Z) must be specified in quotes (unless SET PROC/PARSE=EXTEND is + set). For example: + + unzip "-VX" -a zipfile + + When extracting to SYS$OUTPUT (-c or -p options) redirected to a + file, you may want to override the default text file conversion by + specifying the -b option. A single "-b" option switches to "binary + piping" mode for Zip entries marked as non-text, only. To force + "binary piping" mode even for Zip file entries marked as text, the + "-bb" option should be used. (Please note that a later "-a" cancels + any -b option, see below.) + + The output conversion options -b and -a may be combined to perform + binary conversions on binary files and text conversion on text + files. But note: For compatibility with implementation on other + systems, -b cancels any -a option; to get the intended result, -a + must be specified AFTER -b. And, in combination, "text" recognition + takes precedence; this means that -bba (-bb -a) has the same effect + as -ba (-b -a), and -aa overrides binary conversion for ALL files. + + The conversion option -S is only effective when used together with + -a or -aa. When specified, "text" files are written in Stream_LF + record format instead of the VMS default of Variable-Length record + format. (When no conversion options are specified, all non-VMS + entries are always written as Stream_LF files.) + + Please note that using the "-P" option is higly insecure, + the plaintext password may be seen by others. For this reason (and + because of lack of space), the "-P" option is not + advertised on UnZip's online help screen. +2 URL + The Info-ZIP main Web page is: + http://www.info-zip.org/ + + FTP access is available, too: + ftp://ftp.info-zip.org/pub/infozip/ +2 ZipInfo_mode + If the first option on the UnZip command line is "-Z", then the + program runs in ZipInfo mode. Remaining options are interpreted as + ZipInfo options. + + ZipInfo reports detailed information about a ZIP archive and its + members. This information may include file access permissions, + compression method, encryption method, version and operating system + (or file system) of the archive-creating program, and so on. The + default behavior (with no options) is to show a single-line entry + for each member in the archive, with a header and a trailer + providing summary information for the entire archive. The format is + a cross between Unix "ls -l" and "unzip -lv" output. See + Detailed_Description. ZipInfo is the same program as UnZip. (On + Unix, "zipinfo" may be a link to "unzip". On VMS, "zipinfo" is + normally a DCL symbol defined as "''unzip' -Z".) However, ZipInfo + support may have been disabled when UnZip was built. + + Format + + zipinfo [ zipinfo_options ] [ file[.zip] ] [ member ... ] + unzip -Z [ zipinfo_options ] [ file[.zip] ] [ member ... ] +3 Command_Parameters + +file[.zip] + + File path/name of a ZIP archive. A wildcard name may be used to + specify multiple ZIP archives to be processed in one command. On + VMS systems, any of the standard wildcards for a directory/file + specification may be used: "...", "*", or "%" (or, since VMS V7.2, + "?"). The default archive file specification is "[]*.ZIP". + + Note that a ".zip" or ".ZIP" file type on an archive is merely a + convention, not a requirement. For example, a self-extracting ZIP + archive named "fred" or "fred.exe" could be processed as if it were + an ordinary archive; just specify the actual file name with its + actual name ending (if any), whatever that may be. + +member ... + + An optional list of archive members to be processed, separated by + spaces. Unix-like ("globbing") wildcard patterns may be used to + match multiple members: + + * Matches a sequence of 0 or more characters. + ? Matches exactly 1 character. + [...] Matches any single character found inside the brackets. + Ranges are specified by a beginning character, a hyphen, and + an ending character. If an exclamation point ("!") or a + caret ("^") follows the left bracket, then the range of + characters within the brackets is complemented. That is, + anything except the characters inside the brackets is + considered a match. To specify a literal left bracket, use + the three-character sequence "[[]". +3 Options_Primary_Format + Options in this group (-1, -2, -l, -m, -s, -v) specify the primary + report format of ZipInfo. Only one of these primary format options + may be specified. +4 -1 +-1 +--names-only + + Primary Format. Show member names only, one per line. This option + excludes all others, and the report does not include headers, + trailers, or archive comments. This format may be useful with Unix + shell (or other) scripts. +4 -2 +-2 +--names-mostly + + Primary Format. Show member names only, one per line (as with + "-1"), but allow headers (-h), trailers (-t), and archive comments + (-z), if requested explicitly. +4 -l +-l +--long-list + + Primary Format. Show member info in long Unix "ls -l" format. Like + the -m format, except that the compressed size (in bytes) is printed + instead of the compression ratio. +4 -m +-m +--medium-list + + Primary Format. Show member info in medium-length Unix "ls -l" + format. Like the -s format, except that the compression factor, + expressed as a percentage, is also included. +4 -s +-s +--short-list + + Primary Format. Show member info in short Unix "ls -l" format. + This is the default behavior, unless -h or -t is specified. +4 -v +-v +--verbose + + Primary Format. The verbose report is very detailed, and mostly + self-explanatory, but it does assume some familiarity with the ZIP + archive format. It also includes the archive comment, if any. + Extra fields in the central directory are broken dowm into + subfields, with brief descriptions of recognized subfields (or + abbreviated dumps of unrecognized subfields). +3 Options_Ordinary + Options in this group modify the operation or report format of + ZipInfo. +4 -C +-C +--ignore-case ([CMS, MVS] --CMS-MVS-lower) + + Use case-insensitive name matching for names in the member list and + the -x excluded-member list on the command line. By default, + case-sensitive matching is done. For example, specifying "makefile" + on the command line will match only "makefile" in the archive, not + "Makefile" or "MAKEFILE". On many systems, the local file system is + case-insensitive, so case-insensitive name matching would be more + natural. With -C, "makefile" would match "makefile", "Makefile", or + "MAKEFILE". + + /CASE_MATCH does not affect the search for the ZIP archive file(s). +4 -h +-h +--header + + Include a header in the report, showing the archive name, the + archive size (in bytes), and the number of members in the archive. + + For the Unix-format reports (options -l, -m, -s), the header is + included by default, if no archive members are specified. If -h is + specified alone, that is, without one of the Unix-format options, + and without a member list, then only the header lines will be put + out. +4 -M +-M ([CMS,MVS] Or: -m) +--more + + Pipe all output through an internal pager similar to the Unix + more(1) command. At the end of a screenful of output, Zipinfo + pauses with a "--More--" prompt; the next screenful may be viewed by + pressing the Enter (Return) key or the space bar. ZipInfo can be + terminated by pressing the "q" key, or, on some systems, the + Enter/Return key. Unlike Unix more(1), there is no + forward-searching or editing capability. Also, ZipInfo doesn't + notice if long lines wrap at the edge of the screen, effectively + resulting in the printing of two or more lines and the likelihood + that some text will scroll off the top of the screen before being + viewed. If the actual number of lines on the screen can not be + determined, 24 lines will be assumed. +4 -T +-T +--decimal-time + + Show the file date-times in a sortable, all-numeric, + "YYYYMMDD.hhmmss" format. The default date format is an + alpha-numeric "YY-Mmm-DD hh:mm". For example ("-s", "-s -T"): + + -rw-a-- 3.1 fat 211916 tx defX 10-Jun-18 00:27 zip31c/zip.c + -rw-a-- 3.1 fat 211916 tx defX 20100618.002703 zip31c/zip.c +4 -t +-t +--totals + + Include a totals summary at the end of the report, showing the + number of members in the report, the sum of their uncompressed + sizes, the sum of their compressed sizes, and the compression factor + as a percentage. + + For the Unix-format reports (options -l, -m, -s), the totals summary + is included by default, if no archive members are specified. If -t + is specified alone, that is, without one of the Unix-format options, + and without a member list, then only the totals summary trailer + lines will be put out. + + The total "bytes compressed" reported includes only the actual data, + not the ZIP archive meta-data, so the size of the archive will + always be greater than this value. + + See also -mc. +4 -U +-U +--unicode + + [UNICODE_SUPPORT] Control UTF-8 handling. When UNICODE_SUPPORT is + available, -U forces ZipInfo to escape all non-ASCII characters from + UTF-8 coded filenames as "#Uxxxx" (for UCS-2 characters, or + "#Lxxxxxx" for Unicode codepoints needing 3 octets). This option is + mainly provided for debugging purpose when the fairly new UTF-8 + support is suspected of damaging extracted filenames. + + -UU disables the recognition of UTF-8 encoded filenames. The + handling of filename codings within ZipInfo falls back to the + behavior of pre-Unicode versions. +4 -W +-W +--wild-no-span + + [WILD_STOP_AT_DIR] (Valid when the program was built with the C + macro WILD_STOP_AT_DIR defined.) By default, the wildcard characters + "?" (single-character wildcard) and "*" (multi-character wildcard) + match any character in a member path/name. "-W" modifies the + pattern-matching behavior for archive members so that both "?" + (single-character wildcard) and "*" (multi-character wildcard) do + not match the directory separator character "/". (The two-character + sequence "**" acts as a multi-character wildcard that includes the + directory separator in its matched characters.) For example, with + "-W": + + "*.c" matches "foo.c" but not "mydir/foo.c" + "**.c" matches both "foo.c" and "mydir/foo.c" + "*/*.c" matches "bar/foo.c" but not "baz/bar/foo.c" + "??*/*" matches "ab/foo" and "abc/foo" + but not "a/foo" or "a/b/foo" + + This modified behavior is equivalent to the pattern matching style + used by the shells of some of UnZip's supported target OSs (one + example is Acorn RISC OS). This option may not be available on + systems where the Zip archive's internal directory separator + character "/" is allowed as regular character in native operating + system filenames. (Currently, UnZip uses the same pattern matching + rules for both wildcard archive file name specifications and archive + member selection patterns on most system types. For systems + allowing "/" as regular filename character, the -W option would not + work as expected on a wildcard file name specification.) +4 -x +-x member ... +--exclude member ... + + An optional list of archive members to be excluded from processing. + Because wildcard characters normally match "/" directory separators + (for exceptions see the option -W), this option may be used to + exclude any files that are in subdirectories. For example, "unzip + foo *.[ch] -x */*" would extract all C source files (*.c, *.h) in + the main directory, but none in any subdirectories. Without the -x + option, all C source files in all directories within the archive + would be extracted. + + When the program sees -x (--exclude) on a command line, it stops + scanning for options, and treats every succeeding item as an archive + member name. To avoid confusion between member names and command + options, it's simplest to specify -x (--exclude) and its member list + as the last items on a command line. Alternatively, the special + name "@" can be used to terminate the member list (and cause the + program to resume scanning for options). That is, the following two + commands are equivalent: + + zipinfo fred.zip -2 -t -x file1 file2 file3 + zipinfo fred.zip -x file1 file2 file3 @ -2 -t +4 -z +-z +--zipfile-comment + + Include the archive comments (if any) in the report. +3 Detailed_Description + ZipInfo has three basic report formats, providing different degrees + of detail in the information about the members of an archive: a + simple list of names (-1, -2), a Unix ls-style listing (-l, -m, -s), + and a very detailed analysis (-v). Some of the information, such as + file sizes, is easy to interpret. Some of the information involves + fairly obscure details of ZIP archive structure. ZIP archive + structure is documented in the PKWARE Inc. APPNOTE.TXT: + http://www.pkware.com/documents/casestudies/APPNOTE.TXT + + The table below shows some typical -l report entries: + + Perm/Prot Zver Ofs UncSize At CmpSize Cmth ModDate Mtime Name + ----------+----+---+-------+--+-------+----+---------------+---------- + -rw-a-- 3.1 fat 211916 tx 53467 defX 10-Jun-18 00:27 zip3/zip.c + -rwxr-x--- 3.1 unx 709 Tx 311 aesw 11-Aug-21 22:20 endian.c + RWED,RE, 3.1 vms 6656 bx 2295 defN 07-Aug-15 14:12 it/T.EXE;8 + + Field 1 (Perm/Prot) shows the file permission/protection attributes, + formatted according to the original operating system or file system + where the archive was created. + + Field 2 (Zver) shows the (approximate) version of the Zip program + which created the archive. + + Field 3 (Ofs) shows the original operating system where the archive + was created, or the file system on which the member file was stored. + + Field 4 (UncSize) shows the original, uncompressed file size. + + Field 5 (At) shows some archive member attributes, as detailed in + the tables below. The first character indicates whether a file was + binary or text, and whether it was encrypted. The second character + indicates the presence of a data descriptor and/or an extra field in + the member data. + + | File Type Extra Field | + First char | binary text yes no | Second char + --------------+-------+----- ------+-----+-------------------- + Encrypted no | b t x - | no Data Descriptor + yes | B T X l | yes + + A Data Descriptor holds CRC and size data at an alternate place in + the archive (after processed member data instead of before), and is + normally used when the archiving program can't seek in the output + archive data/file. An Extra Field can hold a wide variety of data, + including 64-bit file sizes, many kinds of OS-specific attribute + data, UTC times, and so on. + + Field 6 (CmpSize) shows the compressed file size. With -m, this + field shows the compression fraction as a percentage. With -s (the + default), this field is omitted. This compressed size value (unlike + the one in an "unzip -l" report) includes all the overhead resulting + from Traditional encryption. + + Field 7 (Cmth) shows the compression method used. Note that AES_WG + encryption is treated as a compression method here. Not all of the + methods shown in the table below are supported. (Some are + obsolete.) + + Num Abbr Name, description + ----+----+------------------------------------------------------------ + 0 stor Store (no compression) + 1 shrk Shrink + 2 re:1 Reduce (factor 1) + 3 re:2 Reduce (factor 2) + 4 re:3 Reduce (factor 3) + 5 re:4 Reduce (factor 4) + 6 i#:# Implode (dictonary_size:Shannon-Fano_trees) + 7 tokn Tokenize + 8 def# Deflate (N: normal, X: maximum, F: fast, S: super-fast) + 9 d64# Deflate64 (N: normal, X: maximum, F: fast, S: super-fast) + 10 dcli PKWARE Data Compression Library Imploding - IBM TERSE (old) + 12 bzp2 bzip2 + 14 lzma LZMA + 18 ters IBM TERSE (new) + 19 lz77 IBM LZ77 z Architecture (PFS) + 96 jpeg JPEG + 97 wavp WavPack + 98 ppmd PPMd version I, Rev 1 + 99 aesw AES_WG encryption + + Fields 8 and 9 (ModDate, Mtime) show the file modification date-time + (MS-DOS format, local time). + + Field 10 (Name) shows the file path/name. +3 Environment_Options + ZipInfo's default behavior may be modified by placing command-line + options in an environment variable. This can be done with any + option, but it is probably most useful options like -T (decimal time + format) or one of the non-default Unix format options: -l, -m. + + For ZipInfo ("unzip -Z"), the environment variable name on VMS is + ZIPINFO_OPTS (non-VMS: ZIPINFO). For compatibility with Zip, if + ZIPINFO_OPTS is not defined, then ZipInfo will use ZIPINFOOPT the + same way. + + For example, to make the default format the long Unix format instead + of the short Unix format, one could use commands like the following: + + Unix Bourne (or similar) shell: + ZIPINFO='-l'; export UNZIP + + Unix C shell: + setenv ZIPINFO '-l' + + OS/2 or MS-DOS: + set ZIPINFO="-l" + + VMS (with quotation to preserve lower case in DCL): + define ZIPINFO_OPTS "-l" ! Logical name, or + ZIPINFO_OPTS = "-l" ! DCL symbol. (Either works.) + + Environment options are treated the same as any other command-line + options, except that they are effectively the first options on the + command line. To override an environment option, one may use an + explicit option to cancel or override it. For example, to disable + the totals trailer line by default, one could use commands like the + following: + + Unix Bourne (or similar) shell: + ZIPINFO='-t-'; export ZIPINFO + + Unix C shell: + setenv ZIPINFO '-t-' + + VMS (with quotation to preserve lower case in DCL): + define ZIPINFO_OPTS "-t-" ! Logical name, or + ZIPINFO_OPTS = "-t-" ! DCL symbol. (Either works.) + + The examples show short (one-character) options, but long ("--") + options are also allowed. +3 Examples + To get a basic, short-format listing of the complete contents of a + ZIP archive zip31c.zip, with both header and totals lines, use only + the archive name as an argument to zipinfo: + + zipinfo zip31c.zip + zipinfo zip31c + + To produce a basic, long-format listing (not verbose), including + header and totals lines, use -l: + + zipinfo -l zip31c.zip + + To list the complete contents of the archive without header and + totals lines, either negate the -h and -t options or else specify + the contents explicitly: + + zipinfo -h- -t- zip31c.zip + zipinfo zip31c.zip * + + (On a Unix system, the wildcard member name would typically need to + be quoted to keep a a Unix shell from expanding ("globbing") it. + This is not necessary on VMS.) + + To list information on a single archive member, in medium format, + specify the member name explicitly: + + zipinfo -m unzip60.zip */unshrink.c + + When any member name is specified, the header and totals trailer + are, by default, not included in the report, but explicitly + specifying -h and/or -t will restore them. For example: + + zipinfo -m -t unzip610b.zip *.[ch] */Make* + + On a Unix system, one could use the -T option along with an external + sorting program (and another filter like "head" or "tail") to get a + listing of the least or most recently modified files in the archive: + + zipinfo -l -T -h- -t- zip31c.zip | sort -k 8 | head -12 + zipinfo -l -T -h- -t- zip31c.zip | sort -r -k 8 | head -12 + + The "sort" option "-k 8" tells it to sort on field 8, which is the + date-time field in a long- or medium-format (-l, -m) ZipInfo report. + (Use "-k 7" for the short (-s) format.) The -r option reverses the + default smallest-to-largest sort order. +3 Bugs + As with UnZip, ZipInfo's -M ("--more") option is overly simplistic + in its handling of screen output. As noted above, it fails to + detect the wrapping of long lines and may thereby cause lines at the + top of the screen to be scrolled off before being read. ZipInfo + should detect and treat each occurrence of line-wrap as one + additional line printed. This requires knowledge of the screen's + width as well as its height. In addition, ZipInfo should detect the + true screen geometry on all systems. + + The interactions among the various listing format, header, and + trailer options (-h, -l, -m, -s, -t) are unnecessarily complex and + should be simplified, despite the potential disruption to current + users. +3 URL + The Info-ZIP main Web page is: + http://www.info-zip.org/ + + FTP access is available, too: + ftp://ftp.info-zip.org/pub/infozip/ diff --git a/UNZIP_CLI.HLP b/UNZIP_CLI.HLP new file mode 100644 index 0000000..813710d --- /dev/null +++ b/UNZIP_CLI.HLP @@ -0,0 +1,1342 @@ +1 UNZIP + UnZip lists, tests, or extracts files from a ZIP archive (an + archive format commonly used on many different systems). The + default behavior (with no options) is to extract into the current + directory (and subdirectories below it) all files from the + specified ZIP archive. A companion program, Zip, creates ZIP + archives. + + Info-ZIP UnZip and Zip were intended to be compatible with archives + created by PKWARE's PKZIP and PKUNZIP programs (originally for + MS-DOS), but in many cases the program options or default behaviors + differ. Nowadays, many other programs are available which work + with ZIP archives. + + This help file describes the VMS CLI edition of UnZip. A + Unix-style command-line edition is also available, with a separate + help file. + + The VMS CLI edition of UnZip adds a command-line translator to the + normal UnZip program. This translator transforms a set of + VMS-style qualifiers and parameters into an equivalent set of + Unix-style options and parameters, and then passes those + transformed arguments to UnZip's standard Unix-style command-line + processor. The documentation often shows the related Unix-style + options in parentheses after a VMS-style qualifier. For example: + /HELP (-h, -hh). + + Format: + + UNZIP [/unzip_qualifiers] [file[.zip]] [member [,...]] + + UNZIP /ZIPINFO [/zipinfo_qualifiers] [file[.zip]] [member [,...]] + + ZIPINFO [/zipinfo_qualifiers] [file[.zip]] [member [,...]] + + To display the basic built-in help, use the command: + + UNZIP /HELP + + To display the extended built-in help, use the command: + + UNZIP /HELP=EXTENDED + + The built-in help may be more current than this help file, + especially between full product releases. + + The VMS CLI edition of the program can also provide built-in help + on the Unix-style command-line edition; just use the "-h" or "-hh" + options. +2 Command_Parameters + file[.zip] + + File path/name of a ZIP archive. A wildcard name may be used to + specify multiple ZIP archives to be processed in one command. + On VMS systems, any of the standard wildcards for a + directory/file specification may be used: "...", "*", or "%" + (or, since VMS V7.2, "?"). The default archive file + specification is ".ZIP". + + Note that a ".zip" or ".ZIP" file type on an archive is merely a + convention, not a requirement. For example, a self-extracting + ZIP archive named "fred" or "fred.exe" could be processed as if + it were an ordinary archive; just specify the actual file name + with its actual name ending (if any), whatever that may be. + + member [,...] + + An optional list of archive members to be processed, separated + by commas. If no member list is specified, then all archive + members are processed. Unix-like ("globbing") wildcard patterns + may be used to match multiple members: + + * Matches a sequence of 0 or more characters. + ? Matches exactly 1 character. + [...] Matches any single character found inside the brackets. + Ranges are specified by a beginning character, a hyphen, + and an ending character. If an exclamation point ("!") + or a caret ("^") follows the left bracket, then the + range of characters within the brackets is complemented. + That is, anything except the characters inside the + brackets is considered a match. To specify a literal + left bracket, use the three-character sequence "[[]". +2 Qualifiers_Primary_mode + Qualifiers in this group specify the primary mode of operation of + UnZip. Only one of these primary mode qualifiers may be specified. +3 /COMMENT (-z) + Primary mode. Display only the archive comment. +3 /FRESHEN (-f) + Primary Mode. Freshen existing files. That is, extract only those + files that already exist on disk and that are newer than the disk + copies. By default UnZip queries before overwriting, but the + /EXISTING (-o) option may be used to suppress the queries. +3 /HELP (-h, -hh) + /HELP [=NORMAL] + /HELP=EXTENDED + + Primary Mode. Display brief (roughly 24 lines) usage instructions + (NORMAL, the default), or EXTENDED help (more complete usage + instructions). +3 /LICENSE (--license) + Primary Mode. Display the Info-ZIP license. +3 /LIST (-l) + Primary Mode. List archive members. By default, a brief format is + used, which includes the following items: member name, + uncompressed file size ("Length"), and modification date-time of + the member. A summary is included at the end of the report, + showing total size and count for all the members in the report. + Specifying a member list limits the report to those members. + + Adding /VERBOSE to an "UNZIP /LIST" command line adds the following + items to the report: compression method, compressed size ("Size"), + compression ratio, and 32-bit CRC. + + In contrast to some other programs, UnZip does not include the + 12-byte encryption header in the compressed size values for a + Traditionally encrypted member. Therefore, compressed size and + compression ratio figures are independent of the member's + encryption status and show the correct compression performance. + (The complete size of the encrypted compressed data stream for + archive members is reported by the more verbose ZipInfo reports. + See ZipInfo. + + If UnZip was built with OS2_EAS enabled, then the /LIST report also + includes the sizes of stored OS/2 extended attributes (EAs) and + OS/2 access control lists (ACLs). In addition, the archive comment + and individual member comments (if any) are displayed. + + If a file was archived from a single-case file system (for example, + the old MS-DOS FAT file system) and the /NAMES=DOWNCASE option was + given, the filename is converted to lowercase and is shown prefixed + with a caret (^). + + Note: If only /VERBOSE is specified with an archive name, then + UnZip acts as if "/LIST /VERBOSE" were specified, and a detailed + listing is generated. +3 /PIPE (-p) + Primary Mode. Extract files to stdout (pipe). Only the actual + file data for the members are sent to stdout (no file names, or + other information, as would be displayed with /SCREEN (-c), and the + files are always extracted in binary format, just as they are + stored (no conversions). See also /SCREEN. +3 /SCREEN (-c) + Primary Mode. Extract files to stdout/screen. This option is + similar to the /PIPE (-p) option except that the name of each file + is displayed as it is extracted, and the /TEXT (-a) option is + allowed, which can provide automatic ASCII-EBCDIC conversion, where + appropriate. See also /PIPE. +3 /TEST (-t) + Primary Mode. Test archive members. Testing means that each + archive member is extracted in memory (expanding and decrypting, as + needed), but not written to a file. The resulting CRC (cyclic + redundancy check, an enhanced checksum) of the extracted data is + then compared with the original file's stored CRC value, and an + error message is emitted if a CRC mismatch is detected. + + Adding /VERBOSE (-v) to /TEST adds some diagnostic information to + the report for archive members with LZMA or PPMd compression. +3 /TIMESTAMP (-T) + Primary Mode. Set the timestamp on the archive(s) to that of the + newest file in each one. This corresponds to Zip's /APPEND /LATEST + (-go) option, except that it can be used on wildcard archives (for + example, "unzip -T *.zip"), and is much faster. +3 /UPDATE (-u) + Primary mode. Update existing files and create new ones if needed. + This mode performs the same function as the Freshen (/FRESHEN, -f) + mode, extracting (with query) files that are newer than those with + the same name on disk, but it also extracts those files that do not + already exist on disk. +3 /VERBOSE (-v) + + Primary mode (when alone) or option. When used as a primary mode + (alone), and no archive is specified, an "UNZIP /VERBOSE" command + generates a report showing the program version, build options, and + relevant envrironment variables. + + When used with some other primary mode option, /VERBOSE can make + output more verbose (detailed). + + If no other primary mode is specified, and an archive is specified, + then UnZip acts as if "/LIST /VERBOSE" were specified, and a + detailed listing is generated. See Qualifiers_Primary_mode, + particularly /LIST. +2 Qualifiers_Ordinary + Qualifiers in this group modify the operation of UnZip. +3 /AUTO_DIRECTORY (-da) + /NOAUTO_DIRECTORY (default) + /AUTO_DIRECTORY[=REUSE] + + Specifies a destination directory for extracted files which is + derived from the base name of the archive. By default, files are + extracted (and subdirectories created) in the current default + directory. With /AUTO_DIRECTORY, UnZip automatically derives a + subdirectory name from the archive name, creates that subdirectory, + and extracts files into that subdirectory. + + For example, with /AUTO_DIRECTORY, extraction of "fred.zip" is done + into subdirectory "[.fred]" instead of into the current directory. + (On non-VMS systems, subdirectory "fred".) + + Using this option can help to avoid cluttering the current + directory with files extracted from an archive whose structure does + not include a top-level directory. + + If -da is specified as a default option in an environment variable, + it can be overridden by either a /NOAUTO_DIRECTORY qualifier or an + explicit /DIRECTORY=dest_dir qualifier. See also /DIRECTORY. +3 /BINARY (-b, -bb) + /BINARY[=keyword] + /NOBINARY (Default.) + + Selects the file record format used when extracting binary files. + + The optional keywords are: + + ALL Extract all files with fixed-length, 512-byte record + format. (-bb) + AUTO Extract binary files with fixed-length, 512-byte + record format. (Default value keyword: "/BINARY" is + equivalent to "/BINARY=AUTO".) (-b) + NONE Same as /NOBINARY. Extract binary files with + Stream_LF record format. (Default condition.) + + Zip (or a similar archiving program) identifies files as "binary" + or "text" when they are archived. (A short-format ZipInfo report + denotes a binary file with a "b", and a text file with a "t".) + + [VMS] On VMS, for archives with VMS attribute information (made + with "zip -V", "ZIP /VMS"), files are always created with their + original record formats. For archives without VMS attribute + information (not made with "zip -V", "ZIP /VMS"), files are + normally created with Stream_LF record format. With + /BINARY[=AUTO], binary files are created with fixed-length, + 512-byte record format. With /BINARY=ALL, all files are created + with fixed-length, 512-byte record format. When extracting to + standard output (/PIPE or /SCREEN in effect), the default + conversion of text record delimiters is disabled for binary files + (with /BINARY[=AUTO]), or for all files (with /BINARY=ALL). + + /BINARY may conflict or interact with /TEXT. A combination of + /BINARY[=AUTO] and /TEXT[=AUTO] is allowed. (See /TEXT.) +3 /BRIEF + Deprecated. Ignored. A no-op place-holder, originally intended as + an opposite of /FULL (also deprecated). See + Qualifiers_Primary_mode, particularly /LIST and /VERBOSE. +3 /CASE_INSENSITIVE (-C) + /CASE_INSENSITIVE + /NOCASE_INSENSITIVE (default) + + Deprecated. Use /MATCH=CASE. + + With /CASE_INSENSITIVE, match member names case-blindly. +3 /DIRECTORY (-d) + /DIRECTORY=dest_dir + + Specifies a destination directory for extracted files. By default, + files are extracted (and subdirectories created) in the current + default directory. With "/DIRECTORY=dest_dir", extraction is done + into the specified directory, instead. + + [VMS] On VMS, only a VMS-style device:[directory] specification is + permitted. +3 /DOT_VERSION (-Y) + [VMS] Treat archive member name endings of ".nnn" (where "nnn" is a + decimal number) as if they were VMS version numbers (";nnn"). (The + default is to treat them as file types.) For example: + + "a.b.3" -> "a.b;3" +3 /EXCLUDE (-x) + /EXCLUDE=(member [,...]) + + An optional list of archive members to be excluded from processing. + Because wildcard characters normally match "/" directory separators + (for exceptions see /MATCH=[NO]WILD_MATCH_SLASH (-W)), this option + may be used to exclude any files that are in subdirectories. For + example, + UNZIP foo *.[ch] /EXCLUDE = */* + would extract all C source files (*.c, *.h) in the main directory, + but none in any subdirectories. Without the /EXCLUDE option, all C + source files in all directories within the archive would be + extracted. + + Note that archive members are specified using the Unix-style names + which are used in ZIP archives, not VMS-style names. +3 /EXISTING (-n, -o) + /EXISTING[=keyword] + + Specifies the action when extracting files, and a file already + exists. + + The optional keywords are: + + NEW_VERSION Create a new version of an existing file. (-o) + OVERWRITE Overwrite an existing file. (-oo) + NOEXTRACT Do not extract. Leave an existing file intact. (-n) + + By default, UnZip queries the user before extracting any file that + already exists. + + [Non-VMS] On non-VMS systems, the user may choose to overwrite only + the current file, overwrite all files, skip extraction of the + current file, skip extraction of all existing files, or rename the + current file (choose a new name for the extracted file). + + [VMS] On VMS, the usual query choices are to create a new version + of an existing file, to skip extraction, or to rename the current + file. In the case where an archive member name includes a version + number, and /VERSION (-V, "retain VMS file version numbers") is in + effect, then an additional query choice is offered: to overwrite + the existing file. +3 /FULL (-v) + /FULL + /FULL=DIAGNOSTICS + + Deprecated. Adds detail to a /LIST report. See + Qualifiers_Primary_mode, particularly /LIST and /VERBOSE, and + Qualifiers_Ordinary, particularly /VERBOSE. +3 /JAR (--jar) + Treat archive(s) as Java JAR. Over-simplification in Java JAR + archives can cause UnZip to transform UTF-8 file names according to + inappropriate (MS-DOS) rules, yielding corrupt names on extracted + files (typically those with ASCII codes 128-255). Archives + containing a Java "CAFE" extra field should be detected + automatically, and handled correctly, but not all JAR archives + include that extra field. Specifying /JAR tells UnZip to expect + UTF-8 file names, regardless of whether the archive contains a + "CAFE" extra field. +3 /JUNK_DIRS (-j) + /NOJUNK_DIRS (Default.) + /JUNK_DIRS[=depth] + + Junk directories on extracted files. With /JUNK_DIRS, all + directory information is stripped from an archive member name, so + all files are extracted into the destination directory. (See also + /DIRECTORY.) + + If a depth ("=depth", where "depth" is a positive integer) is + specified, then that number of directory levels will be stripped + from an archive member name. For example, an archive member like + "a/b/c/d/ee.txt" would normally be extracted as "[.a.b.c.d]ee.txt". + With /JUNK_DIRS, it would be extracted as "ee.txt". With + /JUNK_DIRS=2, the first two directory levels would be stripped, so + it would be extracted as "[.c.d]ee.txt". +3 /LOWERCASE (-L) + /[NO]LOWERCASE + + Deprecated. Use /NAMES=[NO]DOWNCASE. + + /LOWERCASE: Convert to lowercase any filename originating on an + uppercase-only operating system or file system. + + /NOLOWERCASE: Do not convert to lowercase any filename originating + on an uppercase-only operating system or file system. + + See also /UPPERCASE, which is also deprecated. +3 /MATCH (-C, -W) + /MATCH=(keyword, ...) + + Specifies name-matching behavior for names in the member list and + the /EXCLUDE excluded-member list on the command line. + + The optional keywords and values are: + + CASE=BLIND Name matching is case-insensitive. (-C) + CASE=SENSITIVE Name matching is case-sensitive. (Default.) + + By default, case-sensitive matching is done. For example, + specifying "makefile" on the command line will match only + "makefile" in the archive, not "Makefile" or "MAKEFILE". On many + systems, the local file system is case-insensitive, so + case-insensitive name matching would be more natural. With + /MATCH=CASE=BLIND, "makefile" would match "makefile", "Makefile", + or "MAKEFILE". + + /MATCH does not affect the search for the ZIP archive file(s), nor + the matching of archive members to existing files on the extraction + path. So, on a case-sensitive file system, UnZip will never try to + overwrite a file "FOO" when extracting a member named "foo"! + + [WILD_STOP_AT_DIR] If the C macro WILD_STOP_AT_DIR is defined at + build time, then an additional keyword is allowed: + + NOWILD_MATCH_SLASH Wildcards stop at directory slash. (-W) + WILD_MATCH_SLASH Wildcards match directory slash. (Default.) + + By default, the wildcard characters "?" (single-character wildcard) + and "*" (multi-character wildcard) match any character in a member + path/name. /MATCH=NOWILD_MATCH_SLASH (-W) modifies the + pattern-matching behavior for archive members so that both "?" + (single-character wildcard) and "*" (multi-character wildcard) do + not match the directory separator character "/". (The + two-character sequence "**" acts as a multi-character wildcard that + includes the directory separator in its matched characters.) For + example, with /MATCH=NOWILD_MATCH_SLASH: + + "*.c" matches "foo.c" but not "mydir/foo.c" + "**.c" matches both "foo.c" and "mydir/foo.c" + "*/*.c" matches "bar/foo.c" but not "baz/bar/foo.c" + "??*/*" matches "ab/foo" and "abc/foo" + but not "a/foo" or "a/b/foo" + + This modified behavior is equivalent to the pattern matching style + used by the shells of some of \fIUnZip\fP's supported target OSs + (one example is Acorn RISC OS). This option may not be available + on systems where the Zip archive's internal directory separator + character "/" is allowed as regular character in native operating + system filenames. + + [non-VMS] (Currently, UnZip uses the same pattern matching rules + for both wildcard archive file name specifications and archive + member selection patterns on most system types. For systems + allowing "/" as regular filename character, the -W option would not + work as expected on a wildcard file name specification.) +3 /NAMES (-0 -2, -L, -s) + /NAMES + /NAMES=(keyword, ...) + + Selects name transformations during extraction. The keywords are: + + [NO]CHAR_SET CHAR_SET: Use CP850 character-set mapping on names + of archive members which originated on a FAT or + NTFS file system. (Default condition.) + NOCHAR_SET: Do not map these archive member names. + DOWNCASE Convert filenames from all-uppercase operating + systems to lowercase. (-L) + DOWNCASE=ALL Convert all filenames to lowercase. (-LL) + ODS2 Restrict names to ODS2 conventions, regardless + of the destination file system. (Invalid + character -> "_".) (-2) + [NO]SPACES SPACES: Permit space characters in (ODS5) names. + (Default condition.) + NOSPACES: Change spaces to underscores. (-s) + + The default is to use ODS5-compatible file names (including spaces) + when the destination file system is ODS5, and to convert the names + to ODS2-compatible names when the destination file system is ODS2. +3 /OVERWRITE (-n, -o) + /[NO]OVERWRITE + + Deprecated. Use /EXISTING. + + /OVERWRITE is equivalent to /EXISTING=NEW_VERSION. + /NOOVERWRITE is equivalent to /EXISTING=NOEXTRACT. +3 /PAGE (-M) + Pipe all output through an internal pager similar to the Unix + more(1) command. At the end of a screenful of output, UnZip pauses + with a "--More--" prompt; the next screenful may be viewed by + pressing the Enter (Return) key or the space bar. UnZip can be + terminated by pressing the "Q" key and, on some systems, the + Enter/Return key. Unlike Unix more(1), there is no + forward-searching or editing capability. Also, UnZip doesn't + notice if long lines wrap at the edge of the screen, effectively + resulting in the printing of two or more lines and the likelihood + that some text will scroll off the top of the screen before being + viewed. If the actual number of lines on the screen can not be + determined, 24 lines will be assumed. +3 /PASSWORD (-P) + /PASSWORD=password + + Use "password" to decrypt encrypted archive members (if any). THIS + IS INSECURE! Many multi-user operating systems provide ways for + any user to see the current command line of any other user. Even + on stand-alone systems, there is always the threat of + over-the-shoulder peeking. Storing the plaintext password as part + of a command line in an automated script can be even less secure, + Whenever possible, use the non-echoing, interactive prompt to enter + passwords. Where security is truly important, use a strong + encryption method, such as AES, instead of the relatively weak + encryption provided by Traditional ZIP encryption. Or, use an + external encryption program, such as GnuPG, before archiving the + file. (Note that Zip will probably not be able to do significant + compression on a file which has already been encrypted.) +3 /QUIET (-q, -qq) + /QUIET[=SUPER] + + Perform operations quietly. (/QUIET=SUPER: even more quietly). + + By default, UnZip prints the names of the files it's extracting or + testing, the extraction methods, any member or archive comments + that may be stored in the archive, and possibly a summary when + finished with each archive. The /QUIET[=SUPER] options suppress + the printing of some or all of these messages. +3 /RESTORE (-D, -k, -ka, -X) + /RESTORE[=(keyword, ...)] + + Selects restoration options for some meta-data. The optional + keywords are: + + ACL Restore file ACL settings. (-ka) + OWNER Restore file owner/UIC settings. (-X) + PROTECTION = LIMITED Restore file UIC-based (SOGW) protection + settings, respecting the current default + protection. (Default.) + PROTECTION = ORIGINAL Restore file UIC-based (SOGW) protection + settings, ignoring the current default + protection. (-k) + NOPROTECTION Do not restore file UIC-based (SOGW) protection settings. + The current default protection is used. (-k-) + NODATE Do not restore any timestamps. + DATE=ALL Restore timestamps for all extracted entries, + files and directories. + DATE=FILES Restore timestamps for extracted files. (Default.) + + By default, on VMS, UnZip restores the original date-time + attributes for files, but not for directories. This agrees with + the behavior of VMS BACKUP (and UnZip versions before 5.52 where + the capability to restore directory timestamps was added). + + For compatibility with UnZip versions before 6.0 (5.53), the + following deprecated short forms are still accepted: + + Deprecated form: Modern form: + /RESTORE /RESTORE=PROTECTION + /NORESTORE /RESTORE=NOPROTECTION +3 /TEXT (-a, -aa, -S) + + /TEXT[=(keyword, ...)] + /NOTEXT (Default.) + + The optional keywords are: + + ALL Extract all files with variable-length record format. + Adjust line endings to local standard, and convert + EBCDIC to ASCII, as needed. (-aa) + AUTO Extract text files with variable-length record format. + Adjust line endings to local standard, and convert + EBCDIC to ASCII, as needed. (Default value keyword: + "/TEXT" is equivalent to "/TEXT=AUTO".) (-a) + NONE Same as /NOTEXT. Extract text files with Stream_LF + record format without conversions. (Default + condition.) + STMLF Use Stream_LF record format for text files (instead of + variable-length record format) when ALL or AUTO is in + effect. Adjust line endings to local standard, and + convert EBCDIC to ASCII, as needed. (-S) + + Selects the file record format, character encoding, and line-ending + type used when extracting text files. + + Zip (or a similar archiving program) identifies files as "binary" + or "text" when they are archived. (A short-format ZipInfo report + denotes a binary file with a "b", and a text file with a "t".) + Zip's identification of text files may not be perfect, so UnZip + prints "[binary]" or "[text]" as a visual check for each file it + extracts with /TEXT. /TEXT=ALL forces all files to be extracted + (and converted) as text, regardless of the supposed file type. + + [VMS] On VMS, for archives with VMS attribute information (made + with "zip -V", "ZIP /VMS"), files are always created with their + original record formats. For archives without VMS attribute + information (not made with "zip -V", "ZIP /VMS"), all files are + normally created with Stream_LF record format. With /TEXT[=AUTO], + text files are normally created with variable-length record format, + but adding STMLF gives them Stream_LF record format. Additionally, + line endings (CR, LF, CR+LF, ..) are adjusted to the local + standard, and EBCDIC is converted to ASCII. With /TEXT=ALL, all + files are treated as text files, and processed as described above. + + See also /BINARY. +3 /TRAVERSE_DIRS (-:) + /[NO]TRAVERSE_DIRS (Default: /NOTRAVERSE_DIRS.) + + Allows UnZip to extract archive members into locations outside of + the current extraction destination directory (and its + subdirectories). + + For security reasons, UnZip normally removes "parent directory" + path components ("../") from the path names of archive members as + they are extracted. This safety feature (new for version 5.50) + prevents UnZip from accidentally writing files to directories + outside the current destination directory tree. /TRAVERSE_DIRS + sets UnZip back to its previous, more liberal behavior, allowing + exact extraction of archives that use "../" path components to + create multiple directory trees at or above the level of the + destination directory. + + Use this option with extreme caution. +3 /UPPERCASE (-L) + /[NO]UPPERCASE + + Deprecated. Use /NAMES=[NO]DOWNCASE. + + /UPPERCASE: Do not convert to lowercase any filename originating + on an uppercase-only operating system or file system. + + /NOUPPERCASE: Convert to lowercase any filename originating on an + uppercase-only operating system or file system. + + See also /LOWERCASE, which is also deprecated. +3 /VERBOSE (-v) + /VERBOSE[=(keyword, ...)] + + The optional keywords are: + + NORMAL Make a report more detailed/verbose. (Default value + keyword: "/VERBOSE" is equivalent to + "/VERBOSE=NORMAL".) (-v) + MORE Enable special developer I/O diagnostics. See below. + (-vv) + COMMAND Enable special developer CLI diagnostics. See below. + + MORE and NORMAL may not be specified together. (MORE implies + NORMAL.) + + When used with some primary mode options, /VERBOSE can make output + more detailed/verbose. See also Qualifiers_Primary_mode, + particularly /LIST. + + If no other primary mode is specified, and an archive is specified, + then UnZip acts as if "/LIST /VERBOSE" were specified, and a + detailed listing is generated. See Qualifiers_Primary_mode, + particularly /LIST and /VERBOSE. + + /VERBOSE=MORE ("-vv") enables some VMS-specific I/O diagnostic + messages, and is intended for use in program development, not in + normal use. + + /VERBOSE=COMMAND causes UnZip to show the translated Unix-style + command-line argument vector before processing it, and is intended + for use in program development, not in normal use. + /VERBOSE=COMMAND has no Unix-style equivalent. +3 /VERSION (-V) + [Non-CMS-MVS] Retain VMS file version numbers. VMS files can be + stored with a version number, in the format "file.type;##", where + "##" is a decimal number. By default the ";##" version numbers are + stripped, but this option allows them to be retained. (On file + systems that limit filenames to particularly short lengths, the + version numbers may be truncated or stripped regardless of this + option.) + + [Non-VMS] Note that before UnZip version 6.10, on a non-VMS system, + a file with a name like "fred;123" would, by default, be extracted + as "fred", even if the file did not originate on a VMS system (so + that ";123" was probably not really a VMS version number). + Beginning with UnZip version 6.10, the default behavior is to strip + VMS version numbers only from files which were archived on a VMS + system. To restore the old behavior, and always strip apparent VMS + version numbers, explicitly negate the option: "-V-". +3 /ZIPINFO (-Z) + ZipInfo mode. With /ZIPINFO, the program runs in ZipInfo mode, + which is used to display information about an archive and its + members. Remaining options are interpreted as ZipInfo options. If + used, /ZIPINFO must be the first qualifier on the command line. + See ZipInfo_mode. +2 Environment_Options + UnZip's default behavior may be modified by placing Unix-style + command-line options in an environment variable. (The VMS CLI + translator acts only on the command line itself, not on the + environment variables.) This can be done with any option, but it is + probably most useful options like -a (/TEXT, auto-convert text + files), -L (/NAMES, downcase file names from systems with all + uppercase file names), -C (/MATCH=CASE=BLIND, use case-insensitive + name matching), -q (/QUIET, quiet), -o (/EXISTING, always + overwrite), or -n (/EXISTING, never overwrite). + + For UnZip, the environment variable name on VMS is UNZIP_OPTS + (non-VMS: UNZIP). The name on VMS is different to avoid conflict + with a foreign-command DCL symbol, UNZIP. For compatibility with + Zip, if UNZIP_OPTS is not defined, then UnZip will use UNZIPOPT the + same way. + + For ZipInfo ("UNZIP /ZIPINFO"), the environment variable name on + VMS is ZIPINFO_OPTS (non-VMS: ZIPINFO). For compatibility with + Zip, if ZIPINFO_OPTS is not defined, then ZipInfo will use + ZIPINFOOPT the same way. + For example, to make UnZip act as quietly as possible, only + reporting errors, one could use commands like the following (with + quotation to preserve lower case in DCL): + + define UNZIP_OPTS "-q -q" ! Logical name, or + UNZIP_OPTS = "-q -q" ! DCL symbol. (Either works.) + + Environment options are treated the same as any other Unix-style + command-line options, except that they are effectively the first + options on the command line. Generally, the VMS CLI translator + will override an environment option if an explicit corresponding + VMS-style qualifier is specified. + + The examples show short (one-character) options, but long ("--") + options are also allowed. +2 Encryption_Decryption + Zip and UnZip have long supported a relatively weak encryption + method, which we call Traditional ZIP encryption. The source code + for Traditional encryption is included in the source kits, and + support for Traditional encryption is enabled by default. + (Build-time C macro: CRYPT_TRAD.) + + Beginning with UnZip version 6.10 and Zip version 3.1, these + programs also offer a stronger, Advanced Encryption Standard (AES) + encryption method, which we call AES WinZip/Gladman (AES_WG) + encryption. (The encryption code was supplied by Brian Gladman, + and the archive format is intended to be compatible with that used + by the WinZip program. WinZip is a registered trademark of WinZip + International LLC.) The source code for AES_WG encryption is + distributed in a separate kit (for export control reasons), and + support for AES_WG encryption must be enabled explicitly at build + time. (Build-time C macro: CRYPT_AES_WG.) See the INSTALL file in + the source kit for details on how to enable AES_WG encryption (or + how to disable Traditional encryption). + + For details on the WinZip AES scheme, see: + http://www.winzip.com/aes_info.htm + + For information on the separate AES_WG source kit, see: + ftp://ftp.info-zip.org/pub/infozip/crypt/ + ftp://ftp.info-zip.org/pub/infozip/crypt/README_AES_WG.txt + + Normally, encryption passwords are supplied by the user + interactively when requested by the program. See /PASSWORD for a + (less secure) method of specifying a password on the command line. + + With Traditional encryption, when decrypting, a password will be + checked against header data, and used if it appears to be correct. + The correct password will always check out against the header data, + but there is a 1-in-256 chance that an incorrect password will as + well. (This is a security feature of the PKWARE archive format; it + helps prevent brute-force attacks that might otherwise gain a large + speed advantage by testing only the header.) In the case that an + incorrect password is given but it passes the header test anyway, + either an incorrect CRC will be generated for the extracted data or + else UnZip will fail during the extraction because the "decrypted" + bytes do not constitute a valid compressed data stream. + + If the first password fails the header check on some file, UnZip + will prompt for another password, and so on until all files are + extracted. If a password is not known, entering a null password + (that is, just a carriage return or "Enter") is taken as a signal + to skip all further prompting. Only unencrypted files in the + archive(s) will thereafter be extracted. (The situation is + actually a little more complicated. Some old versions of Zip and + ZipCloak allowed null passwords, so UnZip checks each encrypted + file to see if the null password works. This may result in "false + positives" and extraction errors, as noted above.) + + Archives encrypted with 8-bit-character passwords (for example, + passwords with accented European characters) may not be portable + across systems or to other archivers. This problem stems from the + use of multiple encoding methods for such characters, including + Latin-1 (ISO 8859-1) and OEM code page 850. DOS PKZIP 2.04g uses + the OEM code page; Windows PKZIP 2.50 uses Latin-1 (and is + therefore incompatible with DOS PKZIP; Info-ZIP uses the OEM code + page on DOS, OS/2 and Win3.x ports but ISO coding (Latin-1 etc.) + everywhere else; and Nico Mak's WinZip 6.x does not allow + 8-bit-character passwords at all. UnZip 5.3 (or newer) attempts to + use the default character set first (e.g., Latin-1), followed by + the alternate one (e.g., OEM code page) to test passwords. On + EBCDIC systems, if both of these fail, EBCDIC encoding will be + tested as a last resort. (EBCDIC is not tested on non-EBCDIC + systems, because there are no known archivers that encrypt using + EBCDIC encoding.) ISO character encodings other than Latin-1 are + not supported. The new addition of (partial) Unicode (UTF-8) + support in UnZip 6.0 has not yet been adapted to the encryption + password handling in UnZip. On systems that use UTF-8 as native + character encoding, UnZip simply tries decryption with the native + UTF-8 encoded password; the built-in attempts to check the password + in translated encoding have not yet been adapted for UTF-8 support + and will consequently fail. +2 Examples + To use UnZip to extract all members of the archive letters.zip into + the current directory and subdirectories below it, creating any + subdirectories as necessary: + + unzip letters + + To extract all members of letters.zip into the current directory + only: + + unzip /junk_dirs letters + + To test letters.zip, printing only a summary message indicating + whether the archive is OK or not: + + unzip /test /quiet letters + + To test all ".zip" archives in the current directory, printing only + the summaries: + + unzip /test /quiet *.zip + + (On a Unix system, the wildcard member name would typically need to + be quoted to keep a a Unix shell from expanding ("globbing") it. + This is not necessary on VMS. However, a name with a slash ("/") + character, such as "*/zip*.*", must be quoted. Otherwise, DCL may + interpret the slash as introducing a qualifier, causing unexpected + behavior or an "%CLI-W-IVQUAL, unrecognized qualifier" error.) + + The following command extracts to standard output all members of + letters.zip whose names end in ".tex", auto-converting to the local + end-of-line convention, in Stream_LF record format, and piping the + output into TYPE /PAGE: + + pipe unzip /screen /text=(auto, stmlf) letters *.tex | \ + type /page sys$input + + To extract from source.zip all Fortran and C source files (*.f, + *.c, *.h) and Makefile into the SYS$SCRATCH directory: + + unzip source.zip *.[fch] Makefile /directory = sys$scratch + + To extract all FORTRAN and C source files, regardless of case (for + example, both *.c and *.C, and any makefile, Makefile, MAKEFILE or + similar): + + unzip -C source.zip *.[fch] makefile /directory = sys$scratch + + The following command extracts only newer versions of the files + already in the current directory, without querying. (Note: Be + careful of extracting in one timezone an archive created in + another. ZIP archives created by Zip versions before 2.1 contain + no timezone information, and a "newer" file from an eastern + timezone may, in fact, be older): + + unzip /freshen /existing=new_version sources + + To extract newer versions of the files already in the current + directory and to create any files not already there (same caveat as + previous example): + + unzip /update /existing=new_version sources + + To display a configuration report showing the program version, the + OS and compiler used to build it, a list of optional features + enabled at build time, and the values of all the relevant + environment variables: + + unzip /verbose +2 Exit_Status + UnZip's exit status approximates the exit codes defined by PKWARE. + On VMS, UnZip's UNIX-style exit values are translated into + VMS-style status codes with facility code 1954 = %x7A2, and with + the inhibit-message (%x10000000) and facility-specific (%x00008000) + bits set: + + %x17A28001 normal exit + %x17A28000 + 16*UnZip_error_code warnings + %x17A28002 + 16*UnZip_error_code normal errors + %x17A28004 + 16*UnZip_error_code fatal errors + + Note that multiplying the UNIX-style UnZip error code by 16 places + it conveniently in the hexadecimal representation of the VMS exit + code, "__" in %x17A28__s, where "s" is the severity code. For + example, a missing archive might cause UnZip error code 9, which + would be transformed into the VMS exit status %X17A28092. + + The UnZip VMS exit codes include severity values which approximate + those defined by PKWARE, as shown in the following table: + + VMS UnZip + severity err code Error description + ----------+----------+---------------------------------------------- + Success 0 Normal. No errors or warnings detected. + Warning 1 One or more warnings were encountered, but + processing completed successfully. This + includes archives where one or more (but not + all) files were skipped because of an + unsupported compression or encryption method, + or a bad encryption password. + Error 2 Error in the archive format. Processing may + or may not have completed successfully. + Fatal 3 Severe error in the archive format. + Processing probably failed immediately. + Fatal 4 Memory allocation failed in program + initialization. + Fatal 5 Memory allocation or terminal I/O failed in + password processing. + Fatal 6 Memory allocation failed while decompressing + to disk. + Fatal 7 Memory allocation failed while decompressing + in memory. + Fatal 8 Memory allocation failed. (Currently not + used.) + Error 9 Specified archive files were not found. + Error 10 Invalid command-line options or parameters. + Error 11 No matching files were found. + Fatal 50 Disk (file system) filled during extraction. + Fatal 51 Unexpected end-of-file while reading the + archive. + Error 80 User interrupt (Ctrl/C). + Error 81 No files were processed, because of + unsupported compression or encryption + methods. + Error 82 No files were processed, because of bad + encryption password(s). + Fatal 83 Large-file archive could not be processed by + this small-file program. +2 Bugs + Multi-part archives are not yet supported, except in conjunction + with Zip. (All parts must be concatenated together in order, and + then "zip -F" (for Zip 2.x) or "zip -FF" (for Zip 3.x) must be + performed on the concatenated archive in order to "fix" it. Also, + zip 3.0 and later can combine multi-part (split) archives into a + combined single-file archive using "zip -s- inarchive -O + outarchive". See the zip manual page for more information.) This + may be corrected in the next major release. + + Archives read from standard input are not yet supported, except + with UnZip (and then only the first member of the archive can be + extracted). + + Archives encrypted with 8-bit-character passwords (such as + passwords with accented European characters) may not be portable + across systems and/or other archivers. See also + Encryption_Decryption. + + UnZip's -M ("--more") option tries to take into account automatic + wrapping of long lines. However, the code may fail to detect the + correct wrapping locations. First, TAB characters (and similar + control sequences) are not taken into account, they are handled as + ordinary printable characters. Second, depending on the actual + system type, UnZip may not detect the true terminal/emulator + geometry, but instead may rely on "commonly used" default + dimensions. The correct handling of tabs would require the + implementation of a query for the actual tab setup on the output + terminal/emulator. + + [Unix] Unix special files such as FIFO buffers (named pipes), block + devices and character devices are not restored even if they are + somehow represented in the archive, nor are hard-linked files + relinked. Basically, the only file types restored by UnZip are + regular files, directories, and symbolic (soft) links. + + [OS/2] Extended attributes for existing directories are only + updated if the -o ("--overwrite") option is given. This is a + limitation of the operating system; because directories only have a + creation time associated with them, UnZip has no way to determine + whether the stored attributes are newer or older than those on + disk. In practice this may mean a two-pass approach is required: + first unpack the archive normally (with or without + freshening/updating existing files), then overwrite just the + directory entries (for example, "unzip -o foo */"). +2 URL + The Info-ZIP main Web page is: + http://www.info-zip.org/ + + FTP access is available, too: + ftp://ftp.info-zip.org/pub/infozip/ +2 ZipInfo_mode + When /ZIPINFO is specified, the program runs in ZipInfo mode. + Remaining options are interpreted as ZipInfo options. If used, + /ZIPINFO must be the first qualifier on the command line. + + ZipInfo reports detailed information about a ZIP archive and its + members. This information may include file access permissions, + compression method, encryption method, version and operating system + (or file system) of the archive-creating program, and so on. The + default behavior (with no options) is to show a single-line entry + for each member in the archive, with a header and a trailer + providing summary information for the entire archive. The format + is a cross between Unix "ls -l" and "UNZIP /LIST /VERBOSE" output. + See Detailed_Description. ZipInfo is the same program as UnZip. + (On Unix, "zipinfo" may be a link to "unzip". On VMS, "ZIPINFO" is + normally a DCL symbol defined as "''UNZIP' /ZIPINFO".) However, + ZipInfo support may have been disabled when UnZip was built. + + Format: + + ZIPINFO [/zipinfo_options] [file[.zip]] [member [,...]] + + UNZIP /ZIPINFO [/zipinfo_options] [file[.zip]] [member [,...]] +3 Command_Parameters + file[.zip] + + File path/name of a ZIP archive. A wildcard name may be used to + specify multiple ZIP archives to be processed in one command. + On VMS systems, any of the standard wildcards for a + directory/file specification may be used: "...", "*", or "%" + (or, since VMS V7.2, "?"). The default archive file + specification is ".ZIP". + + Note that a ".zip" or ".ZIP" file type on an archive is merely a + convention, not a requirement. For example, a self-extracting + ZIP archive named "fred" or "fred.exe" could be processed as if + it were an ordinary archive; just specify the actual file name + with its actual name ending (if any), whatever that may be. + + member [,...] + + An optional list of archive members to be processed, separated + by commas. If no member list is specified, then all archive + members are processed. Unix-like ("globbing") wildcard patterns + may be used to match multiple members: + + * Matches a sequence of 0 or more characters. + ? Matches exactly 1 character. + [...] Matches any single character found inside the + brackets. Ranges are specified by a beginning + character, a hyphen, and an ending character. If an + exclamation point ("!") or a caret ("^") follows the + left bracket, then the range of characters within + the brackets is complemented. That is, anything + except the characters inside the brackets is + considered a match. To specify a literal left + bracket, use the three-character sequence "[[]". +3 Qualifiers_Primary_Format + Qualifiers in this group specify the primary report format of + ZipInfo. Only one of these primary format qualifiers may be + specified. +4 /LONG (-l) + Primary Format. Show member info in long Unix "ls -l" format. + Like the /MEDIUM format, except that the compressed size (in bytes) + is printed instead of the compression ratio. +4 /ONE_LINE (-2) + Primary Format. Show member names only, one per line. Other + report elements are allowed, if requested explicitly using /HEADER, + /TOTALS, and/or /COMMENT. +4 /MEDIUM (-m) + Primary Format. Show member info in medium-length Unix "ls -l" + format. Like the /SHORT format, except that the compression + factor, expressed as a percentage, is also included. +4 /SHORT (-s) + Primary Format. Show member info in short Unix "ls -l" format. + This is the default behavior, unless /HEADER or /TOTALS is + specified. +4 /VERBOSE (-v) + Primary Format. The ZipInfo /VERBOSE report is very detailed, and + mostly self-explanatory, but it does assume some familiarity with + the ZIP archive format. It also includes the archive comment, if + any. Extra fields in the central directory are broken down into + subfields, with brief interpretations of recognized subfields (or + abbreviated dumps of unrecognized subfields). +3 Qualifiers_Ordinary + Qualifiers in this group modify the operation or report format of + ZipInfo. +4 /COMMENT (-z) + Include the archive comments (if any) in the report. +4 /DECIMAL_TIME (-T) + Show the file date-times in a sortable, all-numeric, + "YYYYMMDD.hhmmss" format. The default date format is an + alpha-numeric "YY-Mmm-DD hh:mm". For example ("/SHORT", "/SHORT + /DECIMAL_TIME"): + + -rw-a-- 3.1 fat 211916 tx defX 10-Jun-18 00:27 zip31c/zip.c + -rw-a-- 3.1 fat 211916 tx defX 20100618.002703 zip31c/zip.c +4 /EXCLUDE (-x) + /EXCLUDE=(member [,...]) + An optional list of archive members to be excluded from processing. + Because wildcard characters normally match "/" directory separators + (for exceptions see /WILD_SPAN (-W)), this option may be used to + exclude any files that are in subdirectories. For example, + UNZIP foo *.[ch] /EXCLUDE = */* + would extract all C source files (*.c, *.h) in the main directory, + but none in any subdirectories. Without the /EXCLUDE option, all C + source files in all directories within the archive would be + extracted. + + Note that archive members are specified using the Unix-style names + which are used in ZIP archives, not VMS-style names. +4 /HEADER (-h) + Include a header in the report, showing the archive name, the + archive size (in bytes), and the number of members in the archive. + + For the Unix-format reports (options /LONG, /MEDIUM, /SHORT), the + header is included by default, if no archive members are specified. + If /HEADER is specified alone, that is, without one of the + Unix-format options, and without a member list, then only the + header lines will be put out. +3 /MATCH (-C, -W) + /MATCH=(keyword, ...) + + Specifies name-matching behavior for names in the member list and + the /EXCLUDE excluded-member list on the command line. + + The optional keywords and values are: + + CASE=BLIND Name matching is case-insensitive. (-C) + CASE=SENSITIVE Name matching is case-sensitive. (Default.) + + By default, case-sensitive matching is done. For example, + specifying "makefile" on the command line will match only + "makefile" in the archive, not "Makefile" or "MAKEFILE". On many + systems, the local file system is case-insensitive, so + case-insensitive name matching would be more natural. With + /MATCH=CASE=BLIND, "makefile" would match "makefile", "Makefile", + or "MAKEFILE". + + /MATCH does not affect the search for the ZIP archive file(s), nor + the matching of archive members to existing files on the extraction + path. So, on a case-sensitive file system, UnZip will never try to + overwrite a file "FOO" when extracting a member named "foo"! + + [WILD_STOP_AT_DIR] If the C macro WILD_STOP_AT_DIR is defined at + build time, then an additional keyword is allowed: + + NOWILD_MATCH_SLASH Wildcards stop at directory slash. (-W) + WILD_MATCH_SLASH Wildcards match directory slash. (Default.) + + By default, the wildcard characters "?" (single-character wildcard) + and "*" (multi-character wildcard) match any character in a member + path/name. /MATCH=NOWILD_MATCH_SLASH (-W) modifies the + pattern-matching behavior for archive members so that both "?" + (single-character wildcard) and "*" (multi-character wildcard) do + not match the directory separator character "/". (The + two-character sequence "**" acts as a multi-character wildcard that + includes the directory separator in its matched characters.) For + example, with /MATCH=NOWILD_MATCH_SLASH: + "*.c" matches "foo.c" but not "mydir/foo.c" + "**.c" matches both "foo.c" and "mydir/foo.c" + "*/*.c" matches "bar/foo.c" but not "baz/bar/foo.c" + "??*/*" matches "ab/foo" and "abc/foo" + but not "a/foo" or "a/b/foo" + + This modified behavior is equivalent to the pattern matching style + used by the shells of some of \fIUnZip\fP's supported target OSs + (one example is Acorn RISC OS). This option may not be available + on systems where the Zip archive's internal directory separator + character "/" is allowed as regular character in native operating + system filenames. + + [non-VMS] (Currently, UnZip uses the same pattern matching rules + for both wildcard archive file name specifications and archive + member selection patterns on most system types. For systems + allowing "/" as regular filename character, the -W option would not + work as expected on a wildcard file name specification.) +4 /MEMBER_COUNTS (default) (-mc) + /NOMEMBER_COUNTS + Control inclusion of separate member counts for directories, files, + and (if symlinks are supported) links, after the totals summary at + the end of the report. By default, they are included. Use + /NOMEMBER_COUNTS" to suppress them. See also /TOTALS. +4 /PAGE (-M) + Pipe all output through an internal pager similar to the Unix + more(1) command. At the end of a screenful of output, UnZip pauses + with a "--More--" prompt; the next screenful may be viewed by + pressing the Enter (Return) key or the space bar. UnZip can be + terminated by pressing the "Q" key and, on some systems, the + Enter/Return key. Unlike Unix more(1), there is no + forward-searching or editing capability. Also, UnZip doesn't + notice if long lines wrap at the edge of the screen, effectively + resulting in the printing of two or more lines and the likelihood + that some text will scroll off the top of the screen before being + viewed. If the actual number of lines on the screen can not be + determined, 24 lines will be assumed. +4 /TOTALS (-t) + Include a totals summary at the end of the report, showing the + number of members in the report, the sum of their uncompressed + sizes, the sum of their compressed sizes, and the compression + factor as a percentage. + + For the Unix-format reports (/LONG, /MEDIUM, /SHORT), the totals + summary is included by default, if no archive members are + specified. If /TOTALS is specified alone, that is, without one of + the Unix-format options, and without a member list, then only the + totals summary trailer lines will be put out. + + The total "bytes compressed" reported includes only the actual + data, not the ZIP archive meta-data, so the size of the archive + will always be greater than this value. + + See also /MEMBER_COUNTS. +3 Detailed_Description + ZipInfo has three basic report formats, providing different degrees + of detail in the information about the members of an archive: a + simple list of names (/ONE_LINE (-1, -2)), a Unix ls-style listing + (/LONG (-l), /MEDIUM (-m), /SHORT (-s)), and a very detailed + analysis (/VERBOSE (-v)). Some of the information, such as file + sizes, is easy to interpret. Some of the information involves + fairly obscure details of ZIP archive structure. ZIP archive + structure is documented in the PKWARE Inc. APPNOTE.TXT: + http://www.pkware.com/documents/casestudies/APPNOTE.TXT + + The table below shows some typical /LONG report entries: + + Perm/Prot Zver Ofs UncSize At CmpSize Cmth ModDate Mtime Name + ----------+----+---+-------+--+-------+----+---------------+---------- + -rw-a-- 3.1 fat 211916 tx 53467 defX 10-Jun-18 00:27 zip3/zip.c + -rwxr-x--- 3.1 unx 709 Tx 311 aesw 11-Aug-21 22:20 endian.c + RWED,RE, 3.1 vms 6656 bx 2295 defN 07-Aug-15 14:12 it/T.EXE;8 + + Field 1 (Perm/Prot) shows the file permission/protection + attributes, formatted according to the original operating system or + file system where the archive was created. + + Field 2 (Zver) shows the (approximate) version of the Zip program + which created the archive. + + Field 3 (Ofs) shows the original operating system where the archive + was created, or the file system on which the member file was + stored. + + Field 4 (UncSize) shows the original, uncompressed file size. + + Field 5 (At) shows some archive member attributes, as detailed in + the tables below. The first character indicates whether a file was + binary or text, and whether it was encrypted. The second character + indicates the presence of a data descriptor and/or an extra field + in the member data. + + | File Type Extra Field | + First char | binary text yes no | Second char + --------------+-------+----- ------+-----+-------------------- + Encrypted no | b t x - | no Data Descriptor + yes | B T X l | yes + + A Data Descriptor holds CRC and size data at an alternate place in + the archive (after processed member data instead of before), and is + normally used when the archiving program can't seek in the output + archive data/file. An Extra Field can hold a wide variety of data, + including 64-bit file sizes, many kinds of OS-specific attribute + data, UTC times, and so on. + + Field 6 (CmpSize) shows the compressed file size. With /MEDIUM, + this field shows the compression fraction as a percentage. With + /SHORT (the default), this field is omitted. This compressed size + value (unlike the one in an "UNZIP /LIST" report) includes all the + overhead resulting from Traditional encryption. + + Field 7 (Cmth) shows the compression method used. Note that AES_WG + encryption is treated as a compression method here. Not all of the + methods shown in the table below are supported. (Some are + obsolete.) + + Num Abbr Name, description + ----+----+------------------------------------------------------------ + 0 stor Store (no compression) + 1 shrk Shrink + 2 re:1 Reduce (factor 1) + 3 re:2 Reduce (factor 2) + 4 re:3 Reduce (factor 3) + 5 re:4 Reduce (factor 4) + 6 i#:# Implode (dictonary_size:Shannon-Fano_trees) + 7 tokn Tokenize + 8 def# Deflate (N: normal, X: maximum, F: fast, S: super-fast) + 9 d64# Deflate64 (N: normal, X: maximum, F: fast, S: super-fast) + 10 dcli PKWARE Data Compression Library Imploding - IBM TERSE (old) + 12 bzp2 bzip2 + 14 lzma LZMA + 18 ters IBM TERSE (new) + 19 lz77 IBM LZ77 z Architecture (PFS) + 96 jpeg JPEG + 97 wavp WavPack + 98 ppmd PPMd version I, Rev 1 + 99 aesw AES_WG encryption + + Fields 8 and 9 (ModDate, Mtime) show the file modification + date-time (MS-DOS format, local time). + + Field 10 (Name) shows the file path/name. +3 Environment_Options + ZipInfo's default behavior may be modified by placing Unix-style + command-line options in an environment variable. (The VMS CLI + translator acts only on the command line itself, not on the + environment variables.) This can be done with any option, but it is + probably most useful options like -T (/DECIMAL_TIME, decimal time + format) or one of the non-default Unix format options: -l (/LONG), + -m (/MEDIUM). + + For ZipInfo ("UNZIP /ZIPINFO", ZIPINFO), the environment variable + name on VMS is ZIPINFO_OPTS (non-VMS: ZIPINFO). For compatibility + with Zip, if ZIPINFO (ZIPINFO_OPTS on VMS) is not defined, then + ZipInfo will use ZIPINFOOPT the same way. + + For example, to make the default format the long Unix format + instead of the short Unix format, one could use commands like the + following (with quotation to preserve lower case in DCL): + + define ZIPINFO_OPTS "-l" ! Logical name, or + ZIPINFO_OPTS = "-l" ! DCL symbol. (Either works.) + + Environment options are treated the same as any other Unix-style + command-line options, except that they are effectively the first + options on the command line. Generally, the VMS CLI translator + will override an environment option if an explicit corresponding + VMS-style qualifier is specified. + + The examples show short (one-character) options, but long ("--") + options are also allowed. +3 Examples + To get a basic, short-format listing of the complete contents of a + ZIP archive zip31c.zip, with both header and totals lines, use only + the archive name as an argument to zipinfo: + + zipinfo zip31c.zip + zipinfo zip31c + + To produce a basic, long-format listing (not verbose), including + header and totals lines, use /LONG: + + zipinfo /long zip31c.zip + + To list the complete contents of the archive without header and + totals lines, either negate the /HEADER and /TOTALS qualifiers or + else specify the contents explicitly: + + zipinfo /noheader /nototals zip31c.zip + zipinfo zip31c.zip * + + (On a Unix system, the wildcard member name would typically need to + be quoted to keep a a Unix shell from expanding ("globbing") it. + This is not necessary on VMS. However, a name with a slash ("/") + character, such as "*/zip*.*", must be quoted. Otherwise, DCL may + interpret the slash as introducing a qualifier, causing unexpected + behavior or an "%CLI-W-IVQUAL, unrecognized qualifier" error.) + + To list information on a single archive member, in medium format, + specify the member name explicitly: + + zipinfo /medium unzip60.zip */unshrink.c + + On a VMS system, one could use /DECIMAL_TIME along with an external + sorting program to get a listing of files in the archive in + date-time order: + + pipe zipinfo /decimal_time /long /noheader /nototals zip31c.zip | - + sort sys$input sys$output /key = (position:47, size:15, descend) + + For a /LONG (-l) format report, the date-time field should begin at + position 47; for /MEDIUM (-m), 42; for /SHORT (-s), 38. HELP SORT + [/KEY] should lead to an explanation of the various SORT options. + (Unlike Unix, VMS does not include a useful "head" or "tail" + program.) + + On a Unix system, one could use the -T option along with an + external sorting program (and another filter like "head" or "tail") + to get a listing of the least or most recently modified files in + the archive: + + zipinfo -l -T -h- -t- zip31c.zip | sort -k 8 | head -12 + zipinfo -l -T -h- -t- zip31c.zip | sort -r -k 8 | head -12 + + The "sort" option "-k 8" tells it to sort on field 8, which is the + date-time field in a long- or medium-format (-l, -m) ZipInfo + report. (Use "-k 7" for the short (-s) format.) The -r option + reverses the default smallest-to-largest sort order. +3 Bugs + As with UnZip, ZipInfo's /PAGE (-M) option is overly simplistic in + its handling of screen output. As noted above, it fails to detect + the wrapping of long lines and may thereby cause lines at the top + of the screen to be scrolled off before being read. ZipInfo should + detect and treat each occurrence of line-wrap as one additional + line printed. This requires knowledge of the screen's width as + well as its height. In addition, ZipInfo should detect the true + screen geometry on all systems. + + The interactions among the various listing format, header, and + trailer options (/HEADER, /LONG, /MEDIUM, /SHORT, /TOTALS) are + unnecessarily complex and should be simplified, despite the + potential disruption to current users. +3 URL + The Info-ZIP main Web page is: + http://www.info-zip.org/ + + FTP access is available, too: + ftp://ftp.info-zip.org/pub/infozip/ diff --git a/extract.c b/extract.c index d15237a..f704350 100644 --- a/extract.c +++ b/extract.c @@ -3827,6 +3827,7 @@ static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata) ulg eb_ucsize; uch *eb_ucptr; int r; + ush eb_compr_method; if (compr_offset < 4) /* field is not compressed: */ return PK_OK; /* do nothing and signal OK */ @@ -3836,6 +3837,14 @@ static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata) eb_size <= (long)(compr_offset + EB_CMPRHEADLEN))) return IZ_EF_TRUNC; /* no compressed data! */ + /* 2014-11-03 Michal Zalewski, SMS. + * For STORE method, compressed and uncompressed sizes must agree. + * http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=450 + */ + eb_compr_method = makeword( eb + (EB_HEADSIZE + compr_offset)); + if ((eb_compr_method == STORED) && (eb_size - compr_offset != eb_ucsize)) + return PK_ERR; + if ( #ifdef INT_16BIT (((ulg)(extent)eb_ucsize) != eb_ucsize) || @@ -4510,7 +4519,7 @@ char *fnfilter(raw, space, size) # endif /* ?HAVE_WORKING_ISPRINT */ } else { # ifdef _MBCS - unsigned i = CLEN(r); + extent i = CLEN(r); if (se != NULL && (s > (space + (size-i-2)))) { have_overflow = TRUE; break; @@ -4710,7 +4719,7 @@ __GDEF #endif G.inptr = (uch *)bstrm.next_in; - G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */ + G.incnt = (int)((G.inbuf + INBUFSIZ) - G.inptr); /* Reset for others. */ uzbunzip_cleanup_exit: err = BZ2_bzDecompressEnd(&bstrm); diff --git a/fileio.c b/fileio.c index 3884ee2..554a727 100644 --- a/fileio.c +++ b/fileio.c @@ -102,14 +102,14 @@ */ #ifdef WINDLL # define WriteError(buf,len,strm) \ - (win_fprintf(pG, strm, (extent)len, (char far *)buf) != (int)(len)) + (win_fprintf(pG, (strm), (int)(len), (char far *)(buf)) != (len)) #else /* !WINDLL */ # ifdef USE_FWRITE # define WriteError(buf,len,strm) \ - ((extent)fwrite((char *)(buf),1,(extent)(len),strm) != (extent)(len)) + (fwrite((char *)(buf), 1, (len), (strm)) != (len)) # else # define WriteError(buf,len,strm) \ - ((extent)write(fileno(strm),(char *)(buf),(extent)(len)) != (extent)(len)) + (write(fileno(strm), (char *)(buf), (int)(len)) != (len)) # endif #endif /* ?WINDLL */ @@ -393,7 +393,9 @@ int open_outfile(__G) /* return 1 if fail */ if (uO.B_flag) { /* do backup */ char *tname; z_stat tmpstat; - int blen, flen, tlen; + size_t blen; + size_t flen; + size_t tlen; blen = strlen(BackupSuffix); flen = strlen(G.filename); @@ -902,7 +904,7 @@ int seek_zipf(__G__ abs_offset) G.incnt -= (int)inbuf_offset; G.inptr = G.inbuf + (int)inbuf_offset; } else { - G.incnt += (G.inptr-G.inbuf) - (int)inbuf_offset; + G.incnt += (int)(G.inptr- G.inbuf) - (int)inbuf_offset; G.inptr = G.inbuf + (int)inbuf_offset; } return(PK_OK); @@ -1362,7 +1364,7 @@ static int partflush(__G__ rawbuf, size, unshrink) } else # endif if (!uO.cflag && WriteError(transbuf, - (extent)(q-transbuf), G.outfile)) + (q- transbuf), G.outfile)) return disk_error(__G); else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf, (ulg)(q-transbuf), 0x2000)) @@ -1386,7 +1388,7 @@ static int partflush(__G__ rawbuf, size, unshrink) } else # endif if (!uO.cflag && - WriteError(transbuf, (extent)(q-transbuf), + WriteError(transbuf, (q- transbuf), G.outfile)) return disk_error(__G); else if (uO.cflag && (*G.message)((zvoid *)&G, @@ -1467,11 +1469,11 @@ static int partflush(__G__ rawbuf, size, unshrink) if (q > transbuf) { # ifdef DLL if (G.redirect_data) { - if (writeToMemory(__G__ transbuf, (extent)(q-transbuf))) + if (writeToMemory(__G__ transbuf, (q- transbuf))) return PK_ERR; } else # endif - if (!uO.cflag && WriteError(transbuf, (extent)(q-transbuf), + if (!uO.cflag && WriteError(transbuf, (q- transbuf), G.outfile)) return disk_error(__G); else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf, @@ -2758,7 +2760,7 @@ int do_string(__G__ length, option) /* return PK-type error code */ #ifdef WINDLL /* ran out of local mem -- had to cheat */ - win_fprintf((zvoid *)&G, stdout, (extent)(q-G.outbuf), + win_fprintf((zvoid *)&G, stdout, (int)(q-G.outbuf), (char *)G.outbuf); win_fprintf((zvoid *)&G, stdout, 2, (char *)"\n\n"); #else /* def WINDLL */ @@ -3148,7 +3150,7 @@ char *name_only( path) char *result = NULL; char *dot; char *name; - int len; + size_t len; name = strrchr( path, '/'); if (name == NULL) @@ -3537,7 +3539,7 @@ char *plastchar(ptr, len) ZCONST char *ptr; extent len; { - unsigned clen; + extent clen; ZCONST char *oldptr = ptr; while(*ptr != '\0' && len > 0){ oldptr = ptr; diff --git a/globals.h b/globals.h index d2b7cf4..bdac3fe 100644 --- a/globals.h +++ b/globals.h @@ -453,9 +453,9 @@ typedef struct Globals { uch *inptr_leftover; # ifdef VMS_TEXT_CONV - unsigned VMS_line_length; /* so native VMS variable-length text files */ - int VMS_line_state; /* are readable on other platforms */ - int VMS_line_pad; + extent VMS_line_length; /* For conversion of VMS variable-length- */ + int VMS_line_state; /* record text files on non-VMS systems. */ + int VMS_line_pad; # endif # if (defined(SFX) && defined(CHEAP_SFX_AUTORUN)) diff --git a/mod/win32/w32cfg.h b/mod/win32/w32cfg.h new file mode 100644 index 0000000..b450c2a --- /dev/null +++ b/mod/win32/w32cfg.h @@ -0,0 +1,674 @@ +/* + Copyright (c) 1990-2014 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2009-Jan-02 or later + (the contents of which are also included in unzip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + Win32 specific configuration section: + ---------------------------------------------------------------------------*/ + +#ifndef __w32cfg_h +#define __w32cfg_h + +#ifdef __CYGWIN__ +/* We treat the file system underneath the Cygwin Unix emulator environment + * as "native VFAT/NTFS" and use the WIN32 API for its special attributes... + */ +# ifdef UNIX +# undef UNIX +# endif +#endif + +#if (defined(_MSC_VER) && !defined(MSC)) +# define MSC +#endif + +/* enable multibyte character set support by default */ +#if (!defined(_MBCS) && !defined(NO_MBCS)) +# define _MBCS +#endif +#if (defined(_MBCS) && defined(NO_MBCS)) +# undef _MBCS +#endif +#if (defined(__CYGWIN__) && defined(_MBCS)) +# undef _MBCS /* Cygwin RTL lacks support for __mb_cur_max */ +#endif +#if (defined(__DJGPP__) && !defined(__EMX__) && defined(_MBCS)) +# undef _MBCS /* __mb_cur_max missing for RSXNTdj 1.6 beta */ +#endif + +#include /* off_t, time_t, dev_t, ... */ +#include +#include /* read(), open(), etc. */ +#include +#if ((defined(__RSXNT__) || defined(__EMX__)) && !defined(tzset)) +# define tzset _tzset +#endif +#if (defined(__LCC__) && !defined(tzset)) +# define tzset _tzset +#endif +#ifdef __MINGW32__ + extern void _tzset(void); /* this is missing in */ +# ifndef tzset +# define tzset _tzset +# endif +#endif +#ifdef W32_USE_IZ_TIMEZONE +# ifdef __BORLANDC__ +# define tzname tzname +# define IZTZ_DEFINESTDGLOBALS +# endif +# ifdef __WATCOMC__ +# define IZTZ_DEFINESTDGLOBALS +# endif +# ifndef tzset +# define tzset _tzset +# endif +# ifndef timezone +# define timezone _timezone +# endif +# ifndef daylight +# define daylight _daylight +# endif +# ifndef tzname +# define tzname _tzname +# endif +# if (!defined(NEED__ISINDST) && !defined(__BORLANDC__)) +# define NEED__ISINDST +# endif +# ifdef IZTZ_GETLOCALETZINFO +# undef IZTZ_GETLOCALETZINFO +# endif +# define IZTZ_GETLOCALETZINFO GetPlatformLocalTimezone +#endif /* W32_USE_IZ_TIMEZONE */ +#include +#if (!defined(__RSXNT__) && !defined(__CYGWIN__)) +# include /* mkdir() */ +#endif +#include +#ifdef __CYGWIN__ +# include + extern int setmode(int, int); /* this is missing in */ +#endif +#if (defined(MSC) || defined(__WATCOMC__) || defined(__MINGW32__)) +# include +# define HAVE_LOCALE_H 1 /* 2012-12-18 SMS. */ +#else +# include +#endif +#define GOT_UTIMBUF + +#ifdef _MBCS +# if (!defined(__EMX__) && !defined(__DJGPP__) && !defined(__CYGWIN__)) +# if (!defined(__MINGW32__) || defined(__MSVCRT__)) +# include +# include + /* for MSC (and compatible compilers), use routines supplied by RTL */ +# define CLEN(ptr) _mbclen((const uch *)(ptr)) +# define PREINCSTR(ptr) (ptr = (char *)_mbsinc((const uch *)(ptr))) +# define MBSCHR(str, c) (char *)_mbschr((const uch *)(str), (c)) +# define MBSRCHR(str, c) (char *)_mbsrchr((const uch *)(str), (c)) +# endif +# endif +# if (defined(__MINGW32__) && !defined(MB_CUR_MAX)) +# ifdef __MSVCRT__ + extern int *__p___mb_cur_max(void); +# define MB_CUR_MAX (*__p___mb_cur_max()) +# else + extern int *_imp____mb_cur_max_dll; +# define MB_CUR_MAX (*_imp____mb_cur_max_dll) +# endif +# endif +# if (defined(__LCC__) && !defined(MB_CUR_MAX)) + extern int *_imp____mb_cur_max; +# define MB_CUR_MAX (*_imp____mb_cur_max) +# endif +# if (defined(__DJGPP__) && !defined(__EMX__) && !defined(MB_CUR_MAX)) + extern int *_imp____mb_cur_max; +# define MB_CUR_MAX (*_imp____mb_cur_max) +# endif +#endif + +/* for UnZip, the "basic" part of the win32 api is sufficient */ +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#if defined(__FILEIO_C) +# ifndef __CYGWIN__ +# include +# endif +# include +# ifdef __RSXNT__ +# include "../win32/rsxntwin.h" +# endif +# ifndef TIME_ZONE_ID_INVALID +# define TIME_ZONE_ID_INVALID (DWORD)0xFFFFFFFFL +# endif +#endif +#if (defined(__ENVARGS_C) || defined(__EXTRACT_C) || defined(__UNZIP_C) || \ + defined(ZCRYPT_INTERNAL)) +# include +# ifdef __RSXNT__ +# include "../win32/rsxntwin.h" +# endif +# ifndef TIME_ZONE_ID_INVALID +# define TIME_ZONE_ID_INVALID (DWORD)0xFFFFFFFFL +# endif +#endif + +#ifndef Cdecl +# define Cdecl __cdecl +#endif + +/* the following definitions are considered as "obsolete" by Microsoft and + * might be missing in some versions of + */ +#ifndef AnsiToOem +# define AnsiToOem CharToOemA +#endif +#ifndef OemToAnsi +# define OemToAnsi OemToCharA +#endif + +#define DIR_END '\\' /* OS uses '\\' as directory separator */ +#define DIR_END2 '/' /* also check for '/' (RTL may convert) */ +#ifdef DATE_FORMAT +# undef DATE_FORMAT +#endif +#define DATE_FORMAT dateformat() +#ifdef DATE_SEPCHAR +# undef DATE_SEPCHAR +#endif +#define DATE_SEPCHAR dateseparator() +#define lenEOL 2 +#define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);} + +#if (defined(__RSXNT__) && !defined(HAVE_MKTIME)) +# define HAVE_MKTIME /* use mktime() in time conversion routines */ +#endif +#if (defined(MSC) && !defined(HAVE_MKTIME)) +# define HAVE_MKTIME /* use mktime() in time conversion routines */ +#endif +#if (defined(__CYGWIN__) && defined(HAVE_MKTIME)) +# undef HAVE_MKTIME /* Cygnus' mktime() implementation is buggy */ +#endif +#if (defined(W32_USE_IZ_TIMEZONE) && !defined(HAVE_MKTIME)) +# define HAVE_MKTIME /* use mktime() in time conversion routines */ +#endif +#if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)) +# define USE_EF_UT_TIME +#endif +#if (!defined(NO_DIR_ATTRIB) && !defined(SET_DIR_ATTRIB)) +# define SET_DIR_ATTRIB +#endif +#if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP)) +# define TIMESTAMP +#endif +#if (!defined(NO_NTSD_EAS) && !defined(NTSD_EAS)) +# define NTSD_EAS /* enable NTSD support unless explicitly suppressed */ +#endif +#if (defined(NTSD_EAS) && !defined(RESTORE_ACL)) +# define RESTORE_ACL /* "restore ACLs" only needed when NTSD_EAS active */ +#endif +#ifdef NO_UNICODE_SUPPORT +# ifdef UNICODE_SUPPORT +# undef UNICODE_SUPPORT +# endif +#endif +#if (!defined(NO_UNICODE_SUPPORT) && !defined(UNICODE_SUPPORT)) +# define UNICODE_SUPPORT /* enable UTF-8 filename support by default */ +#endif +#ifdef UNICODE_SUPPORT +# ifndef WIN32_WIDE +# define WIN32_WIDE +# endif +#endif +#if (defined(UNICODE_SUPPORT) && !defined(UNICODE_WCHAR)) +# define UNICODE_WCHAR /* wchar_t is UTF-16 encoded on WIN32 */ +#endif +#ifdef UTF8_MAYBE_NATIVE +# undef UTF8_MAYBE_NATIVE /* UTF-8 cannot be system charset on WIN32 */ +#endif + +/* Windows-only, wide-character, fopen() modes. See also unzpriv.h. */ +#if defined( UNICODE_SUPPORT) && defined( WIN32_WIDE) +# define FOPR_W L"rb" +# define FOPM_W L"r+b" +# define FOPW_W L"wb" +# define FOPWT_W L"wt" +# define FOPWR_W L"w+b" +#endif + +/* The following compiler systems provide or use a runtime library with a + * locale-aware isprint() implementation. For these systems, the "enhanced" + * unprintable charcode detection in fnfilter() gets enabled. + */ +#if (!defined(HAVE_WORKING_ISPRINT) && !defined(NO_WORKING_ISPRINT)) +# if defined(MSC) || defined(__BORLANDC__) +# define HAVE_WORKING_ISPRINT +# endif +# if defined(__MINGW32__) && defined(__MSVCRT__) +# define HAVE_WORKING_ISPRINT +# endif +#endif + +/* WIN32 runs solely on little-endian processors; enable support + * for the 32-bit optimized CRC-32 C code by default. + */ +#ifdef IZ_CRC_BE_OPTIMIZ +# undef IZ_CRC_BE_OPTIMIZ +#endif +#if !defined(IZ_CRC_LE_OPTIMIZ) && !defined(NO_CRC_OPTIMIZ) +# define IZ_CRC_LE_OPTIMIZ +#endif + +/* handlers for OEM <--> ANSI string conversions */ +#ifdef __RSXNT__ + /* RSXNT uses OEM coded strings in functions supplied by C RTL */ +# ifdef CRTL_CP_IS_ISO +# undef CRTL_CP_IS_ISO +# endif +# ifndef CRTL_CP_IS_OEM +# define CRTL_CP_IS_OEM +# endif +#else + /* "real" native WIN32 compilers use ANSI coded strings in C RTL calls */ +# ifndef CRTL_CP_IS_ISO +# define CRTL_CP_IS_ISO +# endif +# ifdef CRTL_CP_IS_OEM +# undef CRTL_CP_IS_OEM +# endif +#endif + +#ifdef CRTL_CP_IS_ISO + /* C RTL's file system support assumes ANSI coded strings */ +# define ISO_TO_INTERN(src, dst) {if ((src) != (dst)) strcpy((dst), (src));} +# define OEM_TO_INTERN(src, dst) OemToAnsi(src, dst) +# define INTERN_TO_ISO(src, dst) {if ((src) != (dst)) strcpy((dst), (src));} +# define INTERN_TO_OEM(src, dst) AnsiToOem(src, dst) +#endif /* CRTL_CP_IS_ISO */ +#ifdef CRTL_CP_IS_OEM + /* C RTL's file system support assumes OEM coded strings */ +# define ISO_TO_INTERN(src, dst) AnsiToOem(src, dst) +# define OEM_TO_INTERN(src, dst) {if ((src) != (dst)) strcpy((dst), (src));} +# define INTERN_TO_ISO(src, dst) OemToAnsi(src, dst) +# define INTERN_TO_OEM(src, dst) {if ((src) != (dst)) strcpy((dst), (src));} +#endif /* CRTL_CP_IS_OEM */ +#define _OEM_INTERN(str1) OEM_TO_INTERN(str1, str1) +#define _ISO_INTERN(str1) ISO_TO_INTERN(str1, str1) +#ifndef WINDLL + /* Despite best intentions, for the command-line version UzpPassword() + * could return either character set, depending on whether running under + * Win95 (DOS-session) or WinNT (native WinNT command interpreter)! */ +# define STR_TO_CP2(dst, src) (AnsiToOem(src, dst), dst) +# define STR_TO_CP3(dst, src) (OemToAnsi(src, dst), dst) +#else + /* The WINDLL front end is known to supply ISO/ANSI-coded passwords! */ +# define STR_TO_CP2(dst, src) (AnsiToOem(src, dst), dst) +#endif +/* dummy defines to disable these functions, they are not needed */ +#define STR_TO_OEM +#define STR_TO_ISO + +#if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +# if defined( DYNAMIC_WIDE_NAME) || defined( SYMLINKS) + wchar_t *utf8_to_wchar_string_dyn OF((const char *)); +# endif /* defined( DYNAMIC_WIDE_NAME) || defined( SYMLINKS) */ +# ifdef DYNAMIC_WIDE_NAME +# define utf8_to_wchar_string utf8_to_wchar_string_dyn +# else /* def DYNAMIC_WIDE_NAME */ +# define utf8_to_wchar_string utf8_to_wchar_string_stat + void utf8_to_wchar_string_stat OF((wchar_t *, const char *)); +# endif /* def DYNAMIC_WIDE_NAME [else] */ + wchar_t *local_to_wchar_string OF((char *)); + int has_win32_wide(); +#endif /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ + +/* 2013-07-08 SMS. + * Some anti-virus programs may temporarily lock a newly created + * file, causing transient failures of CreateFile[AW]() when + * setting date-time (win32/win32.c:close_outfile()). + * We try up to IZ_CREATEFILE_TRY_COUNT times, at intervals of + * IZ_CREATEFILE_TRY_TIME_MS (millisecond). To disable the + * retries, define IZ_CREATEFILE_TRY_COUNT as zero. (win32/w32cfg.h). + * http://sourceforge.net/p/infozip/bugs/44/ + * http://support.microsoft.com/kb/316609 + */ +#ifndef IZ_CREATEFILE_TRY_COUNT +# define IZ_CREATEFILE_TRY_COUNT 8 +#endif +#ifndef IZ_CREATEFILE_TRY_TIME_MS +# define IZ_CREATEFILE_TRY_TIME_MS 125 +#endif +#if defined( IZ_CREATEFILE_TRY_COUNT) && (IZ_CREATEFILE_TRY_COUNT > 1) +# define RETRY_CREATEFILE 1 +#endif + +/* Static variables that we have to add to Uz_Globs: */ +#if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +#define SYSTEM_SPECIFIC_GLOBALS \ + int created_dir;\ + int renamed_fullpath;\ + size_t fnlen;\ + unsigned nLabelDrive;\ + char lastRootPath[4];\ + wchar_t lastRootPathw[4];\ + int lastVolOldFAT, lastVolLocTim;\ + char *rootpath, *buildpathHPFS, *buildpathFAT, *endHPFS, *endFAT;\ + wchar_t *rootpathw, *buildpathHPFSw, *buildpathFATw, *endHPFSw, *endFATw;\ + ZCONST char *wildname;\ + ZCONST wchar_t *wildnamew;\ + char *dirname, matchname[FILNAMSIZ];\ + wchar_t *dirnamew, matchnamew[FILNAMSIZ];\ + size_t dirnamelen;\ + size_t rootlen;\ + int have_dirname, notfirstcall;\ + zvoid *wild_dir; +#else /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ +#define SYSTEM_SPECIFIC_GLOBALS \ + int created_dir, renamed_fullpath, fnlen;\ + unsigned nLabelDrive;\ + char lastRootPath[4];\ + int lastVolOldFAT, lastVolLocTim;\ + char *rootpath, *buildpathHPFS, *buildpathFAT, *endHPFS, *endFAT;\ + ZCONST char *wildname;\ + char *dirname, matchname[FILNAMSIZ];\ + int rootlen, have_dirname, dirnamelen, notfirstcall;\ + zvoid *wild_dir; +#endif /* ?(defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ + +/* created_dir, renamed_fullpath, fnlen, and nLabelDrive are used by */ +/* both mapname() and checkdir(). */ +/* lastRootPath, lastVolOldFAT and lastVolLocTim are used by */ +/* IsVolumeOldFAT() and NTQueryVolInfo(). */ +/* rootlen, rootpath, buildpathHPFS, buildpathFAT, endHPFS, and endFAT */ +/* are used by checkdir(). */ +/* wild_dir, dirname, wildname, matchname[], dirnamelen, have_dirname, */ +/* and notfirstcall are used by do_wild(). */ + +/* This replacement for C-RTL-supplied getch() (or similar) functionality + * avoids leaving unabsorbed LFs in the keyboard buffer under Windows95, + * and supports the +[0] feature. + */ +int getch_win32 OF((void)); + +/* Up to now, all versions of Microsoft C runtime libraries lack the support + * for customized (non-US) switching rules between daylight saving time and + * standard time in the TZ environment variable string. + * But non-US timezone rules are correctly supported when timezone information + * is read from the OS system settings in the Win32 registry. + * The following work-around deletes any TZ environment setting from + * the process environment. This results in a fallback of the RTL time + * handling code to the (correctly interpretable) OS system settings, read + * from the registry. + */ +#ifdef USE_EF_UT_TIME +# if (defined(__WATCOMC__) || defined(__CYGWIN__) || \ + defined(W32_USE_IZ_TIMEZONE)) +# define iz_w32_prepareTZenv() +# else +# define iz_w32_prepareTZenv() putenv("TZ=") +# endif +#endif + +/* This patch of stat() is useful for at least two compilers. It is */ +/* difficult to take a stat() of a root directory under Windows95, so */ +/* zstat_win32() detects that case and fills in suitable values. */ +#ifndef __RSXNT__ +# ifndef W32_STATROOT_FIX +# define W32_STATROOT_FIX +# endif +#endif /* !__RSXNT__ */ + +#define W32_STAT_BANDAID +#if defined(REENTRANT) +# define __W32STAT_GLOBALS__ Uz_Globs *pG, +# define __W32STAT_G__ pG, +#else +# define __W32STAT_GLOBALS__ +# define __W32STAT_G__ +#endif +#ifdef SSTAT +# undef SSTAT +#endif +#ifdef WILD_STAT_BUG +# define SSTAT(path, pbuf) (iswild(path) || zstat_win32(__W32STAT_G__ path, pbuf)) +#else +# define SSTAT(path, pbuf) zstat_win32(__W32STAT_G__ path, pbuf) +#endif + +#if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +# ifdef WILD_STAT_BUG +# define SSTATW(pathw, pbuf) (iswildw(pathw) || zstat_win32w(__W32STAT_G__ pathw, pbuf)) +# else +# define SSTATW(pathw, pbuf) zstat_win32w(__W32STAT_G__ pathw, pbuf) +# endif +#endif /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ + + +#ifdef SYMLINKS +# define lstat SSTAT +# define lstatw SSTATW +# ifndef S_ISLNK +# ifndef S_IFLNK +# define S_IFLNK 0120000 +# endif +# define S_ISLNK(m) (((m)& S_IFMT) == S_IFLNK) +# endif /* ndef S_ISLNK */ + +int symlink( const char *target, const char *name, int is_dir); +# ifdef UNICODE_SUPPORT +int symlinkw( const char *target, const wchar_t *name, int is_dir); +# endif /* def UNICODE_SUPPORT */ +#endif /* def SYMLINKS */ + + +#ifdef __WATCOMC__ +# ifdef __386__ +# ifndef WATCOMC_386 +# define WATCOMC_386 +# endif +# define __32BIT__ +# undef far +# define far +# undef near +# define near +# undef Cdecl +# define Cdecl + +/* gaah -- Watcom's docs claim that _get_osfhandle exists, but it doesn't. */ +# define _get_osfhandle _os_handle + +/* Get asm routines to link properly without using "__cdecl": */ +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [eax] modify [eax] +# pragma aux get_crc_table "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif /* !USE_ZLIB */ +# endif /* __386__ */ +#endif /* __WATCOMC__ */ + +#define SCREENWIDTH 80 +#define SCREENSIZE(scrrows, scrcols) screensize(scrrows, scrcols) +int screensize(int *tt_rows, int *tt_cols); + +/* on the DOS or NT console screen, line-wraps are always enabled */ +#define SCREENLWRAP 1 +#define TABSIZE 8 + + +/* 64-bit-Integers & Large File Support + * (pasted here from Zip 3b, osdep.h - Myles Bennett 7-jun-2004) + * (updated from Zip 3.0d - Ed Gordon 6-oct-2004) + * + * If this is set it is assumed that the port + * supports 64-bit file calls. The types are + * defined here. Any local implementations are + * in w32i64.c and the prototypes for the calls are + * in unzip.h. Note that a port must support + * these calls fully or should not set + * LARGE_FILE_SUPPORT. + */ + +/* Automatically set ZIP64_SUPPORT if supported */ + +#ifndef NO_ZIP64_SUPPORT +# ifndef ZIP64_SUPPORT +# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) +# define ZIP64_SUPPORT +# elif defined(__LCC__) + /* LCC links against crtdll.dll -> no support of 64-bit offsets :( */ +# elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100)) +# define ZIP64_SUPPORT +# elif (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0520)) + /* Borland C RTL lacks any support to get/set 64-bit file pointer :( */ +# endif +# endif +#endif + +#ifdef ZIP64_SUPPORT + /* base type for file offsets and file sizes */ +# if (defined(__GNUC__) || defined(ULONG_LONG_MAX)) + typedef long long zoff_t; +# else + /* all other compilers use this as intrinsic 64-bit type */ + typedef __int64 zoff_t; +# endif +# define ZOFF_T_DEFINED + + /* user-defined types and format strings for 64-bit numbers and + * file pointer functions (these depend on the rtl library and library + * headers used; they are NOT compiler-specific) + */ +# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__LCC__) + /* MS C and VC, MinGW32, lcc32 */ + /* these systems use the Microsoft C RTL */ + + /* 64-bit stat struct */ + typedef struct _stati64 z_stat; +# define Z_STAT_DEFINED + +# ifdef __LCC__ + /* The LCC headers lack these declarations of MSC rtl functions in + sys/stat.h. */ + struct _stati64 { + unsigned int st_dev; + unsigned short st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + unsigned int st_rdev; + __int64 st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; + }; + int _stati64(const char *, struct _stati64 *); + int _fstati64(int, struct _stati64 *); + __int64 _lseeki64(int, __int64, int); +# endif /* __LCC__ */ + + /* printf format size prefix for zoff_t values */ +# define FZOFFT_FMT "I64" +# define FZOFFT_HEX_WID_VALUE "16" + +# define SHORTHDRSTATS "%9I64u %02u%c%02u%c%02u %02u:%02u %c" +# define SHORTFILETRAILER " -------- -------\n%9I64u %9lu file%s\n" + +# elif (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0520)) + /* Borland C 5.2 or newer */ + + /* 64-bit stat struct */ + typedef struct stati64 z_stat; +# define Z_STAT_DEFINED + + /* Borland C does not provide a 64-bit-capable _lseeki64(), so we + need to use the stdio.h stream functions instead. */ +# ifndef USE_STRM_INPUT +# define USE_STRM_INPUT +# endif + + /* printf format size prefix for zoff_t values */ +# define FZOFFT_FMT "L" +# define FZOFFT_HEX_WID_VALUE "16" + +# define SHORTHDRSTATS "%9Lu %02u%c%02u%c%02u %02u:%02u %c" +# define SHORTFILETRAILER " -------- -------\n%9Lu %9lu file%s\n" + +# elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100)) + /* WATCOM C */ + + /* 64-bit stat struct */ + typedef struct _stati64 z_stat; +# define Z_STAT_DEFINED + + /* printf format size prefix for zoff_t values */ +# define FZOFFT_FMT "ll" +# define FZOFFT_HEX_WID_VALUE "16" + +# define SHORTHDRSTATS "%9llu %02u%c%02u%c%02u %02u:%02u %c" +# define SHORTFILETRAILER " -------- -------\n%9llu %9lu file%s\n" + +# elif (defined(__IBMC__) && (__IBMC__ >= 350)) + /* IBM C */ + + /* 64-bit stat struct */ + + /* printf format size prefix for zoff_t values */ +# define FZOFFT_FMT "I64" +# define FZOFFT_HEX_WID_VALUE "16" + +# define SHORTHDRSTATS "%9I64u %02u%c%02u%c%02u %02u:%02u %c" +# define SHORTFILETRAILER " -------- -------\n%9I64u %9lu file%s\n" + +# endif + +#endif + +/* If port has LARGE_FILE_SUPPORT then define here + to make automatic unless overridden */ + +#ifndef LARGE_FILE_SUPPORT +# ifndef NO_LARGE_FILE_SUPPORT +# if defined(_MSC_VER) || defined(__MINGW32__) +# define LARGE_FILE_SUPPORT +# elif defined(__LCC__) + /* LCC links against crtdll.dll -> no support of 64-bit offsets :( */ +# elif defined(__CYGWIN__) +# define LARGE_FILE_SUPPORT +# elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100)) +# define LARGE_FILE_SUPPORT +# elif (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0520)) + /* Borland C RTL lacks any support to get/set 64-bit file pointer :( */ +# endif +# endif +#endif + + +#ifndef LARGE_FILE_SUPPORT + /* No Large File Support */ + + /* base type for file offsets and file sizes */ + typedef long zoff_t; +# define ZOFF_T_DEFINED + + /* stat struct */ + typedef struct stat z_stat; +# define Z_STAT_DEFINED + +# define FZOFFT_FMT "l" +# define FZOFFT_HEX_WID_VALUE "8" + + +# define SHORTHDRSTATS "%9lu %02u%c%02u%c%02u %02u:%02u %c" +# define SHORTFILETRAILER " -------- -------\n%9lu %9lu file%s\n" + +#endif /* LARGE_FILE_SUPPORT */ + +#endif /* !__w32cfg_h */ diff --git a/mod/win32/win32.c b/mod/win32/win32.c new file mode 100644 index 0000000..4a7d1bc --- /dev/null +++ b/mod/win32/win32.c @@ -0,0 +1,5050 @@ +/* + Copyright (c) 1990-2014 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2009-Jan-02 or later + (the contents of which are also included in unzip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + win32.c + + 32-bit Windows-specific (NT/9x) routines for use with Info-ZIP's UnZip 5.3 + and later. + + Contains: GetLoadPath() + Opendir() + Readdir() + Closedir() + SetSD() set security descriptor on file + FindSDExtraField() extract SD e.f. block from extra field + IsWinNT() indicate type of WIN32 platform + test_NTSD() test integrity of NT security data + utime2NtfsFileTime() + utime2VFatFileTime() + FStampIsLocTime() + NtfsFileTime2utime() + VFatFileTime2utime() + getNTfiletime() + SetFileSize() + close_outfile() + defer_dir_attribs() + set_direc_attribs() + stamp_file() + isfloppy() + NTQueryVolInfo() + IsVolumeOldFAT() + do_wild() + mapattr() + mapname() + mapnamew() + maskDOSdevice() + map2fat() + checkdir() + dateformat() + dateseparator() + version() + screensize() + zstat_win32() + conv_to_rule() + GetPlatformLocalTimezone() + getch_win32() + + ---------------------------------------------------------------------------*/ + + +#define UNZIP_INTERNAL +#include "../unzip.h" +#include /* must be AFTER unzip.h to avoid struct G problems */ +#ifdef __RSXNT__ +# include "../win32/rsxntwin.h" +#endif +#include "../win32/nt.h" + +#ifndef FUNZIP /* most of this file is not used with fUnZip */ + +/* some non-MS runtime headers (e.g. lcc) may miss this definition */ +# ifndef FILE_WRITE_ATTRIBUTES +# define FILE_WRITE_ATTRIBUTES 0x0100 +# endif + +# if (defined(__EMX__) || defined(__CYGWIN__)) +# define MKDIR(path,mode) mkdir(path,mode) +# else +# define MKDIR(path,mode) mkdir(path) +# endif + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +# if (defined(__EMX__) || defined(__CYGWIN__)) +# define MKDIRW(pathw,mode) _wmkdir(pathw,mode) +# else +# define MKDIRW(pathw,mode) _wmkdir(pathw) +# endif +# endif + +# ifdef HAVE_WORKING_DIRENT_H +# undef HAVE_WORKING_DIRENT_H +# endif +/* The emxrtl dirent support of (__GO32__ || __EMX__) converts to lowercase! */ +# if defined(__CYGWIN__) +# define HAVE_WORKING_DIRENT_H +# endif + +# ifndef SFX +# ifdef HAVE_WORKING_DIRENT_H +# include /* use readdir() */ +# define zdirent dirent +# define zDIR DIR +# define Opendir opendir +# define Readdir readdir +# define Closedir closedir +# else /* !HAVE_WORKING_DIRENT_H */ + typedef struct zdirent { + char reserved [21]; + char ff_attrib; + short ff_ftime; + short ff_fdate; + long size; + char d_name[MAX_PATH]; + int d_first; + HANDLE d_hFindFile; + } zDIR; + + static zDIR *Opendir (const char *n); + static struct zdirent *Readdir (zDIR *d); + static void Closedir (zDIR *d); +# endif /* ?HAVE_WORKING_DIRENT_H */ +# endif /* !SFX */ + +# ifdef SET_DIR_ATTRIB +typedef struct NTdirattr { /* struct for holding unix style directory */ + struct NTdirattr *next; /* info until can be sorted and set at end */ + char *fn; /* filename of directory */ + FILETIME Modft; /* File time type defined in NT, `last modified' time */ + FILETIME Accft; /* NT file time type, `last access' time */ + FILETIME Creft; /* NT file time type, `file creation' time */ + int gotTime; + unsigned perms; /* same as min_info.file_attr */ +# ifdef NTSD_EAS + unsigned SDlen; /* length of SD data in buf */ +# endif + char buf[1]; /* buffer stub for directory SD and name */ +} NTdirattr; +#define NtAtt(d) ((NTdirattr *)d) /* typecast shortcut */ + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + typedef struct NTdirattrw { /* struct for holding unix style directory */ + struct NTdirattrw *next; /* info until can be sorted and set at end */ + wchar_t *fnw; /* filename of directory */ + FILETIME Modft; /* File time type defined in NT, `last modified' time */ + FILETIME Accft; /* NT file time type, `last access' time */ + FILETIME Creft; /* NT file time type, `file creation' time */ + int gotTime; + unsigned perms; /* same as min_info.file_attr */ +# ifdef NTSD_EAS + unsigned SDlen; /* length of SD data in buf */ +# endif + wchar_t buf[1]; /* buffer stub for directory SD and name */ + } NTdirattrw; +# define NtAttw(dw) ((NTdirattrw *)dw) /* typecast shortcut */ +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + +# endif /* SET_DIR_ATTRIB */ + + +/* Function prototypes */ +# ifdef NTSD_EAS +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + static int SetSD(__GPRO__ wchar_t *path, unsigned fperms, + uch *eb_ptr, unsigned eb_len); +# else + static int SetSD(__GPRO__ char *path, unsigned fperms, + uch *eb_ptr, unsigned eb_len); +# endif + static int FindSDExtraField(__GPRO__ + uch *ef_ptr, unsigned ef_len, + uch **p_ebSD_ptr, unsigned *p_ebSD_len); +# endif /* NTSD_EAS */ + +# ifndef NO_W32TIMES_IZFIX + static void utime2NtfsFileTime(time_t ut, FILETIME *pft); +# endif +static void utime2VFatFileTime(time_t ut, FILETIME *pft, int clipDosMin); +# if (defined(W32_STAT_BANDAID) && !defined(NO_W32TIMES_IZFIX)) + static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut); +# endif +# ifdef W32_STAT_BANDAID + static int VFatFileTime2utime(const FILETIME *pft, time_t *ut); +# endif +static int FStampIsLocTime(__GPRO__ const char *path); +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + static int FStampIsLocTimeW(__GPRO__ const wchar_t *pathw); +# endif + + +static int getNTfiletime (__GPRO__ FILETIME *pModFT, FILETIME *pAccFT, + FILETIME *pCreFT); +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +static int getNTfiletimeW (__GPRO__ FILETIME *pModFT, FILETIME *pAccFT, + FILETIME *pCreFT); +# endif +static int isfloppy (int nDrive); +static int NTQueryVolInfo (__GPRO__ const char *name); +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + static int NTQueryVolInfoW (__GPRO__ const wchar_t *namew); +# endif +static int IsVolumeOldFAT (__GPRO__ const char *name); +static void maskDOSdevice (__GPRO__ char *pathcomp); +static void map2fat (char *pathcomp, char **pEndFAT); +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + static void maskDOSdevicew (__GPRO__ wchar_t *pathcompw); + static void map2fatw (wchar_t *pathcompw, wchar_t **pEndFATw); +# endif + + +# if (defined(__MINGW32__) && !defined(USE_MINGW_GLOBBING)) + int _CRT_glob = 0; /* suppress command line globbing by C RTL */ +# endif + +# ifdef ACORN_FTYPE_NFS +/* Acorn bits for NFS filetyping */ +typedef struct { + uch ID[2]; + uch size[2]; + uch ID_2[4]; + uch loadaddr[4]; + uch execaddr[4]; + uch attr[4]; +} RO_extra_block; + +# endif /* ACORN_FTYPE_NFS */ + +/* static int created_dir; */ /* used by mapname(), checkdir() */ +/* static int renamed_fullpath; */ /* ditto */ +/* static int fnlen; */ /* ditto */ +/* static unsigned nLabelDrive; */ /* ditto */ + + + +# ifdef SFX + +/**************************/ +/* Function GetLoadPath() */ +/**************************/ + +char *GetLoadPath(__GPRO) +{ +# ifdef MSC + extern char *_pgmptr; + return _pgmptr; + +# else /* use generic API call */ + + GetModuleFileName(NULL, G.filename, FILNAMSIZ); + _ISO_INTERN(G.filename); /* translate to codepage of C rtl's stdio */ + return G.filename; +# endif + +} /* end function GetLoadPath() */ + + + + + +# else /* !SFX */ + +# ifndef HAVE_WORKING_DIRENT_H + +/**********************/ /* Borrowed from ZIP 2.0 sources */ +/* Function Opendir() */ /* Difference: no special handling for */ +/**********************/ /* hidden or system files. */ + +static zDIR *Opendir(n) + const char *n; /* directory to open */ +{ + zDIR *d; /* malloc'd return value */ + char *p; /* malloc'd temporary string */ + WIN32_FIND_DATAA fd; + extent len = strlen(n); + + /* Start searching for files in directory n */ + + if ((d = (zDIR *)izu_malloc(sizeof(zDIR))) == NULL || + (p = izu_malloc(strlen(n) + 5)) == NULL) + { + if (d != (zDIR *)NULL) + izu_free((void *)d); + return (zDIR *)NULL; + } + INTERN_TO_ISO(n, p); + if (len > 0) { + if (p[len-1] == ':') + p[len++] = '.'; /* x: => x:. */ + else if (p[len-1] == '/' || p[len-1] == '\\') + --len; /* foo/ => foo */ + } + strcpy(p+len, "/*"); + + if (INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFileA(p, &fd))) { + izu_free((zvoid *)d); + izu_free((zvoid *)p); + return NULL; + } + strcpy(d->d_name, fd.cFileName); + + izu_free((zvoid *)p); + d->d_first = 1; + return d; + +} /* end of function Opendir() */ + + + + +/**********************/ /* Borrowed from ZIP 2.0 sources */ +/* Function Readdir() */ /* Difference: no special handling for */ +/**********************/ /* hidden or system files. */ + +static struct zdirent *Readdir(d) + zDIR *d; /* directory stream from which to read */ +{ + /* Return pointer to first or next directory entry, or NULL if end. */ + + if ( d->d_first ) + d->d_first = 0; + else + { + WIN32_FIND_DATAA fd; + + if ( !FindNextFileA(d->d_hFindFile, &fd) ) + return NULL; + + ISO_TO_INTERN(fd.cFileName, d->d_name); + } + return (struct zdirent *)d; + +} /* end of function Readdir() */ + + + + +/***********************/ +/* Function Closedir() */ /* Borrowed from ZIP 2.0 sources */ +/***********************/ + +static void Closedir(d) + zDIR *d; /* directory stream to close */ +{ + FindClose(d->d_hFindFile); + izu_free(d); +} + +# endif /* !HAVE_WORKING_DIRENT_H */ +# endif /* ?SFX */ + + + + +# ifdef NTSD_EAS + +/**********************/ +/* Function SetSD() */ /* return almost-PK errors */ +/**********************/ + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +static int SetSD(__G__ path, fperms, eb_ptr, eb_len) + __GDEF + wchar_t *path; +# else +static int SetSD(__G__ path, fperms, eb_ptr, eb_len) + __GDEF + char *path; +# endif + unsigned fperms; + uch *eb_ptr; + unsigned eb_len; +{ + ulg ntsd_ucSize; + VOLUMECAPS VolumeCaps; + uch *security_data; + int error; + + ntsd_ucSize = makelong(eb_ptr + (EB_HEADSIZE+EB_UCSIZE_P)); + if (ntsd_ucSize > 0L && eb_len <= (EB_NTSD_L_LEN + EB_CMPRHEADLEN)) + return IZ_EF_TRUNC; /* no compressed data! */ + + /* provide useful input */ + VolumeCaps.dwFileAttributes = fperms; + VolumeCaps.bUsePrivileges = (uO.X_flag > 1); + + /* check target volume capabilities - just fall through + * and try if fail */ +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + if (GetVolumeCaps(G.rootpathw, path, &VolumeCaps) && + !(VolumeCaps.dwFileSystemFlags & FS_PERSISTENT_ACLS)) + return PK_OK; +# else + if (GetVolumeCaps(G.rootpath, path, &VolumeCaps) && + !(VolumeCaps.dwFileSystemFlags & FS_PERSISTENT_ACLS)) + return PK_OK; +# endif + + /* allocate storage for uncompressed data */ + security_data = (uch *)izu_malloc((extent)ntsd_ucSize); + if (security_data == (uch *)NULL) + return PK_MEM4; + + error = memextract(__G__ security_data, ntsd_ucSize, + (eb_ptr + (EB_HEADSIZE+EB_NTSD_L_LEN)), (ulg)(eb_len - EB_NTSD_L_LEN)); + + if (error == PK_OK) { + if (SecuritySet(path, &VolumeCaps, security_data)) { + error = PK_COOL; + if (!uO.tflag && QCOND2) + Info(slide, 0, ((char *)slide, " (%lu bytes security)", + ntsd_ucSize)); + } + } + + izu_free(security_data); + return error; +} + + + + +/********************************/ /* scan extra fields for something */ +/* Function FindSDExtraField() */ /* we happen to know */ +/********************************/ +/* Returns TRUE when a valid NTFS SD block is found. + * Address and size of the NTSD e.f. block are passed up to the caller. + * In case of more than one valid NTSD block in the e.f., the last block + * found is passed up. + * Returns FALSE and leaves the content of the ebSD_ptr and ebSD_len + * parameters untouched when no valid NTFS SD block is found. */ +static int FindSDExtraField(__GPRO__ + uch *ef_ptr, unsigned ef_len, + uch **p_ebSD_ptr, unsigned *p_ebSD_len) +{ + int rc = FALSE; + + if (!uO.X_flag) + return FALSE; /* user said don't process ACLs; for now, no other + extra block types are handled here */ + + while (ef_len >= EB_HEADSIZE) + { + unsigned eb_id = makeword(EB_ID + ef_ptr); + unsigned eb_len = makeword(EB_LEN + ef_ptr); + + if (eb_len > (ef_len - EB_HEADSIZE)) { + /* discovered some extra field inconsistency! */ + Trace((stderr, + "FindSDExtraField: block length %u > rest ef_size %u\n", eb_len, + ef_len - EB_HEADSIZE)); + break; + } + + switch (eb_id) + { + /* process security descriptor extra data if: + Caller is WinNT AND + Target local/remote drive supports acls AND + Target file is not a directory (else we defer processing + until later) + */ + case EF_NTSD: + if (!IsWinNT()) + break; /* OS not capable of handling NTFS attributes */ + + if (eb_len < EB_NTSD_L_LEN) + break; /* not a valid NTSD extra field */ + + /* check if we know how to handle this version */ + if (*(ef_ptr + (EB_HEADSIZE+EB_NTSD_VERSION)) + > (uch)EB_NTSD_MAX_VER) + break; + + *p_ebSD_ptr = ef_ptr; + *p_ebSD_len = eb_len; + rc = TRUE; + break; + +# ifdef DEBUG + case EF_OS2: + case EF_AV: + case EF_PKVMS: + case EF_PKW32: + case EF_PKUNIX: + case EF_IZVMS: + case EF_IZUNIX: + case EF_IZUNIX2: + case EF_TIME: + case EF_MAC3: + case EF_JLMAC: + case EF_ZIPIT: + case EF_VMCMS: + case EF_MVS: + case EF_ACL: + case EF_ATHEOS: + case EF_BEOS: + case EF_QDOS: + case EF_AOSVS: + case EF_SPARK: + case EF_MD5: + case EF_ASIUNIX: + break; /* shut up for other known e.f. blocks */ +# endif /* DEBUG */ + + default: + Trace((stderr, + "FindSDExtraField: unknown extra field block, ID=%u\n", + eb_id)); + break; + } + + ef_ptr += (eb_len + EB_HEADSIZE); + ef_len -= (eb_len + EB_HEADSIZE); + } + + return rc; +} + + + + +# ifndef SFX + +/**************************/ +/* Function test_NTSD() */ /* returns PK_WARN when NTSD data is invalid */ +/**************************/ + +# ifdef __BORLANDC__ +/* Turn off warning about not using all parameters for this function only */ +# pragma argsused +# endif +int test_NTSD(__G__ eb, eb_size, eb_ucptr, eb_ucsize) + __GDEF + uch *eb; + long eb_size; + uch *eb_ucptr; + ulg eb_ucsize; +{ + return (ValidateSecurity(eb_ucptr) ? PK_OK : PK_WARN); +} /* end function test_NTSD() */ + +# endif /* !SFX */ +# endif /* NTSD_EAS */ + + + + +/**********************/ +/* Function IsWinNT() */ +/**********************/ + +int IsWinNT(void) /* returns TRUE if real NT, FALSE if Win9x or Win32s */ +{ + static DWORD g_PlatformId = 0xFFFFFFFF; /* saved platform indicator */ + + if (g_PlatformId == 0xFFFFFFFF) { + /* note: GetVersionEx() doesn't exist on WinNT 3.1 */ + if (GetVersion() < 0x80000000) + g_PlatformId = TRUE; + else + g_PlatformId = FALSE; + } + return (int)g_PlatformId; +} + + +/* DEBUG_TIME insertion: */ +# ifdef DEBUG_TIME +static int show_NTFileTime(FILE *hdo, char *TTmsg, int isloc, FILETIME *pft); + +static int show_NTFileTime(FILE *hdo, char *TTmsg, int isloc, FILETIME *pft) +{ + SYSTEMTIME w32tm; + int rval; + + rval = FileTimeToSystemTime(pft, &w32tm); + if (!rval) { + fprintf(hdo, "%s\n %08lX,%08lX (%s) -> Conversion failed !!!\n", + TTmsg, (ulg)(pft->dwHighDateTime), (ulg)(pft->dwLowDateTime), + (isloc ? "local" : "UTC")); + } else { + fprintf(hdo, "%s\n %08lx,%08lx -> %04u-%02u-%02u, %02u:%02u:%02u %s\n", + TTmsg, (ulg)(pft->dwHighDateTime), (ulg)(pft->dwLowDateTime), + w32tm.wYear, w32tm.wMonth, w32tm.wDay, w32tm.wHour, + w32tm.wMinute, w32tm.wSecond, (isloc ? "local" : "UTC")); + } + return rval; +} +#define FTTrace(x) show_NTFileTime x +# else +#define FTTrace(x) +# endif /* DEBUG_TIME */ +/* end of DEBUG_TIME insertion */ + +# ifndef IZ_USE_INT64 +# if (defined(__GNUC__) || defined(ULONG_LONG_MAX)) + typedef long long LLONG64; + typedef unsigned long long ULLNG64; +# define IZ_USE_INT64 +# elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100)) + typedef __int64 LLONG64; + typedef unsigned __int64 ULLNG64; +# define IZ_USE_INT64 +# elif (defined(_MSC_VER) && (_MSC_VER >= 1100)) + typedef __int64 LLONG64; + typedef unsigned __int64 ULLNG64; +# define IZ_USE_INT64 +# elif (defined(__IBMC__) && (__IBMC__ >= 350)) + typedef __int64 LLONG64; + typedef unsigned __int64 ULLNG64; +# define IZ_USE_INT64 +# elif defined(HAVE_INT64) + typedef __int64 LLONG64; + typedef unsigned __int64 ULLNG64; +# define IZ_USE_INT64 +# endif +# endif + +/* scale factor and offset for conversion time_t -> FILETIME */ +#define NT_QUANTA_PER_UNIX 10000000L +#define UNIX_TIME_ZERO_HI 0x019DB1DEUL +#define UNIX_TIME_ZERO_LO 0xD53E8000UL +/* special FILETIME values for bound-checks */ +#define UNIX_TIME_UMAX_HI 0x0236485EUL +#define UNIX_TIME_UMAX_LO 0xD4A5E980UL +#define UNIX_TIME_SMIN_HI 0x0151669EUL +#define UNIX_TIME_SMIN_LO 0xD53E8000UL +#define UNIX_TIME_SMAX_HI 0x01E9FD1EUL +#define UNIX_TIME_SMAX_LO 0xD4A5E980UL +#define DOSTIME_MIN_FT_HI 0x01A8E79FUL +#define DOSTIME_MIN_FT_LO 0xE1D58000UL +/* time_t equivalent of DOSTIME_MINIMUM */ +#define UTIME_1980_JAN_01_00_00 315532800L + + +# ifndef NO_W32TIMES_IZFIX +/*********************************/ +/* Function utime2NtfsFileTime() */ /* convert Unix time_t format into the */ +/*********************************/ /* form used by SetFileTime() in NT/9x */ + +static void utime2NtfsFileTime(time_t ut, FILETIME *pft) +{ +# ifdef IZ_USE_INT64 + ULLNG64 NTtime; + + /* NT_QUANTA_PER_UNIX is small enough so that "ut * NT_QUANTA_PER_UNIX" + * cannot overflow in 64-bit signed calculation, regardless whether "ut" + * is signed or unsigned. */ + NTtime = ((LLONG64)ut * NT_QUANTA_PER_UNIX) + + ((ULLNG64)UNIX_TIME_ZERO_LO + ((ULLNG64)UNIX_TIME_ZERO_HI << 32)); + pft->dwLowDateTime = (DWORD)NTtime; + pft->dwHighDateTime = (DWORD)(NTtime >> 32); + +# else /* !IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */ + unsigned int b1, b2, carry = 0; + unsigned long r0, r1, r2, r3; + long r4; /* signed, to catch environments with signed time_t */ + + b1 = ut & 0xFFFF; + b2 = (ut >> 16) & 0xFFFF; /* if ut is over 32 bits, too bad */ + r1 = b1 * (NT_QUANTA_PER_UNIX & 0xFFFF); + r2 = b1 * (NT_QUANTA_PER_UNIX >> 16); + r3 = b2 * (NT_QUANTA_PER_UNIX & 0xFFFF); + r4 = b2 * (NT_QUANTA_PER_UNIX >> 16); + r0 = (r1 + (r2 << 16)) & 0xFFFFFFFFL; + if (r0 < r1) + carry++; + r1 = r0; + r0 = (r0 + (r3 << 16)) & 0xFFFFFFFFL; + if (r0 < r1) + carry++; + pft->dwLowDateTime = r0 + UNIX_TIME_ZERO_LO; + if (pft->dwLowDateTime < r0) + carry++; + pft->dwHighDateTime = r4 + (r2 >> 16) + (r3 >> 16) + + UNIX_TIME_ZERO_HI + carry; +# endif /* ?IZ_USE_INT64 */ + +} /* end function utime2NtfsFileTime() */ +# endif /* !NO_W32TIMES_IZFIX */ + + + +/*********************************/ +/* Function utime2VFatFileTime() */ /* convert Unix time_t format into the */ +/*********************************/ /* form used by SetFileTime() in NT/9x */ + +static void utime2VFatFileTime(time_t ut, FILETIME *pft, int clipDosMin) +{ + time_t utc = ut; + struct tm *ltm; + SYSTEMTIME w32tm; + FILETIME lft; + + /* The milliseconds field gets always initialized to 0. */ + w32tm.wMilliseconds = 0; + +# ifdef __BORLANDC__ /* Borland C++ 5.x crashes when trying to reference tm */ + if (utc < UTIME_1980_JAN_01_00_00) + utc = UTIME_1980_JAN_01_00_00; +# endif + ltm = localtime(&utc); + if (ltm == (struct tm *)NULL) + /* localtime() did not accept given utc time value; try to use + the UTC value */ + ltm = gmtime(&utc); + if (ltm == (struct tm *)NULL) { + if (ut <= (UTIME_1980_JAN_01_00_00 + 86400)) { + /* use DOSTIME_MINIMUM date instead of "early" failure dates */ + w32tm.wYear = 1980; + w32tm.wMonth = 1; + w32tm.wDay = 1; + w32tm.wHour = 0; + w32tm.wMinute = 0; + w32tm.wSecond = 0; + } else { + /* as a last resort, use the current system time */ + GetLocalTime(&w32tm); + } + } else if (clipDosMin && (ltm->tm_year < 80)) { + w32tm.wYear = 1980; + w32tm.wMonth = 1; + w32tm.wDay = 1; + w32tm.wHour = 0; + w32tm.wMinute = 0; + w32tm.wSecond = 0; + } else { + w32tm.wYear = ltm->tm_year + 1900; /* year + 1900 -> year */ + w32tm.wMonth = ltm->tm_mon + 1; /* 0..11 -> 1..12 */ + w32tm.wDay = ltm->tm_mday; /* 1..31 */ + w32tm.wHour = ltm->tm_hour; /* 0..23 */ + w32tm.wMinute = ltm->tm_min; /* 0..59 */ + w32tm.wSecond = ltm->tm_sec; /* 0..61 in ANSI C */ + } + + SystemTimeToFileTime(&w32tm, &lft); + LocalFileTimeToFileTime(&lft, pft); + +} /* end function utime2VFatFileTime() */ + + + + /* nonzero if `y' is a leap year, else zero */ +#define leap(y) (((y)%4 == 0 && (y)%100 != 0) || (y)%400 == 0) + /* number of leap years from 1970 to `y' (not including `y' itself) */ +#define nleap(y) (((y)-1969)/4 - ((y)-1901)/100 + ((y)-1601)/400) + +extern ZCONST ush ydays[]; /* defined in fileio.c */ + +# if (defined(W32_STAT_BANDAID) && !defined(NO_W32TIMES_IZFIX)) +/*********************************/ +/* Function NtfsFileTime2utime() */ +/*********************************/ + +static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut) +{ +# ifdef IZ_USE_INT64 + ULLNG64 NTtime; + + NTtime = ((ULLNG64)pft->dwLowDateTime + + ((ULLNG64)pft->dwHighDateTime << 32)); + +# ifndef TIME_T_TYPE_DOUBLE + /* underflow and overflow handling */ +# ifdef CHECK_UTIME_SIGNED_UNSIGNED + if ((time_t)0x80000000L < (time_t)0L) + { + if (NTtime < ((ULLNG64)UNIX_TIME_SMIN_LO + + ((ULLNG64)UNIX_TIME_SMIN_HI << 32))) { + *ut = (time_t)LONG_MIN; + return FALSE; + } + if (NTtime > ((ULLNG64)UNIX_TIME_SMAX_LO + + ((ULLNG64)UNIX_TIME_SMAX_HI << 32))) { + *ut = (time_t)LONG_MAX; + return FALSE; + } + } + else +# endif /* CHECK_UTIME_SIGNED_UNSIGNED */ + { + if (NTtime < ((ULLNG64)UNIX_TIME_ZERO_LO + + ((ULLNG64)UNIX_TIME_ZERO_HI << 32))) { + *ut = (time_t)0; + return FALSE; + } + if (NTtime > ((ULLNG64)UNIX_TIME_UMAX_LO + + ((ULLNG64)UNIX_TIME_UMAX_HI << 32))) { + *ut = (time_t)ULONG_MAX; + return FALSE; + } + } +# endif /* !TIME_T_TYPE_DOUBLE */ + + NTtime -= ((ULLNG64)UNIX_TIME_ZERO_LO + + ((ULLNG64)UNIX_TIME_ZERO_HI << 32)); + *ut = (time_t)(NTtime / (unsigned long)NT_QUANTA_PER_UNIX); + return TRUE; +# else /* !IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */ + time_t days; + SYSTEMTIME w32tm; + +# ifndef TIME_T_TYPE_DOUBLE + /* underflow and overflow handling */ +# ifdef CHECK_UTIME_SIGNED_UNSIGNED + if ((time_t)0x80000000L < (time_t)0L) + { + if ((pft->dwHighDateTime < UNIX_TIME_SMIN_HI) || + ((pft->dwHighDateTime == UNIX_TIME_SMIN_HI) && + (pft->dwLowDateTime < UNIX_TIME_SMIN_LO))) { + *ut = (time_t)LONG_MIN; + return FALSE; + if ((pft->dwHighDateTime > UNIX_TIME_SMAX_HI) || + ((pft->dwHighDateTime == UNIX_TIME_SMAX_HI) && + (pft->dwLowDateTime > UNIX_TIME_SMAX_LO))) { + *ut = (time_t)LONG_MAX; + return FALSE; + } + } + else +# endif /* CHECK_UTIME_SIGNED_UNSIGNED */ + { + if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) || + ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) && + (pft->dwLowDateTime < UNIX_TIME_ZERO_LO))) { + *ut = (time_t)0; + return FALSE; + } + if ((pft->dwHighDateTime > UNIX_TIME_UMAX_HI) || + ((pft->dwHighDateTime == UNIX_TIME_UMAX_HI) && + (pft->dwLowDateTime > UNIX_TIME_UMAX_LO))) { + *ut = (time_t)ULONG_MAX; + return FALSE; + } + } +# endif /* !TIME_T_TYPE_DOUBLE */ + + FileTimeToSystemTime(pft, &w32tm); + + /* set `days' to the number of days into the year */ + days = w32tm.wDay - 1 + ydays[w32tm.wMonth-1] + + (w32tm.wMonth > 2 && leap (w32tm.wYear)); + + /* now set `days' to the number of days since 1 Jan 1970 */ + days += 365 * (time_t)(w32tm.wYear - 1970) + + (time_t)(nleap(w32tm.wYear)); + + *ut = (time_t)(86400L * days + 3600L * (time_t)w32tm.wHour + + (time_t)(60 * w32tm.wMinute + w32tm.wSecond)); + return TRUE; +# endif /* ?IZ_USE_INT64 */ +} /* end function NtfsFileTime2utime() */ +# endif /* W32_STAT_BANDAID && !NO_W32TIMES_IZFIX */ + + + +# ifdef W32_STAT_BANDAID +/*********************************/ +/* Function VFatFileTime2utime() */ +/*********************************/ + +static int VFatFileTime2utime(const FILETIME *pft, time_t *ut) +{ + FILETIME lft; +# ifndef HAVE_MKTIME + WORD wDOSDate, wDOSTime; +# else + SYSTEMTIME w32tm; + struct tm ltm; +# endif + + if (!FileTimeToLocalFileTime(pft, &lft)) { + /* if pft cannot be converted to local time, set ut to current time */ + time(ut); + return FALSE; + } + FTTrace((stdout, "VFatFT2utime, feed for mktime()", 1, &lft)); +# ifndef HAVE_MKTIME + /* This version of the FILETIME-to-UNIXTIME conversion function + * uses DOS-DATE-TIME format as intermediate stage. For modification + * and access times, this is no problem. But, the extra fine resolution + * of the VFAT-stored creation time gets lost. + */ + if (!FileTimeToDosDateTime(&lft, &wDOSDate, &wDOSTime)) { + static const FILETIME dosmin_ft = + {DOSTIME_MIN_FT_LO, DOSTIME_MIN_FT_HI}; + if (CompareFileTime(&lft, &dosmin_ft) <= 0) { + /* underflow -> set to minimum DOS time */ + wDOSDate = (WORD)((DWORD)DOSTIME_MINIMUM >> 16); + wDOSTime = (WORD)DOSTIME_MINIMUM; + } else { + /* overflow -> set to maximum DOS time */ + wDOSDate = (WORD)0xFF9F; /* 2107-12-31 */ + wDOSTime = (WORD)0xBF7D; /* 23:59:58 */ + } + } + TTrace((stdout,"DosDateTime is %04u-%02u-%02u %02u:%02u:%02u\n", + (unsigned)((wDOSDate>>9)&0x7f)+1980,(unsigned)((wDOSDate>>5)&0x0f), + (unsigned)(wDOSDate&0x1f),(unsigned)((wDOSTime>>11)&0x1f), + (unsigned)((wDOSTime>>5)&0x3f),(unsigned)((wDOSTime<<1)&0x3e))); + *ut = dos_to_unix_time(((ulg)wDOSDate << 16) | (ulg)wDOSTime); + + /* a cheap error check: dos_to_unix_time() only returns an odd time + * when clipping at maximum time_t value. DOS_DATE_TIME values have + * a resolution of 2 seconds and are therefore even numbers. + */ + return (((*ut)&1) == (time_t)0); +# else /* HAVE_MKTIME */ + FileTimeToSystemTime(&lft, &w32tm); +# ifndef TIME_T_TYPE_DOUBLE + /* underflow and overflow handling */ + /* TODO: The range checks are not accurate, the actual limits may + * be off by one daylight-saving-time shift (typically 1 hour), + * depending on the current state of "is_dst". + */ +# ifdef CHECK_UTIME_SIGNED_UNSIGNED + if ((time_t)0x80000000L < (time_t)0L) + { + if ((pft->dwHighDateTime < UNIX_TIME_SMIN_HI) || + ((pft->dwHighDateTime == UNIX_TIME_SMIN_HI) && + (pft->dwLowDateTime < UNIX_TIME_SMIN_LO))) { + *ut = (time_t)LONG_MIN; + return FALSE; + if ((pft->dwHighDateTime > UNIX_TIME_SMAX_HI) || + ((pft->dwHighDateTime == UNIX_TIME_SMAX_HI) && + (pft->dwLowDateTime > UNIX_TIME_SMAX_LO))) { + *ut = (time_t)LONG_MAX; + return FALSE; + } + } + else +# endif /* CHECK_UTIME_SIGNED_UNSIGNED */ + { + if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) || + ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) && + (pft->dwLowDateTime < UNIX_TIME_ZERO_LO))) { + *ut = (time_t)0; + return FALSE; + } + if ((pft->dwHighDateTime > UNIX_TIME_UMAX_HI) || + ((pft->dwHighDateTime == UNIX_TIME_UMAX_HI) && + (pft->dwLowDateTime > UNIX_TIME_UMAX_LO))) { + *ut = (time_t)ULONG_MAX; + return FALSE; + } + } +# endif /* !TIME_T_TYPE_DOUBLE */ + ltm.tm_year = w32tm.wYear - 1900; + ltm.tm_mon = w32tm.wMonth - 1; + ltm.tm_mday = w32tm.wDay; + ltm.tm_hour = w32tm.wHour; + ltm.tm_min = w32tm.wMinute; + ltm.tm_sec = w32tm.wSecond; + ltm.tm_isdst = -1; /* let mktime determine if DST is in effect */ + *ut = mktime(<m); + + /* a cheap error check: mktime returns "(time_t)-1L" on conversion errors. + * Normally, we would have to apply a consistency check because "-1" + * could also be a valid time. But, it is quite unlikely to read back odd + * time numbers from file systems that store time stamps in DOS format. + * (The only known exception is creation time on VFAT partitions.) + */ + return (*ut != (time_t)-1L); +# endif /* ?HAVE_MKTIME */ + +} /* end function VFatFileTime2utime() */ +# endif /* W32_STAT_BANDAID */ + + + +/******************************/ +/* Function FStampIsLocTime() */ +/******************************/ + +static int FStampIsLocTime(__GPRO__ const char *path) +{ + return (NTQueryVolInfo(__G__ path) ? G.lastVolLocTim : FALSE); +} + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +static int FStampIsLocTimeW(__GPRO__ const wchar_t *pathw) +{ + return (NTQueryVolInfoW(__G__ pathw) ? G.lastVolLocTim : FALSE); +} +# endif + + + + +# ifndef NO_W32TIMES_IZFIX +# define UTIME_2_IZFILETIME(ut, pft) \ + if (fs_uses_loctime) {utime2VFatFileTime(ut, pft, TRUE);} \ + else {utime2NtfsFileTime(ut, pft);} +# else +# define UTIME_2_IZFILETIME(ut, pft) \ + utime2VFatFileTime(ut, pft, fs_uses_loctime); +# endif + + + + + + + +/****************************/ /* Get the file time in a format that */ +/* Function getNTfiletime() */ /* can be used by SetFileTime() in NT */ +/****************************/ + +static int getNTfiletime(__G__ pModFT, pAccFT, pCreFT) + __GDEF + FILETIME *pModFT; + FILETIME *pAccFT; + FILETIME *pCreFT; +{ +# ifdef USE_EF_UT_TIME + unsigned eb_izux_flg; + iztimes z_utime; /* struct for Unix-style actime & modtime, + creatime */ +# endif + int fs_uses_loctime = FStampIsLocTime(__G__ G.filename); + + /* Copy and/or convert time and date variables, if necessary; + * return a flag indicating which time stamps are available. */ +# ifdef USE_EF_UT_TIME + if (G.extra_field && +# ifdef IZ_CHECK_TZ + G.tz_is_valid && +# endif + ((eb_izux_flg = ef_scan_for_izux(G.extra_field, + G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, + &z_utime, NULL)) & EB_UT_FL_MTIME)) + { + TTrace((stderr, "getNTfiletime: Unix e.f. modif. time = %lu\n", + z_utime.mtime)); + UTIME_2_IZFILETIME(z_utime.mtime, pModFT) + if (eb_izux_flg & EB_UT_FL_ATIME) { + UTIME_2_IZFILETIME(z_utime.atime, pAccFT) + } + if (eb_izux_flg & EB_UT_FL_CTIME) { + UTIME_2_IZFILETIME(z_utime.ctime, pCreFT) + } + return (int)eb_izux_flg; + } +# endif /* USE_EF_UT_TIME */ +# ifndef NO_W32TIMES_IZFIX + if (!fs_uses_loctime) { + time_t ux_modtime; + + ux_modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime); + utime2NtfsFileTime(ux_modtime, pModFT); + } else +# endif /* NO_W32TIMES_IZFIX */ + { + FILETIME lft; + + DosDateTimeToFileTime((WORD)(G.lrec.last_mod_dos_datetime >> 16), + (WORD)(G.lrec.last_mod_dos_datetime & 0xFFFFL), + &lft); + LocalFileTimeToFileTime(&lft, pModFT); + } + *pAccFT = *pModFT; + return (EB_UT_FL_MTIME | EB_UT_FL_ATIME); + +} /* end function getNTfiletime() */ + + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + static int getNTfiletimeW(__G__ pModFT, pAccFT, pCreFT) + __GDEF + FILETIME *pModFT; + FILETIME *pAccFT; + FILETIME *pCreFT; + { +# ifdef USE_EF_UT_TIME + unsigned eb_izux_flg; + iztimes z_utime; /* struct for Unix-style actime & modtime, + creatime */ +# endif + int fs_uses_loctime = FStampIsLocTimeW(__G__ G.unipath_widefilename); + + /* Copy and/or convert time and date variables, if necessary; + * return a flag indicating which time stamps are available. */ +# ifdef USE_EF_UT_TIME + if (G.extra_field && +# ifdef IZ_CHECK_TZ + G.tz_is_valid && +# endif + ((eb_izux_flg = ef_scan_for_izux(G.extra_field, + G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, + &z_utime, NULL)) & EB_UT_FL_MTIME)) + { + TTrace((stderr, "getNTfiletime: Unix e.f. modif. time = %lu\n", + z_utime.mtime)); + UTIME_2_IZFILETIME(z_utime.mtime, pModFT) + if (eb_izux_flg & EB_UT_FL_ATIME) { + UTIME_2_IZFILETIME(z_utime.atime, pAccFT) + } + if (eb_izux_flg & EB_UT_FL_CTIME) { + UTIME_2_IZFILETIME(z_utime.ctime, pCreFT) + } + return (int)eb_izux_flg; + } +# endif /* USE_EF_UT_TIME */ +# ifndef NO_W32TIMES_IZFIX + if (!fs_uses_loctime) { + time_t ux_modtime; + + ux_modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime); + utime2NtfsFileTime(ux_modtime, pModFT); + } else +# endif /* NO_W32TIMES_IZFIX */ + { + FILETIME lft; + + DosDateTimeToFileTime((WORD)(G.lrec.last_mod_dos_datetime >> 16), + (WORD)(G.lrec.last_mod_dos_datetime & 0xFFFFL), + &lft); + LocalFileTimeToFileTime(&lft, pModFT); + } + *pAccFT = *pModFT; + return (EB_UT_FL_MTIME | EB_UT_FL_ATIME); + + } /* end function getNTfiletime() */ +# endif /* (UNICODE_SUPPORT && WIN32_WIDE) */ + + + + +/**************************/ +/* Function SetFileSize() */ +/**************************/ + +int SetFileSize(FILE *file, zusz_t filesize) +{ +# ifdef __RSXNT__ + /* RSXNT environment lacks a translation function from C file pointer + to Win32-API file handle. So, simply do nothing. */ + return 0; +# else /* !__RSXNT__ */ + /* not yet verified, if that really creates an unfragmented file + rommel@ars.de + */ + HANDLE os_fh; +# ifdef Z_UINT8_DEFINED + LARGE_INTEGER fsbuf; +# endif + + /* Win9x supports FAT file system, only; presetting file size does + not help to prevent fragmentation. */ + if (!IsWinNT()) return 0; + + /* Win32-API calls require access to the Win32 file handle. + The interface function used to retrieve the Win32 handle for + a file opened by the C rtl is non-standard and may not be + available for every Win32 compiler environment. + (see also win32/win32.c of the Zip distribution) + */ + os_fh = (HANDLE)_get_osfhandle(fileno(file)); + /* move file pointer behind the last byte of the expected file size */ +# ifdef Z_UINT8_DEFINED + fsbuf.QuadPart = filesize; + if ((SetFilePointer(os_fh, fsbuf.LowPart, &fsbuf.HighPart, FILE_BEGIN) + == 0xFFFFFFFF) && GetLastError() != NO_ERROR) +# else + if (SetFilePointer(os_fh, (ulg)filesize, 0, FILE_BEGIN) == 0xFFFFFFFF) +# endif + return -1; + /* extend/truncate file to the current position */ + if (SetEndOfFile(os_fh) == 0) { + SetFilePointer(os_fh, 0, 0, FILE_BEGIN); + return -1; + } + /* move file position pointer back to the start of the file! */ + return (SetFilePointer(os_fh, 0, 0, FILE_BEGIN) == 0xFFFFFFFF) ? -1 : 0; +# endif /* ?__RSXNT__ */ +} /* end function SetFileSize() */ + + + + +/****************************/ +/* Function close_outfile() */ +/****************************/ + +void close_outfile(__G) + __GDEF +{ + FILETIME Modft; /* File time type defined in NT, `last modified' time */ + FILETIME Accft; /* NT file time type, `last access' time */ + FILETIME Creft; /* NT file time type, `file creation' time */ + HANDLE hFile = INVALID_HANDLE_VALUE; /* File handle defined in NT */ + int gotTime; +# ifdef NTSD_EAS + uch *ebSDptr; + unsigned ebSDlen; +# endif + +/* 2013-07-08 SMS. See note below. */ +# ifdef RETRY_CREATEFILE + int cf_tries; +# endif + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + if (!G.has_win32_wide) { +# endif +# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ + char *ansi_name = (char *)alloca(strlen(G.filename) + 1); + + INTERN_TO_ISO(G.filename, ansi_name); +# define Ansi_Fname ansi_name +# else +# define Ansi_Fname G.filename +# endif + +/*--------------------------------------------------------------------------- + If symbolic links are supported, allocate storage for a symlink + control structure, put the uncompressed "data" and other required + info into it, and add the structure to the "deferred symlinks" + chain. Because we know it's a symbolic link, we shouldn't need to + worry about overflowing unsigned ints with unsigned longs. + ---------------------------------------------------------------------------*/ + +# ifdef SYMLINKS + if (G.symlnk) { + extent ucsize = (extent)G.lrec.ucsize; +# ifdef SET_SYMLINK_ATTRIBS + /* 2013-12-05 SMS. + * Note that z_uidgid is not (yet?) declared for WIN32, and must + * be an array/ponter for this usage to make sense. See + * unix/unix.c. + */ + extent attribsize = sizeof(unsigned) + + (have_uidgid_flg ? sizeof( z_uidgid) : 0); +# else + extent attribsize = 0; +# endif + /* Size of the symlink entry is the sum of: + * struct size (includes 1 (buf[1]) for target text NUL), + * system specific attribute data size (might be 0), + * target text length (only -- NUL already counted, above), + * link name length + 1 (NUL). + */ + extent slnk_entrysize = sizeof( slinkentry) + attribsize + + ucsize + strlen( G.filename) + 1; + + slinkentry *slnk_entry; + + if (slnk_entrysize < ucsize) { + Info(slide, 0x201, ((char *)slide, + "warning: symbolic link (%s) failed: mem alloc overflow\n", + FnFilter1(G.filename))); + fclose(G.outfile); + return; + } + + if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) { + Info(slide, 0x201, ((char *)slide, + "warning: symbolic link (%s) failed: no mem\n", + FnFilter1(G.filename))); + fclose(G.outfile); + return; + } + slnk_entry->next = NULL; + slnk_entry->targetlen = ucsize; + slnk_entry->attriblen = attribsize; +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + slnk_entry->wide = 0; +# endif +# ifdef SET_SYMLINK_ATTRIBS + memcpy( slnk_entry->buf, &(G.pInfo->file_attr), + sizeof( G.pInfo->file_attr)); + if (have_uidgid_flg) + memcpy( (slnk_entry->buf+ sizeof( unsigned)), z_uidgid, + sizeof( z_uidgid)); +# endif + slnk_entry->target = slnk_entry->buf + slnk_entry->attriblen; + slnk_entry->fname = slnk_entry->target + ucsize + 1; + strcpy(slnk_entry->fname, G.filename); + + /* If symlink name ends in '/', then flag as directory. */ + slnk_entry->is_dir = 0; + if (G.filename[ strlen( G.filename)- 1] == '/') + slnk_entry->is_dir = 1; + + /* move back to the start of the file to re-read the "link data" */ + rewind(G.outfile); + + if (fread(slnk_entry->target, 1, ucsize, G.outfile) != ucsize) + { + Info(slide, 0x201, ((char *)slide, + "warning: symbolic link (%s) failed\n", + FnFilter1(G.filename))); + free(slnk_entry); + fclose(G.outfile); + return; + } + slnk_entry->target[ucsize] = '\0'; + if (QCOND2) + Info(slide, 0, ((char *)slide, "-> %s ", + FnFilter1(slnk_entry->target))); + /* add this symlink record to the list of deferred symlinks */ + if (G.slink_last != NULL) + G.slink_last->next = slnk_entry; + else + G.slink_head = slnk_entry; + G.slink_last = slnk_entry; + fclose( G.outfile); + return; + } +# endif /* def SYMLINKS */ + +# ifndef __RSXNT__ +# if !(defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) + if (IsWinNT()) { + /* Truncate the file to the current position. + * This is needed to remove excess allocation in case the + * extraction has failed or stopped prematurely. */ + SetEndOfFile((HANDLE)_get_osfhandle(fileno(G.outfile))); + } +# endif /* !(defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ +# endif + + /* Close the file and then re-open it using the Win32 + * CreateFile call, so that the file can be created + * with GENERIC_WRITE access, otherwise the SetFileTime + * call will fail. */ + fclose(G.outfile); + + /* don't set the time stamp and attributes on standard output */ + if (uO.cflag) + return; + + gotTime = getNTfiletime(__G__ &Modft, &Accft, &Creft); + + /* open a handle to the file before processing extra fields; + we do this in case new security on file prevents us from updating + time stamps */ + + /* 2013-07-08 SMS. + * Some anti-virus programs may temporarily lock a newly created + * file, causing transient failures of CreateFile[AW]() when + * setting date-time (win32/win32.c:close_outfile()). + * We try up to IZ_CREATEFILE_TRY_COUNT times, at intervals of + * IZ_CREATEFILE_TRY_TIME_MS (millisecond). To disable the + * retries, define IZ_CREATEFILE_TRY_COUNT as zero. (win32/w32cfg.h). + * http://sourceforge.net/p/infozip/bugs/44/ + * http://support.microsoft.com/kb/316609 + * + * Perhaps the count or time interval should depend on the file + * size? + */ +#ifdef RETRY_CREATEFILE + for (cf_tries = IZ_CREATEFILE_TRY_COUNT; cf_tries > 0 ; cf_tries--) + { +#endif /* def RETRY_CREATEFILE */ + + hFile = CreateFileA( Ansi_Fname, + GENERIC_WRITE, FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + +#ifdef RETRY_CREATEFILE + if (hFile == INVALID_HANDLE_VALUE) + { + if (GetLastError() != ERROR_SHARING_VIOLATION) + break; /* Not a sharing error. Get out now. Otherwise: */ + Sleep( IZ_CREATEFILE_TRY_TIME_MS); /* Sleep, then retry. */ + } + else + { + break; /* Not a sharing error. (Success?) Get out now. */ + } + } +#endif /* def RETRY_CREATEFILE */ + + /* sfield@microsoft.com: set attributes before time in case we decide to + support other filetime members later. This also allows us to apply + attributes before the security is changed, which may prevent this + from succeeding otherwise. Also, since most files don't have + any interesting attributes, only change them if something other than + FILE_ATTRIBUTE_ARCHIVE appears in the attributes. This works well + as an optimization because FILE_ATTRIBUTE_ARCHIVE gets applied to the + file anyway, when it's created new. */ + if((G.pInfo->file_attr & 0x7F) & ~FILE_ATTRIBUTE_ARCHIVE) { + if (!SetFileAttributesA(Ansi_Fname, G.pInfo->file_attr & 0x7F)) + Info(slide, 1, ((char *)slide, + "\nwarning (%d): could not set file attributes (1)\n", + (int)GetLastError())); + } + + +# ifdef NTSD_EAS + /* set NTFS SD extra fields */ + if (G.extra_field && /* zipfile extra field may have extended attribs */ + FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length, + &ebSDptr, &ebSDlen)) + { +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + /* no win32_wide implies "no NT SD support", so FindSDExtraField + * will never return "success". + */ +# else /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ + int err = SetSD(__G__ Ansi_Fname, G.pInfo->file_attr, + ebSDptr, ebSDlen); + + if (err == IZ_EF_TRUNC) { + if (uO.qflag) + Info(slide, 1, ((char *)slide, "%-22s ", + FnFilter1(G.filename))); + Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD), + ebSDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), uO.qflag? "\n":"")); + } +# endif /* ? (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ + } +# endif /* NTSD_EAS */ + + /* skip restoring time stamps on user's request */ + if (uO.D_flag <= 1) { + if ( hFile == INVALID_HANDLE_VALUE ) + Info(slide, 1, ((char *)slide, + "\nCreateFile(1) error %d when trying to set file time\n", + (int)GetLastError())); + else { + if (gotTime) { + FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL; + FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL; + FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL; + + if (!SetFileTime(hFile, pCreft, pAccft, pModft)) + Info(slide, 0, ((char *)slide, + "\nSetFileTime(1) failed: %d\n", (int)GetLastError())); + } + CloseHandle(hFile); + } + } + + return; + +#undef Ansi_Fname + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + } else { + /* wide version */ + +/*--------------------------------------------------------------------------- + If symbolic links are supported, allocate storage for a symlink + control structure, put the uncompressed "data" and other required + info into it, and add the structure to the "deferred symlinks" + chain. Because we know it's a symbolic link, we shouldn't need to + worry about overflowing unsigned ints with unsigned longs. + ---------------------------------------------------------------------------*/ + +# ifdef SYMLINKS + if (G.symlnk) { + extent ucsize = (extent)G.lrec.ucsize; +# ifdef SET_SYMLINK_ATTRIBS + extent attribsize = sizeof(unsigned) + + (have_uidgid_flg ? sizeof( z_uidgid) : 0); +# else + extent attribsize = 0; +# endif + /* Note: Hard-coded assumption that sizeof( wchar_t) = 2. */ + int fname_aligner = (attribsize+ ucsize+ 1)& 1; /* Necessary? */ + + /* Size of the symlink entry is the sum of: + * struct size (includes 1 (buf[1]) for target text NUL), + * system specific attribute data size (might be 0), + * target text length (only -- NUL already counted, above), + * 1 (optional) to align wide link name, + * link name length + 1 (NUL). + */ + extent slnk_entrysize = sizeof(slinkentry) + attribsize + + ucsize + fname_aligner + + sizeof( wchar_t)* (wcslen( G.unipath_widefilename)+ 1); + + slinkentry *slnk_entry; + + if (slnk_entrysize < ucsize) { + Info(slide, 0x201, ((char *)slide, + "warning: symbolic link (%s) failed: mem alloc overflow\n", + FnFilter1(G.filename))); + fclose(G.outfile); + return; + } + + if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) { + Info(slide, 0x201, ((char *)slide, + "warning: symbolic link (%s) failed: no mem\n", + FnFilter1(G.filename))); + fclose(G.outfile); + return; + } + slnk_entry->next = NULL; + slnk_entry->targetlen = ucsize; + slnk_entry->attriblen = attribsize; + slnk_entry->wide = 1; +# ifdef SET_SYMLINK_ATTRIBS + memcpy(slnk_entry->buf, &(G.pInfo->file_attr), + sizeof(unsigned)); + if (have_uidgid_flg) + memcpy( (slnk_entry->buf + sizeof( unsigned)), z_uidgid, + sizeof( z_uidgid)); +# endif + slnk_entry->target = slnk_entry->buf + slnk_entry->attriblen; + slnk_entry->fname = slnk_entry->target + ucsize + 1 + fname_aligner; + wcscpy( (wchar_t *)slnk_entry->fname, G.unipath_widefilename); + + slnk_entry->is_dir = 0; + if (G.filename[strlen(G.filename) - 1] == '/') + slnk_entry->is_dir = 1; + + /* move back to the start of the file to re-read the "link data" */ + rewind(G.outfile); + + if (fread(slnk_entry->target, 1, ucsize, G.outfile) != ucsize) + { + Info(slide, 0x201, ((char *)slide, + "warning: symbolic link (%s) failed\n", + FnFilter1(G.filename))); + free(slnk_entry); + fclose(G.outfile); + return; + } + slnk_entry->target[ucsize] = '\0'; + if (QCOND2) + Info(slide, 0, ((char *)slide, "-> %s ", + FnFilter1(slnk_entry->target))); + /* add this symlink record to the list of deferred symlinks */ + if (G.slink_last != NULL) + G.slink_last->next = slnk_entry; + else + G.slink_head = slnk_entry; + G.slink_last = slnk_entry; + fclose( G.outfile); + return; + } +# endif /* def SYMLINKS */ + +# ifndef __RSXNT__ + if (IsWinNT()) { + /* Truncate the file to the current position. + * This is needed to remove excess allocation in case the + * extraction has failed or stopped prematurely. */ + SetEndOfFile((HANDLE)_get_osfhandle(fileno(G.outfile))); + } +# endif + + /* Close the file and then re-open it using the Win32 + * CreateFile call, so that the file can be created + * with GENERIC_WRITE access, otherwise the SetFileTime + * call will fail. */ + fclose(G.outfile); + + /* don't set the time stamp and attributes on standard output */ + if (uO.cflag) + return; + + gotTime = getNTfiletimeW(__G__ &Modft, &Accft, &Creft); + + /* open a handle to the file before processing extra fields; + we do this in case new security on file prevents us from updating + time stamps */ + + /* 2013-07-08 SMS. See note above. */ +#ifdef RETRY_CREATEFILE + for (cf_tries = IZ_CREATEFILE_TRY_COUNT; cf_tries > 0 ; cf_tries--) + { +#endif /* def RETRY_CREATEFILE */ + + hFile = CreateFileW(G.unipath_widefilename, + GENERIC_WRITE, FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + +#ifdef RETRY_CREATEFILE + if (hFile == INVALID_HANDLE_VALUE) + { + if (GetLastError() != ERROR_SHARING_VIOLATION) + break; /* Not a sharing error. Get out now. Otherwise: */ + Sleep( IZ_CREATEFILE_TRY_TIME_MS); /* Sleep, then retry. */ + } + else + { + break; /* Not a sharing error. (Success?) Get out now. */ + } + } +#endif /* def RETRY_CREATEFILE */ + + /* sfield@microsoft.com: set attributes before time in case we decide to + support other filetime members later. This also allows us to apply + attributes before the security is changed, which may prevent this + from succeeding otherwise. Also, since most files don't have + any interesting attributes, only change them if something other than + FILE_ATTRIBUTE_ARCHIVE appears in the attributes. This works well + as an optimization because FILE_ATTRIBUTE_ARCHIVE gets applied to the + file anyway, when it's created new. */ + if((G.pInfo->file_attr & 0x7F) & ~FILE_ATTRIBUTE_ARCHIVE) { + if (!SetFileAttributesW(G.unipath_widefilename, G.pInfo->file_attr & 0x7F)) + Info(slide, 1, ((char *)slide, + "\nwarning (%d): could not set file attributes (2)\n", + (int)GetLastError())); + } + +# ifdef NTSD_EAS + /* set NTFS SD extra fields */ + if (G.extra_field && /* zipfile extra field may have extended attribs */ + FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length, + &ebSDptr, &ebSDlen)) + { + int err = SetSD(__G__ G.unipath_widefilename, G.pInfo->file_attr, + ebSDptr, ebSDlen); + + if (err == IZ_EF_TRUNC) { + if (uO.qflag) + Info(slide, 1, ((char *)slide, "%-22s ", + FnFilter1(G.filename))); + Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD), + ebSDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), uO.qflag? "\n":"")); + } + } +# endif /* NTSD_EAS */ + + /* skip restoring time stamps on user's request */ + if (uO.D_flag <= 1) { + if ( hFile == INVALID_HANDLE_VALUE ) + Info(slide, 1, ((char *)slide, + "\nCreateFile(2) error %d when trying to set file time\n", + (int)GetLastError())); + else { + if (gotTime) { + FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL; + FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL; + FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL; + + if (!SetFileTime(hFile, pCreft, pAccft, pModft)) + Info(slide, 0, ((char *)slide, + "\nSetFileTime(2) failed: %d\n", (int)GetLastError())); + } + CloseHandle(hFile); + } + } + + return; + + } +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + +} /* end function close_outfile() */ + + + + +# ifdef SET_DIR_ATTRIB + +int defer_dir_attribs(__G__ pd) + __GDEF + direntry **pd; +{ + NTdirattr *d_entry; +# ifdef NTSD_EAS + uch *ebSDptr; + unsigned ebSDlen; +# endif + + /* Win9x does not support setting directory time stamps. */ + if (!IsWinNT()) { + *pd = (direntry *)NULL; + return PK_OK; + } + +# ifdef NTSD_EAS + /* set extended attributes from extra fields */ + if (G.extra_field && /* zipfile e.f. may have extended attribs */ + FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length, + &ebSDptr, &ebSDlen)) { + /* ebSDlen contains the payload size of the e.f. block, but + we store it including the e.b. header. */ + ebSDlen += EB_HEADSIZE; + } else { + /* no NTSD e.f. block -> no space needed to allocate */ + ebSDlen = 0; + } +# endif /* NTSD_EAS */ + +# ifdef NTSD_EAS +# define ASIZE1 sizeof(NTdirattr)+ ebSDlen+ strlen(G.filename) +# else /* def NTSD_EAS */ +# define ASIZE1 sizeof(NTdirattr)+ strlen(G.filename) +# endif /* def NTSD_EAS [else] */ + + d_entry = (NTdirattr *)izu_malloc(ASIZE1); + *pd = (direntry *)d_entry; + if (d_entry == (NTdirattr *)NULL) { + return PK_MEM; + } +# ifdef NTSD_EAS + if (ebSDlen > 0) + memcpy(d_entry->buf, ebSDptr, ebSDlen); + d_entry->SDlen = ebSDlen; + d_entry->fn = d_entry->buf + ebSDlen; +# else + d_entry->fn = d_entry->buf; +# endif + + strcpy(d_entry->fn, G.filename); + + d_entry->perms = G.pInfo->file_attr; + + d_entry->gotTime = (uO.D_flag <= 0 + ? getNTfiletime(__G__ &(d_entry->Modft), + &(d_entry->Accft), &(d_entry->Creft)) + : 0); + return PK_OK; +} /* end function defer_dir_attribs() */ + + + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +int defer_dir_attribsw(__G__ pdw) + __GDEF + direntryw **pdw; +{ + NTdirattrw *d_entryw; +# ifdef NTSD_EAS + uch *ebSDptr; + unsigned ebSDlen; +# endif + + /* Win9x does not support setting directory time stamps. */ + if (!IsWinNT()) { + *pdw = (direntryw *)NULL; + return PK_OK; + } + +# ifdef NTSD_EAS + /* set extended attributes from extra fields */ + if (G.extra_field && /* zipfile e.f. may have extended attribs */ + FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length, + &ebSDptr, &ebSDlen)) { + /* ebSDlen contains the payload size of the e.f. block, but + we store it including the e.b. header. */ + ebSDlen += EB_HEADSIZE; + } else { + /* no NTSD e.f. block -> no space needed to allocate */ + ebSDlen = 0; + } +# endif /* NTSD_EAS */ + +# ifdef NTSD_EAS +# define ASIZE2 sizeof(NTdirattrw)+ ebSDlen+ \ + (wcslen(G.unipath_widefilename)* sizeof(wchar_t)) +# else /* def NTSD_EAS */ +# define ASIZE2 sizeof(NTdirattrw)+ \ + (wcslen(G.unipath_widefilename)* sizeof(wchar_t)) +# endif /* def NTSD_EAS [else] */ + + d_entryw = (NTdirattrw *)izu_malloc(ASIZE2); + *pdw = (direntryw *)d_entryw; + if (d_entryw == (NTdirattrw *)NULL) { + return PK_MEM; + } +# ifdef NTSD_EAS + if (ebSDlen > 0) + memcpy(d_entryw->buf, ebSDptr, ebSDlen); + d_entryw->SDlen = ebSDlen; + d_entryw->fnw = d_entryw->buf + ebSDlen; +# else + d_entryw->fnw = d_entryw->buf; +# endif + + wcscpy(d_entryw->fnw, G.unipath_widefilename); + + d_entryw->perms = G.pInfo->file_attr; + + d_entryw->gotTime = (uO.D_flag <= 0 + ? getNTfiletimeW(__G__ &(d_entryw->Modft), + &(d_entryw->Accft), + &(d_entryw->Creft)) + : 0); + return PK_OK; +} /* end function defer_dir_attribsw() */ +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + + + + +int set_direc_attribs(__G__ d) + __GDEF + direntry *d; +{ +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + /* Win9x does not support setting directory time stamps. */ + return PK_OK; +# else /* ! (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ + int errval; + HANDLE hFile = INVALID_HANDLE_VALUE; /* File handle defined in NT */ +# ifdef __RSXNT__ + char *ansi_name; +# endif + + /* Win9x does not support setting directory time stamps. */ + if (!IsWinNT()) + return PK_OK; + + errval = PK_OK; +# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ + ansi_name = (char *)alloca(strlen(d->fn) + 1); + INTERN_TO_ISO(d->fn, ansi_name); +# define Ansi_Dirname ansi_name +# else +# define Ansi_Dirname d->fn +# endif + + /* Skip restoring directory time stamps on user' request. */ + if (uO.D_flag <= 0) { + /* Open a handle to the directory before processing extra fields; + we do this in case new security on file prevents us from updating + time stamps. + Although the WIN32 documentation recommends to use GENERIC_WRITE + access flag to create the handle for SetFileTime(), this is too + demanding for directories with the "read-only" attribute bit set. + So we use the more specific flag FILE_WRITE_ATTRIBUTES here to + request the minimum required access rights. (This problem is a + Windows bug that has been silently fixed in Windows XP SP2.) */ + hFile = CreateFileA(Ansi_Dirname, FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + } + +# ifdef NTSD_EAS + if (NtAtt(d)->SDlen > 0) { + int err; + + if (QCOND2) { + Info(slide, 1, ((char *)slide, " set attrib: %-22s ", + FnFilter1(d->fn))); + } + + /* set NTFS SD extra fields */ + err = SetSD(__G__ Ansi_Dirname, NtAtt(d)->perms, + NtAtt(d)->buf, NtAtt(d)->SDlen - EB_HEADSIZE); + if (err == IZ_EF_TRUNC) { + if (!QCOND2) + Info(slide, 1, ((char *)slide, "%-22s ", + FnFilter1(d->fn))); + Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD), + NtAtt(d)->SDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n")); + } else if (QCOND2) { + Info(slide, 0, ((char *)slide, "\n")); + } + if (errval < err) + errval = err; + } +# endif /* NTSD_EAS */ + + /* Skip restoring directory time stamps on user' request. */ + if (uO.D_flag <= 0) { + if (hFile == INVALID_HANDLE_VALUE) { + Info(slide, 1, ((char *)slide, + "warning: CreateFile(3) error %d (set file times for %s)\n", + (int)GetLastError(), FnFilter1(d->fn))); + if (!errval) + errval = PK_WARN; + } else { + if (NtAtt(d)->gotTime) { + FILETIME *pModft = (NtAtt(d)->gotTime & EB_UT_FL_MTIME) + ? &(NtAtt(d)->Modft) : NULL; + FILETIME *pAccft = (NtAtt(d)->gotTime & EB_UT_FL_ATIME) + ? &(NtAtt(d)->Accft) : NULL; + FILETIME *pCreft = (NtAtt(d)->gotTime & EB_UT_FL_CTIME) + ? &(NtAtt(d)->Creft) : NULL; + + if (!SetFileTime(hFile, pCreft, pAccft, pModft)) { + Info(slide, 0, ((char *)slide, + "warning: SetFileTime(3) for %s error %d\n", + FnFilter1(d->fn), (int)GetLastError())); + if (!errval) + errval = PK_WARN; + } + } + CloseHandle(hFile); + } + } + + return errval; + +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + +} /* end function set_direc_attribs() */ + + + + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +int set_direc_attribsw(__G__ dw) + __GDEF + direntryw *dw; +{ + int errval; + HANDLE hFile = INVALID_HANDLE_VALUE; /* File handle defined in NT */ + + /* Win9x does not support setting directory time stamps. */ + if (!IsWinNT()) + return PK_OK; + + errval = PK_OK; + + /* Skip restoring directory time stamps on user' request. */ + if (uO.D_flag <= 0) { + /* Open a handle to the directory before processing extra fields; + we do this in case new security on file prevents us from updating + time stamps. + Although the WIN32 documentation recommends to use GENERIC_WRITE + access flag to create the handle for SetFileTime(), this is too + demanding for directories with the "read-only" attribute bit set. + So we use the more specific flag FILE_WRITE_ATTRIBUTES here to + request the minimum required access rights. (This problem is a + Windows bug that has been silently fixed in Windows XP SP2.) */ + hFile = CreateFileW(dw->fnw, FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + } + +# ifdef NTSD_EAS + if (NtAtt(dw)->SDlen > 0) { + int err; + + if (QCOND2) { + char *fn = wchar_to_local_string(dw->fnw, G.unicode_escape_all); + Info(slide, 1, ((char *)slide, " set attrib: %-22s ", + FnFilter1(fn))); + izu_free(fn); + } + + /* set NTFS SD extra fields */ + err = SetSD(__G__ dw->fnw, NtAtt(dw)->perms, + NtAtt(dw)->buf, NtAtt(dw)->SDlen - EB_HEADSIZE); + if (err == IZ_EF_TRUNC) { + if (!QCOND2) { + char *fn = wchar_to_local_string(dw->fnw, G.unicode_escape_all); + Info(slide, 1, ((char *)slide, "%-22s ", + FnFilter1(fn))); + izu_free(fn); + } + Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD), + NtAtt(dw)->SDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n")); + } else if (QCOND2) { + Info(slide, 0, ((char *)slide, "\n")); + } + if (errval < err) + errval = err; + } +# endif /* NTSD_EAS */ + + /* Skip restoring directory time stamps on user' request. */ + if (uO.D_flag <= 0) { + if (hFile == INVALID_HANDLE_VALUE) { + char *fn = wchar_to_local_string(dw->fnw, G.unicode_escape_all); + Info(slide, 1, ((char *)slide, + "warning: CreateFile(4) error %d (set file times for %s)\n", + (int)GetLastError(), FnFilter1(fn))); + izu_free(fn); + if (!errval) + errval = PK_WARN; + } else { + if (NtAtt(dw)->gotTime) { + FILETIME *pModft = (NtAtt(dw)->gotTime & EB_UT_FL_MTIME) + ? &(NtAtt(dw)->Modft) : NULL; + FILETIME *pAccft = (NtAtt(dw)->gotTime & EB_UT_FL_ATIME) + ? &(NtAtt(dw)->Accft) : NULL; + FILETIME *pCreft = (NtAtt(dw)->gotTime & EB_UT_FL_CTIME) + ? &(NtAtt(dw)->Creft) : NULL; + + if (!SetFileTime(hFile, pCreft, pAccft, pModft)) { + char *fn = wchar_to_local_string(dw->fnw, + G.unicode_escape_all); + Info(slide, 0, ((char *)slide, + "warning: SetFileTime(4) for %s error %d\n", + FnFilter1(fn), (int)GetLastError())); + izu_free(fn); + if (!errval) + errval = PK_WARN; + } + } + CloseHandle(hFile); + } + } + + return errval; +} /* end function set_direc_attribsw() */ + +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + +# endif /* SET_DIR_ATTRIB */ + + + +# ifdef TIMESTAMP + +/*************************/ +/* Function stamp_file() */ +/*************************/ + +int stamp_file(__GPRO__ ZCONST char *fname, time_t modtime) +{ + FILETIME Modft; /* File time type defined in NT, `last modified' time */ + HANDLE hFile; /* File handle defined in NT */ + int errstat = 0; /* return status: 0 == "OK", -1 == "Failure" */ + int fs_uses_loctime = FStampIsLocTime(__G__ fname); + +/* 2013-07-08 SMS. See note above. */ +# ifdef RETRY_CREATEFILE + int cf_tries; +# endif + +# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ + char *ansi_name = (char *)alloca(strlen(fname) + 1); + + INTERN_TO_ISO(fname, ansi_name); +# define Ansi_Fname ansi_name +# else +# define Ansi_Fname fname +# endif + + /* open a handle to the file to prepare setting the mod-time stamp */ + +#ifdef RETRY_CREATEFILE + for (cf_tries = IZ_CREATEFILE_TRY_COUNT; cf_tries > 0 ; cf_tries--) + { +#endif /* def RETRY_CREATEFILE */ + + hFile = CreateFileA( Ansi_Fname, + GENERIC_WRITE, FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + +#ifdef RETRY_CREATEFILE + if (hFile == INVALID_HANDLE_VALUE) + { + if (GetLastError() != ERROR_SHARING_VIOLATION) + break; /* Not a sharing error. Get out now. Otherwise: */ + Sleep( IZ_CREATEFILE_TRY_TIME_MS); /* Sleep, then retry. */ + } + else + { + break; /* Not a sharing error. (Success?) Get out now. */ + } + } +#endif /* def RETRY_CREATEFILE */ + + if ( hFile == INVALID_HANDLE_VALUE ) { + errstat = -1; + } else { + /* convert time_t modtime into WIN32 native 64bit format */ + UTIME_2_IZFILETIME(modtime, &Modft) + /* set Access and Modification times of the file to modtime */ + if (!SetFileTime(hFile, NULL, &Modft, &Modft)) { + errstat = -1; + } + CloseHandle(hFile); + } + + return errstat; + +#undef Ansi_Fname +} /* end function stamp_file() */ + +# endif /* TIMESTAMP */ + + + + +/***********************/ +/* Function isfloppy() */ /* more precisely, is it removable? */ +/***********************/ + +static int isfloppy(int nDrive) /* 1 == A:, 2 == B:, etc. */ +{ + char rootPathName[4]; + + rootPathName[0] = (char)('A' + nDrive - 1); /* build the root path */ + rootPathName[1] = ':'; /* name, e.g. "A:/" */ + rootPathName[2] = '/'; + rootPathName[3] = '\0'; + + return (GetDriveTypeA(rootPathName) == DRIVE_REMOVABLE); + +} /* end function isfloppy() */ + + + + +/*****************************/ +/* Function NTQueryVolInfo() */ +/*****************************/ + +/* + * Note: 8.3 limits on filenames apply only to old-style FAT filesystems. + * More recent versions of Windows (Windows NT 3.5 / Windows 4.0) + * can support long filenames (LFN) on FAT filesystems. Check the + * filesystem maximum component length field to detect LFN support. + */ + +static int NTQueryVolInfo(__GPRO__ const char *name) +{ + /* static char lastRootPath[4] = ""; */ + /* static int lastVolOldFAT; */ + /* static int lastVolLocTim; */ + char *tmp0; + char tmp1[MAX_PATH], tmp2[MAX_PATH]; + DWORD volSerNo, maxCompLen, fileSysFlags; +# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ + char *ansi_name = (char *)alloca(strlen(name) + 1); + + INTERN_TO_ISO(name, ansi_name); + name = ansi_name; +# endif + + if ((!strncmp(name, "//", 2) || !strncmp(name, "\\\\", 2)) && + (name[2] != '\0' && name[2] != '/' && name[2] != '\\')) { + /* GetFullPathname() and GetVolumeInformation() do not work + * on UNC names. For now, we return "error". + * **FIXME**: check if UNC name is mapped to a drive letter + * and use mapped drive for volume info query. + */ + return FALSE; + } + if (isalpha((uch)name[0]) && (name[1] == ':')) + tmp0 = (char *)name; + else + { + if (!GetFullPathNameA(name, MAX_PATH, tmp1, &tmp0)) + return FALSE; + tmp0 = &tmp1[0]; + } + if (strncmp(G.lastRootPath, tmp0, 2) != 0) { + /* For speed, we skip repeated queries for the same device */ + strncpy(G.lastRootPath, tmp0, 2); /* Build the root path name, */ + G.lastRootPath[2] = '/'; /* e.g. "A:/" */ + G.lastRootPath[3] = '\0'; + + if (!GetVolumeInformationA((LPCSTR)G.lastRootPath, + (LPSTR)tmp1, (DWORD)MAX_PATH, + &volSerNo, &maxCompLen, &fileSysFlags, + (LPSTR)tmp2, (DWORD)MAX_PATH)) { + G.lastRootPath[0] = '\0'; + return FALSE; + } + + /* LFNs are available if the component length is > 12 */ + G.lastVolOldFAT = (maxCompLen <= 12); +/* G.lastVolOldFAT = !strncmp(strupr(tmp2), "FAT", 3); old version */ + + /* Volumes in (V)FAT and (OS/2) HPFS format store file timestamps in + * local time! + */ + G.lastVolLocTim = !strncmp(strupr(tmp2), "VFAT", 4) || + !strncmp(tmp2, "HPFS", 4) || + !strncmp(tmp2, "FAT", 3); + } + + return TRUE; + +} /* end function NTQueryVolInfo() */ + + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +static int NTQueryVolInfoW(__GPRO__ const wchar_t *namew) +{ + /* static char lastRootPath[4] = ""; */ + /* static int lastVolOldFAT; */ + /* static int lastVolLocTim; */ + wchar_t *tmp0w; + wchar_t tmp1w[MAX_PATH], tmp2w[MAX_PATH]; + DWORD volSerNo, maxCompLen, fileSysFlags; + + if ((!wcsncmp(namew, L"//", 2) || !wcsncmp(namew, L"\\\\", 2)) && + (namew[2] != '\0' && namew[2] != '/' && namew[2] != '\\')) { + /* GetFullPathname() and GetVolumeInformation() do not work + * on UNC names. For now, we return "error". + * **FIXME**: check if UNC name is mapped to a drive letter + * and use mapped drive for volume info query. + */ + return FALSE; + } + if (iswalpha(namew[0]) && (namew[1] == ':')) + tmp0w = (wchar_t *)namew; + else + { + if (!GetFullPathNameW(namew, MAX_PATH, tmp1w, &tmp0w)) + return FALSE; + tmp0w = &tmp1w[0]; + } + if (wcsncmp(G.lastRootPathw, tmp0w, 2) != 0) { + /* For speed, we skip repeated queries for the same device */ + wcsncpy(G.lastRootPathw, tmp0w, 2); /* Build the root path name, */ + G.lastRootPathw[2] = '/'; /* e.g. "A:/" */ + G.lastRootPathw[3] = '\0'; + + if (!GetVolumeInformationW(G.lastRootPathw, + tmp1w, (DWORD)MAX_PATH, + &volSerNo, &maxCompLen, &fileSysFlags, + tmp2w, (DWORD)MAX_PATH)) { + G.lastRootPathw[0] = '\0'; + return FALSE; + } + + /* LFNs are available if the component length is > 12 */ + G.lastVolOldFAT = (maxCompLen <= 12); +/* G.lastVolOldFAT = !strncmp(strupr(tmp2), "FAT", 3); old version */ + + /* Volumes in (V)FAT and (OS/2) HPFS format store file timestamps in + * local time! + */ + G.lastVolLocTim = !wcsncmp(_wcsupr(tmp2w), L"VFAT", 4) || + !wcsncmp(tmp2w, L"HPFS", 4) || + !wcsncmp(tmp2w, L"FAT", 3); + } + + return TRUE; + +} /* end function NTQueryVolInfoW() */ +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + + + + +/*****************************/ +/* Function IsVolumeOldFAT() */ +/*****************************/ + +static int IsVolumeOldFAT(__GPRO__ const char *name) +{ + return (NTQueryVolInfo(__G__ name) ? G.lastVolOldFAT : FALSE); +} + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +static int IsVolumeOldFATw(__GPRO__ const wchar_t *namew) +{ + return (NTQueryVolInfoW(__G__ namew) ? G.lastVolOldFAT : FALSE); +} +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + + + + +# ifndef SFX + +/************************/ +/* Function do_wild() */ /* identical to OS/2 version */ +/************************/ + +char *do_wild(__G__ wildspec) + __GDEF + ZCONST char *wildspec; /* only used first time on a given dir */ +{ +/* these statics are now declared in SYSTEM_SPECIFIC_GLOBALS in w32cfg.h: + static zDIR *wild_dir = NULL; + static ZCONST char *wildname; + static char *dirname, matchname[FILNAMSIZ]; + static int notfirstcall=FALSE, have_dirname, dirnamelen; +*/ + char *fnamestart; + struct zdirent *file; + + /* Even when we're just returning wildspec, we *always* do so in + * matchname[]--calling routine is allowed to append four characters + * to the returned string, and wildspec may be a pointer to argv[]. + */ + if (!G.notfirstcall) { /* first call: must initialize everything */ + G.notfirstcall = TRUE; + + if (!iswild(wildspec)) { + strncpy(G.matchname, wildspec, FILNAMSIZ); + G.matchname[FILNAMSIZ-1] = '\0'; + G.have_dirname = FALSE; + G.wild_dir = NULL; + return G.matchname; + } + + /* Break the wildspec into a directory part and a wildcard filename. */ + /* 2014-02-14 SMS. Added test for "\". */ + if ((G.wildname = MBSRCHR(wildspec, '/')) == (ZCONST char *)NULL && + (G.wildname = MBSRCHR(wildspec, '\\')) == (ZCONST char *)NULL && + (G.wildname = MBSRCHR(wildspec, ':')) == (ZCONST char *)NULL) { + G.dirname = "."; + G.dirnamelen = 1; + G.have_dirname = FALSE; + G.wildname = wildspec; + } else { + ++G.wildname; /* Point at char after last '/', '\', or ':'. */ + G.dirnamelen = G.wildname - wildspec; + if ((G.dirname = (char *)izu_malloc(G.dirnamelen+1)) == NULL) { + Info(slide, 1, ((char *)slide, + "warning: cannot allocate wildcard buffers\n")); + strncpy(G.matchname, wildspec, FILNAMSIZ); + G.matchname[FILNAMSIZ-1] = '\0'; + return G.matchname; /* but maybe filespec was not a wildcard */ + } + strncpy(G.dirname, wildspec, G.dirnamelen); + G.dirname[G.dirnamelen] = '\0'; /* terminate for strcpy below */ + G.have_dirname = TRUE; + } + Trace((stderr, "do_wild: dirname = [%s]\n", FnFilter1(G.dirname))); + + if ((G.wild_dir = (zvoid *)Opendir(G.dirname)) != NULL) { + if (G.have_dirname) { + strcpy(G.matchname, G.dirname); + fnamestart = G.matchname + G.dirnamelen; + } else + fnamestart = G.matchname; + while ((file = Readdir((zDIR *)G.wild_dir)) != NULL) { + Trace((stderr, "do_wild: Readdir returns %s\n", + FnFilter1(file->d_name))); + strcpy(fnamestart, file->d_name); + if (MBSRCHR(fnamestart, '.') == (char *)NULL) + strcat(fnamestart, "."); + if (match(fnamestart, G.wildname, TRUE WISEP) && + /* skip "." and ".." directory entries */ + strcmp(fnamestart, ".") && strcmp(fnamestart, "..")) { + Trace((stderr, "do_wild: match() succeeds\n")); + /* remove trailing dot */ + fnamestart = plastchar(fnamestart, strlen(fnamestart)); + if (*fnamestart == '.') + *fnamestart = '\0'; + return G.matchname; + } + } + /* if we get to here directory is exhausted, so close it */ + Closedir((zDIR *)G.wild_dir); + G.wild_dir = NULL; + } + Trace((stderr, "do_wild: Opendir(%s) returns NULL\n", + FnFilter1(G.dirname))); + + /* return the raw wildspec in case that works (e.g., directory not + * searchable, but filespec was not wild and file is readable) */ + strncpy(G.matchname, wildspec, FILNAMSIZ); + G.matchname[FILNAMSIZ-1] = '\0'; + return G.matchname; + } + + /* last time through, might have failed opendir but returned raw wildspec */ + if (G.wild_dir == NULL) { + G.notfirstcall = FALSE; /* reset for new wildspec */ + if (G.have_dirname) + izu_free(G.dirname); + return (char *)NULL; + } + + /* If we've gotten this far, we've read and matched at least one entry + * successfully (in a previous call), so dirname has been copied into + * matchname already. + */ + if (G.have_dirname) { + /* strcpy(G.matchname, G.dirname); */ + fnamestart = G.matchname + G.dirnamelen; + } else + fnamestart = G.matchname; + while ((file = Readdir((zDIR *)G.wild_dir)) != NULL) { + Trace((stderr, "do_wild: readdir returns %s\n", + FnFilter1(file->d_name))); + strcpy(fnamestart, file->d_name); + if (MBSRCHR(fnamestart, '.') == (char *)NULL) + strcat(fnamestart, "."); + if (match(fnamestart, G.wildname, TRUE WISEP)) { + Trace((stderr, "do_wild: match() succeeds\n")); + /* remove trailing dot */ + fnamestart = plastchar(fnamestart, strlen(fnamestart)); + if (*fnamestart == '.') + *fnamestart = '\0'; + return G.matchname; + } + } + + Closedir((zDIR *)G.wild_dir); /* at least one entry read; nothing left */ + G.wild_dir = NULL; + G.notfirstcall = FALSE; /* reset for new wildspec */ + if (G.have_dirname) + izu_free(G.dirname); + return (char *)NULL; + +} /* end function do_wild() */ + +# endif /* !SFX */ + + + +/**********************/ +/* Function mapattr() */ +/**********************/ + +/* Identical to MS-DOS, OS/2 versions. However, NT has a lot of extra + * permission stuff, so this function should probably be extended in the + * future. */ + +int mapattr(__G) + __GDEF +{ + /* set archive bit for file entries (file is not backed up): */ + G.pInfo->file_attr = ((unsigned)G.crec.external_file_attributes | + (G.crec.external_file_attributes & FILE_ATTRIBUTE_DIRECTORY ? + 0 : FILE_ATTRIBUTE_ARCHIVE)) & 0xff; + +# ifdef SYMLINKS + if (SYMLINK_HOST( G.pInfo->hostnum)) + { + unsigned int uxattr; + + uxattr = (G.crec.external_file_attributes >> 16); /* drwxrwxrwx */ + + G.pInfo->symlink = S_ISLNK( uxattr); + } +# endif /* def SYMLINKS */ + + return 0; + +} /* end function mapattr() */ + + + + +/************************/ +/* Function mapname() */ +/************************/ + +int mapname(__G__ renamed) + __GDEF + int renamed; +/* + * returns: + * MPN_OK - no problem detected + * MPN_INF_TRUNC - caution (truncated filename) + * MPN_INF_SKIP - info "skip entry" (dir doesn't exist) + * MPN_ERR_SKIP - error -> skip entry + * MPN_ERR_TOOLONG - error -> path is too long + * MPN_NOMEM - error (memory allocation failed) -> skip entry + * [also MPN_VOL_LABEL, MPN_CREATED_DIR] + */ +{ + char pathcomp[FILNAMSIZ]; /* path-component buffer */ +# ifdef SYMLINKS + char pathcopy[FILNAMSIZ]; /* Copy of path we can alter. */ +# endif + char *pp, *cp=NULL; /* character pointers */ + char *lastsemi = NULL; /* pointer to last semi-colon in pathcomp */ +# ifdef ACORN_FTYPE_NFS + char *lastcomma=(char *)NULL; /* pointer to last comma in pathcomp */ + RO_extra_block *ef_spark; /* pointer Acorn FTYPE ef block */ +# endif + int killed_ddot = FALSE; /* is set when skipping "../" pathcomp */ + int error; + register unsigned workch; /* hold the character being tested */ + +/*--------------------------------------------------------------------------- + Initialize various pointers and counters and stuff. + ---------------------------------------------------------------------------*/ + + /* can create path as long as not just freshening, or if user told us */ + G.create_dirs = (!uO.fflag || renamed); + + G.created_dir = FALSE; /* not yet */ + G.renamed_fullpath = FALSE; + G.fnlen = strlen(G.filename); + + if (renamed) { + cp = G.filename; /* Point to start of renamed name. */ + if (*cp) do { + if (*cp == '\\') /* Convert backslashes to slashes. */ + *cp = '/'; + } while (*PREINCSTR(cp)); + cp = G.filename; + /* use temporary rootpath if user gave full pathname */ + if (G.filename[0] == '/') { + G.renamed_fullpath = TRUE; + pathcomp[0] = '/'; /* Copy the '/', and NUL-terminate. */ + pathcomp[1] = '\0'; + ++cp; + } else if (isalpha((uch)G.filename[0]) && G.filename[1] == ':') { + G.renamed_fullpath = TRUE; + pp = pathcomp; + *pp++ = *cp++; /* Copy the "d:" (+ '/', possibly). */ + *pp++ = *cp++; + if (*cp == '/') + *pp++ = *cp++; /* Otherwise add "./"? */ + *pp = '\0'; + } + } + + /* pathcomp is ignored unless renamed_fullpath is TRUE: */ + if ((error = checkdir(__G__ pathcomp, INIT)) != 0) /* init path buffer */ + return error; /* ...unless no mem or vol label on hard disk */ + + *pathcomp = '\0'; /* initialize translation buffer */ + pp = pathcomp; /* point to translation buffer */ + if (!renamed) { /* cp already set if renamed */ + cp = G.jdir_filename; /* Start at beginning of non-junked path. */ + } + +# ifdef SYMLINKS + /* If a symlink with a trailing "/", then use a copy without the "/". */ + if (G.pInfo->symlink) + { + size_t lenm1; + + lenm1 = strlen( cp)- 1; + if (cp[ lenm1] == '/') + { + strncpy( pathcopy, cp, lenm1); + pathcopy[ lenm1] = '\0'; + cp = pathcopy; + } + } +# endif /* def SYMLINKS */ + +/*--------------------------------------------------------------------------- + Begin main loop through characters in filename. + ---------------------------------------------------------------------------*/ + + for (; (workch = (uch)*cp) != 0; INCSTR(cp)) { + + switch (workch) { + case '/': /* Can assume -j flag not given. */ + *pp = '\0'; + maskDOSdevice(__G__ pathcomp); + if (strcmp(pathcomp, ".") == 0) { + /* Don't bother appending "./" to the path. */ + *pathcomp = '\0'; + } else if (!uO.ddotflag && strcmp(pathcomp, "..") == 0) { + /* "../" dir traversal detected. Skip over it. */ + *pathcomp = '\0'; + killed_ddot = TRUE; /* Set "show message" flag. */ + } + /* When path component is not empty, append it now. */ + if (*pathcomp != '\0' && + ((error = checkdir(__G__ pathcomp, APPEND_DIR)) + & MPN_MASK) > MPN_INF_TRUNC) + return error; + pp = pathcomp; /* Reset conversion buffer for next piece. */ + lastsemi = (char *)NULL; /* Leave dir semi-colons alone. */ + break; + + case ':': /* drive spec not stored, so no colon allowed */ + case '\\': /* '\\' may come as normal filename char (not */ + case '<': /* dir sep char!) from unix-like file system */ + case '>': /* no redirection symbols allowed either */ + case '|': /* no pipe signs allowed */ + case '"': /* no double quotes allowed */ + case '?': /* no wildcards allowed */ + case '*': + *pp++ = '_'; /* these rules apply equally to FAT and NTFS */ + break; + case ';': /* start of VMS version? */ + lastsemi = pp; /* remove VMS version later... */ + *pp++ = ';'; /* but keep semicolon for now */ + break; + +# ifdef ACORN_FTYPE_NFS + case ',': /* NFS filetype extension */ + lastcomma = pp; + *pp++ = ','; /* keep for now; may need to remove */ + break; /* later, if requested */ +# endif + + case ' ': /* keep spaces unless specifically */ + /* NT cannot create filenames with spaces on FAT volumes */ + if (uO.sflag || IsVolumeOldFAT(__G__ G.filename)) + *pp++ = '_'; + else + *pp++ = ' '; + break; + + default: + /* allow European characters in filenames: */ + if (isprint(workch) || workch >= 127) +# ifdef _MBCS + { + memcpy(pp, cp, CLEN(cp)); + INCSTR(pp); + } +# else + *pp++ = (char)workch; +# endif + } /* end switch */ + + } /* end while loop */ + + /* Show warning when stripping insecure "parent dir" path components */ + if (killed_ddot && QCOND2) { + Info(slide, 0, ((char *)slide, + "warning: skipped \"../\" path component(s) (1) in %s\n", + FnFilter1(G.filename))); + if (!(error & ~MPN_MASK)) + error = (error & MPN_MASK) | PK_WARN; + } + +/*--------------------------------------------------------------------------- + Report if directory was created (and no file to create: filename ended + in '/'), check name to be sure it exists, and combine path and name be- + fore exiting. + ---------------------------------------------------------------------------*/ + + if ((lastchar(G.filename, G.fnlen) == '/') +# ifdef SYMLINKS + /* Process a symlink as a file, even if it looks like a directory. + * (Which a Windows directory symlink might do.) + */ + && !G.pInfo->symlink +# endif /* def SYMLINKS */ + ) + { +# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ + char *ansi_name = (char *)alloca(strlen(G.filename) + 1); + + INTERN_TO_ISO(G.filename, ansi_name); +# define Ansi_Fname ansi_name +# else +# define Ansi_Fname G.filename +# endif + checkdir(__G__ G.filename, GETPATH); + if (G.created_dir) { + if (QCOND2) { + Info(slide, 0, ((char *)slide, " creating: %-22s\n", + FnFilter1(G.filename))); + } + + /* set file attributes: + The default for newly created directories is "DIR attribute + flags set", so there is no need to change attributes unless + one of the DOS style attribute flags is set. The readonly + attribute need not be masked, since it does not prevent + modifications in the new directory. */ + if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) { + if (!SetFileAttributesA(Ansi_Fname, G.pInfo->file_attr & 0x7F)) + Info(slide, 1, ((char *)slide, + "\nwarning (%d): could not set file attributes (3) for %s\n", + (int)GetLastError(), FnFilter1(G.filename))); + } + + /* set dir time (note trailing '/') */ + return (error & ~MPN_MASK) | MPN_CREATED_DIR; + } else if (IS_OVERWRT_ALL) { + /* overwrite attributes of existing directory on user's request */ + + /* set file attributes: */ + if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) { + if (!SetFileAttributesA(Ansi_Fname, G.pInfo->file_attr & 0x7F)) + Info(slide, 1, ((char *)slide, + "\nwarning (%d): could not set file attributes (4) for %s\n", + (int)GetLastError(), FnFilter1(G.filename))); + } + } + /* dir existed already; don't look for data to extract */ + return (error & ~MPN_MASK) | MPN_INF_SKIP; + } + + *pp = '\0'; /* done with pathcomp: terminate it */ + + /* If not saving them, remove a VMS version number (ending: ";###"). */ + if (lastsemi && + ((uO.V_flag < 0) || ((uO.V_flag == 0) && (G.pInfo->hostnum == VMS_)))) { + pp = lastsemi + 1; /* semi-colon was kept: expect #'s after */ + if (*pp != '\0') { /* At least one digit is required. */ + while (isdigit((uch)(*pp))) + ++pp; + if (*pp == '\0') /* only digits between ';' and end: nuke */ + *lastsemi = '\0'; + } + } + +# ifdef ACORN_FTYPE_NFS + /* translate Acorn filetype information if asked to do so */ + if (uO.acorn_nfs_ext && + (ef_spark = (RO_extra_block *) + getRISCOSexfield(G.extra_field, G.lrec.extra_field_length)) + != (RO_extra_block *)NULL) + { + /* file *must* have a RISC OS extra field */ + long ft = (long)makelong(ef_spark->loadaddr); + /*32-bit*/ + if (lastcomma) { + pp = lastcomma + 1; + while (isxdigit((uch)(*pp))) ++pp; + if (pp == lastcomma+4 && *pp == '\0') *lastcomma='\0'; /* nuke */ + } + if ((ft & 1<<31)==0) ft=0x000FFD00; + sprintf(pathcomp+strlen(pathcomp), ",%03x", (int)(ft>>8) & 0xFFF); + } +# endif /* ACORN_FTYPE_NFS */ + + maskDOSdevice(__G__ pathcomp); + + if (*pathcomp == '\0') { + Info(slide, 1, ((char *)slide, "mapname(1): conversion of %s failed\n", + FnFilter1(G.filename))); + return (error & ~MPN_MASK) | MPN_ERR_SKIP; + } + + checkdir(__G__ pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */ + checkdir(__G__ G.filename, GETPATH); + + if (G.pInfo->vollabel) { /* set the volume label now */ + char drive[4] = "?:\\"; +# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ + char *ansi_name = (char *)alloca(strlen(G.filename) + 1); + INTERN_TO_ISO(G.filename, ansi_name); +# define Ansi_Fname ansi_name +# else +# define Ansi_Fname G.filename +# endif + + /* Insert the drive letter into the drive string. E.g. "b:\". */ + drive[0] = (char)(('a'- 1)+ G.nLabelDrive); + if (QCOND2) + Info(slide, 0, ((char *)slide, "labeling %s %-22s\n", drive, + FnFilter1(G.filename))); + if (!SetVolumeLabelA(drive, Ansi_Fname)) { + Info(slide, 1, ((char *)slide, + "mapname(1): error setting volume label\n")); + return (error & ~MPN_MASK) | MPN_ERR_SKIP; + } + /* success: skip the "extraction" quietly */ + return (error & ~MPN_MASK) | MPN_INF_SKIP; +#undef Ansi_Fname + } + Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n", + FnFilter1(G.filename), error)); + return error; + +} /* end function mapname() */ + + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + + +int mapnamew(__G__ renamed) + __GDEF + int renamed; +/* + * returns: + * MPN_OK - no problem detected + * MPN_INF_TRUNC - caution (truncated filename) + * MPN_INF_SKIP - info "skip entry" (dir doesn't exist) + * MPN_ERR_SKIP - error -> skip entry + * MPN_ERR_TOOLONG - error -> path is too long + * MPN_NOMEM - error (memory allocation failed) -> skip entry + * [also MPN_VOL_LABEL, MPN_CREATED_DIR] + */ +{ + wchar_t pathcompw[FILNAMSIZ]; /* path-component buffer */ +# ifdef SYMLINKS + wchar_t pathcopy[FILNAMSIZ]; +# endif /* def SYMLINKS */ + wchar_t *ppw, *cpw=NULL; /* character pointers */ + wchar_t *lastsemiw = NULL; /* pointer to last semi-colon in pathcomp */ + int killed_ddot = FALSE; /* is set when skipping "../" pathcomp */ + int error; + register wchar_t workchw; /* hold the character being tested */ + +/*--------------------------------------------------------------------------- + Initialize various pointers and counters and stuff. + ---------------------------------------------------------------------------*/ + + /* can create path as long as not just freshening, or if user told us */ + G.create_dirs = (!uO.fflag || renamed); + + G.created_dir = FALSE; /* not yet */ + G.renamed_fullpath = FALSE; + G.fnlen = wcslen(G.unipath_widefilename); + + if (renamed) { + cpw = G.unipath_widefilename; /* Point to start of renamed name. */ + if (*cpw) do { + if (*cpw == '\\') /* Convert backslashes to slashes. */ + *cpw = '/'; + } while (*(++cpw)); + cpw = G.unipath_widefilename; + /* use temporary rootpath if user gave full pathname */ + if (G.unipath_widefilename[0] == '/') { + G.renamed_fullpath = TRUE; + pathcompw[0] = '/'; /* Copy the '/', and NUL-terminate. */ + pathcompw[1] = '\0'; + ++cpw; + } else if (iswalpha(G.unipath_widefilename[0]) && G.unipath_widefilename[1] == ':') { + G.renamed_fullpath = TRUE; + ppw = pathcompw; + *ppw++ = *cpw++; /* Copy the "d:" (+ '/', possibly). */ + *ppw++ = *cpw++; + if (*cpw == '/') + *ppw++ = *cpw++; /* Otherwise add "./"? */ + *ppw = '\0'; + } + } + + /* pathcomp is ignored unless renamed_fullpath is TRUE: */ + if ((error = checkdirw(__G__ pathcompw, INIT)) != 0) /* init path buffer */ + return error; /* ...unless no mem or vol label on hard disk */ + + *pathcompw = '\0'; /* initialize translation buffer */ + ppw = pathcompw; /* point to translation buffer */ + if (!renamed) { /* cp already set if renamed */ + cpw = G.unipath_jdir_widefilename; /* Beginning of non-junked path. */ + } + +# ifdef SYMLINKS + /* If a symlink with a trailing "/", then use a copy without the "/". */ + if (G.pInfo->symlink) + { + size_t lenm1; + + lenm1 = wcslen( cpw)- 1; + if (cpw[ lenm1] == L'/') + { + wcsncpy( pathcopy, cpw, lenm1); + pathcopy[ lenm1] = L'\0'; + cpw = pathcopy; + } + } +# endif /* def SYMLINKS */ + +/*--------------------------------------------------------------------------- + Begin main loop through characters in filename. + ---------------------------------------------------------------------------*/ + + for (; (workchw = *cpw) != 0; cpw++) { + + switch (workchw) { + case '/': /* Can assume -j flag not given. */ + *ppw = '\0'; + maskDOSdevicew(__G__ pathcompw); + if (wcscmp(pathcompw, L".") == 0) { + /* Don't bother appending "./" to the path. */ + *pathcompw = '\0'; + } else if (!uO.ddotflag && wcscmp(pathcompw, L"..") == 0) { + /* "../" dir traversal detected. Skip over it. */ + *pathcompw = '\0'; + killed_ddot = TRUE; /* Set "show message" flag. */ + } + /* When path component is not empty, append it now. */ + if (*pathcompw != '\0' && + ((error = checkdirw(__G__ pathcompw, APPEND_DIR)) + & MPN_MASK) > MPN_INF_TRUNC) + return error; + ppw = pathcompw; /* Reset conversion buffer for next piece. */ + lastsemiw = (wchar_t *)NULL; /* Leave dir semi-colons alone. */ + break; + + case ':': /* drive spec not stored, so no colon allowed */ + case '\\': /* '\\' may come as normal filename char (not */ + case '<': /* dir sep char!) from unix-like file system */ + case '>': /* no redirection symbols allowed either */ + case '|': /* no pipe signs allowed */ + case '"': /* no double quotes allowed */ + case '?': /* no wildcards allowed */ + case '*': + *ppw++ = '_'; /* these rules apply equally to FAT and NTFS */ + break; + case ';': /* start of VMS version? */ + lastsemiw = ppw; /* remove VMS version later... */ + *ppw++ = ';'; /* but keep semicolon for now */ + break; + + + case ' ': /* keep spaces unless specifically */ + /* NT cannot create filenames with spaces on FAT volumes */ + if (uO.sflag || IsVolumeOldFATw(__G__ G.unipath_widefilename)) + *ppw++ = '_'; + else + *ppw++ = ' '; + break; + + default: + /* allow European characters in filenames: */ + if (iswprint(workchw) || workchw >= 127) + *ppw++ = workchw; + } /* end switch */ + + } /* end while loop */ + + /* Show warning when stripping insecure "parent dir" path components */ + /* For now use standard path for output messages */ + if (killed_ddot && QCOND2) { + Info(slide, 0, ((char *)slide, + "warning: skipped \"../\" path component(s) (2) in %s\n", + FnFilter1(G.filename))); + if (!(error & ~MPN_MASK)) + error = (error & MPN_MASK) | PK_WARN; + } + +/*--------------------------------------------------------------------------- + Report if directory was created (and no file to create: filename ended + in '/'), check name to be sure it exists, and combine path and name be- + fore exiting. + ---------------------------------------------------------------------------*/ + + if ((G.unipath_widefilename[wcslen(G.unipath_widefilename) - 1] == '/') +# ifdef SYMLINKS + /* Process a symlink as a file, even if it looks like a directory. + * (Which a Windows directory symlink might do.) + */ + && !G.pInfo->symlink +# endif /* def SYMLINKS */ + ) + { + checkdirw(__G__ G.unipath_widefilename, GETPATH); + if (G.created_dir) { + if (QCOND2) { + Info(slide, 0, ((char *)slide, " creating: %-22s\n", + FnFilter1(G.filename))); + } + + /* set file attributes: + The default for newly created directories is "DIR attribute + flags set", so there is no need to change attributes unless + one of the DOS style attribute flags is set. The readonly + attribute need not be masked, since it does not prevent + modifications in the new directory. */ + if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) { + if (!SetFileAttributesW(G.unipath_widefilename, G.pInfo->file_attr & 0x7F)) + Info(slide, 1, ((char *)slide, + "\nwarning (%d): could not set file attributes (5) for %s\n", + (int)GetLastError(), FnFilter1(G.filename))); + } + + /* set dir time (note trailing '/') */ + return (error & ~MPN_MASK) | MPN_CREATED_DIR; + } else if (IS_OVERWRT_ALL) { + /* overwrite attributes of existing directory on user's request */ + + /* set file attributes: */ + if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) { + if (!SetFileAttributesW(G.unipath_widefilename, G.pInfo->file_attr & 0x7F)) + Info(slide, 1, ((char *)slide, + "\nwarning (%d): could not set file attributes (6) for %s\n", + (int)GetLastError(), FnFilter1(G.filename))); + } + } + /* dir existed already; don't look for data to extract */ + return (error & ~MPN_MASK) | MPN_INF_SKIP; + } + + *ppw = '\0'; /* done with pathcomp: terminate it */ + + /* If not saving them, remove a VMS version number (ending: ";###"). */ + if (lastsemiw && + ((uO.V_flag < 0) || ((uO.V_flag == 0) && (G.pInfo->hostnum == VMS_)))) { + ppw = lastsemiw + 1; /* semi-colon was kept: expect #'s after */ + if (*ppw != '\0') { /* At least one digit is required. */ + while (iswdigit(*ppw)) + ++ppw; + if (*ppw == '\0') /* only digits between ';' and end: nuke */ + *lastsemiw = '\0'; + } + } + + maskDOSdevicew(__G__ pathcompw); + + if (*pathcompw == '\0') { + Info(slide, 1, ((char *)slide, "mapname(2): conversion of %s failed\n", + FnFilter1(G.filename))); + return (error & ~MPN_MASK) | MPN_ERR_SKIP; + } + + checkdirw(__G__ pathcompw, APPEND_NAME); /* returns 1 if truncated: care? */ + +# ifdef DYNAMIC_WIDE_NAME + if ((unsigned int)(G.endFATw- G.buildpathFATw) > + wcslen( G.unipath_widefilename)) + { + /* 2013-03-18 SMS. + * Need more storage for the constructed name. + * It might make more sense to allocate FILNAMSIZ* sizeof( wchar_t) + * in the first place, but utf8_to_wchar_string() allocates the + * exact size of the leaf name. + */ + if ((G.unipath_widefilename = izu_realloc( G.unipath_widefilename, + ((G.endFATw- G.buildpathFATw+ 1)* sizeof( wchar_t)))) == NULL) + { + return MPN_NOMEM; + } + } +# endif /* def DYNAMIC_WIDE_NAME */ + /* Get the constructed name. */ + checkdirw(__G__ G.unipath_widefilename, GETPATH); + + if (G.pInfo->vollabel) { /* set the volume label now */ + char drive[4] = "?:\\"; + wchar_t drivew[4] = L"?:\\"; + + /* Insert the drive letter into the drive string. E.g. "b:\". */ + drive[0] = (char)(('a'- 1)+ G.nLabelDrive); + drivew[0] = (wchar_t)(('a'- 1)+ G.nLabelDrive); + if (QCOND2) + Info(slide, 0, ((char *)slide, "labeling %s %-22s\n", drive, + FnFilter1(G.filename))); + if (!SetVolumeLabelW(drivew, G.unipath_widefilename)) { + Info(slide, 1, ((char *)slide, + "mapname(2): error setting volume label\n")); + return (error & ~MPN_MASK) | MPN_ERR_SKIP; + } + /* success: skip the "extraction" quietly */ + return (error & ~MPN_MASK) | MPN_INF_SKIP; + } + Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n", + FnFilter1(G.filename), error)); + return error; + +} /* end function mapnamew() */ + + +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + + + + +/****************************/ +/* Function maskDOSdevice() */ +/****************************/ + +static void maskDOSdevice(__G__ pathcomp) + __GDEF + char *pathcomp; +{ +/*--------------------------------------------------------------------------- + Put an underscore in front of the file name if the file name is a + DOS/WINDOWS device name like CON.*, AUX.*, PRN.*, etc. Trying to + extract such a file would fail at best and wedge us at worst. + ---------------------------------------------------------------------------*/ +# if !defined(S_IFCHR) && defined(_S_IFCHR) +# define S_IFCHR _S_IFCHR +# endif +# if !defined(S_ISCHR) +# if defined(_S_ISCHR) +# define S_ISCHR(m) _S_ISCHR(m) +# elif defined(S_IFCHR) +# define S_ISCHR(m) ((m) & S_IFCHR) +# endif +# endif + +# ifdef DEBUG + if (zstat(pathcomp, &G.statbuf) == 0) { + Trace((stderr, + "maskDOSdevice() stat(\"%s\", buf) st_mode result: %X, %o\n", + FnFilter1(pathcomp), G.statbuf.st_mode, G.statbuf.st_mode)); + } else { + Trace((stderr, "maskDOSdevice() stat(\"%s\", buf) failed\n", + FnFilter1(pathcomp))); + } +# endif + if (zstat(pathcomp, &G.statbuf) == 0 && S_ISCHR(G.statbuf.st_mode)) { + extent i; + + /* pathcomp contains a name of a DOS character device (builtin or + * installed device driver). + * Prepend a '_' to allow creation of the item in the file system. + */ + for (i = strlen(pathcomp) + 1; i > 0; --i) + pathcomp[i] = pathcomp[i - 1]; + pathcomp[0] = '_'; + } +} /* end function maskDOSdevice() */ + + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + +static void maskDOSdevicew(__G__ pathcompw) + __GDEF + wchar_t *pathcompw; +{ +/*--------------------------------------------------------------------------- + Put an underscore in front of the file name if the file name is a + DOS/WINDOWS device name like CON.*, AUX.*, PRN.*, etc. Trying to + extract such a file would fail at best and wedge us at worst. + ---------------------------------------------------------------------------*/ +# if !defined(S_IFCHR) && defined(_S_IFCHR) +# define S_IFCHR _S_IFCHR +# endif +# if !defined(S_ISCHR) +# if defined(_S_ISCHR) +# define S_ISCHR(m) _S_ISCHR(m) +# elif defined(S_IFCHR) +# define S_ISCHR(m) ((m) & S_IFCHR) +# endif +# endif + + if (zstatw(pathcompw, &G.statbuf) == 0 && S_ISCHR(G.statbuf.st_mode)) { + extent i; + + /* pathcomp contains a name of a DOS character device (builtin or + * installed device driver). + * Prepend a '_' to allow creation of the item in the file system. + */ + for (i = wcslen(pathcompw) + 1; i > 0; --i) + pathcompw[i] = pathcompw[i - 1]; + pathcompw[0] = '_'; + } +} /* end function maskDOSdevicew() */ + +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + + + +/**********************/ +/* Function map2fat() */ /* Not quite identical to OS/2 version */ +/**********************/ + +static void map2fat(pathcomp, pEndFAT) + char *pathcomp, **pEndFAT; +{ + char *ppc = pathcomp; /* variable pointer to pathcomp */ + char *pEnd = *pEndFAT; /* variable pointer to buildpathFAT */ + char *pBegin = *pEndFAT; /* constant pointer to start of this comp. */ + char *last_dot = NULL; /* last dot not converted to underscore */ + register unsigned workch; /* hold the character being tested */ + + + /* Only need check those characters which are legal in NTFS but not + * in FAT: to get here, must already have passed through mapname. + * Also must truncate path component to ensure 8.3 compliance. + */ + while ((workch = (uch)*ppc++) != 0) { + switch (workch) { + case '[': + case ']': + case '+': + case ',': + case ';': + case '=': + *pEnd++ = '_'; /* convert brackets to underscores */ + break; + + case '.': + if (pEnd == *pEndFAT) { /* nothing appended yet... */ + if (*ppc == '\0') /* don't bother appending a */ + break; /* "./" component to the path */ + else if (*ppc == '.' && ppc[1] == '\0') { /* "../" */ + *pEnd++ = '.'; /* add first dot, */ + *pEnd++ = '.'; /* add second dot, and */ + ++ppc; /* skip over to pathcomp's end */ + } else { /* FAT doesn't allow null filename */ + *pEnd++ = '_'; /* bodies, so map .exrc -> _exrc */ + } /* (_.exr would keep max 3 chars) */ + } else { /* found dot within path component */ + last_dot = pEnd; /* point at last dot so far... */ + *pEnd++ = '_'; /* convert to underscore for now */ + } + break; + + default: + *pEnd++ = (char)workch; + + } /* end switch */ + } /* end while loop */ + + *pEnd = '\0'; /* terminate buildpathFAT */ + + /* NOTE: keep in mind that pEnd points to the end of the path + * component, and *pEndFAT still points to the *beginning* of it... + * Also note that the algorithm does not try to get too fancy: + * if there are no dots already, the name either gets truncated + * at 8 characters or the last underscore is converted to a dot + * (only if more characters are saved that way). In no case is + * a dot inserted between existing characters. + */ + if (last_dot == NULL) { /* no dots: check for underscores... */ + char *plu = MBSRCHR(pBegin, '_'); /* pointer to last underscore */ + + if ((plu != NULL) && /* found underscore: convert to dot? */ + (IZ_MIN(plu - pBegin, 8) + IZ_MIN(pEnd - plu - 1, 3) > 8)) { + last_dot = plu; /* be lazy: drop through to next if-blk */ + } else if ((pEnd - *pEndFAT) > 8) { + /* no underscore; or converting underscore to dot would save less + chars than leaving everything in the basename */ + *pEndFAT += 8; /* truncate at 8 chars */ + **pEndFAT = '\0'; + } else + *pEndFAT = pEnd; /* whole thing fits into 8 chars or less */ + } + + if (last_dot != NULL) { /* one dot is OK: */ + *last_dot = '.'; /* put it back in */ + + if ((last_dot - pBegin) > 8) { + char *p, *q; + int i; + + p = last_dot; + q = last_dot = pBegin + 8; + for (i = 0; (i < 4) && *p; ++i) /* too many chars in basename: */ + *q++ = *p++; /* shift .ext left and trun- */ + *q = '\0'; /* cate/terminate it */ + *pEndFAT = q; + } else if ((pEnd - last_dot) > 4) { /* too many chars in extension */ + *pEndFAT = last_dot + 4; + **pEndFAT = '\0'; + } else + *pEndFAT = pEnd; /* filename is fine; point at terminating zero */ + + if ((last_dot - pBegin) > 0 && last_dot[-1] == ' ') + last_dot[-1] = '_'; /* NO blank in front of '.'! */ + } +} /* end function map2fat() */ + + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + +static void map2fatw(pathcompw, pEndFATw) + wchar_t *pathcompw, **pEndFATw; +{ + wchar_t *ppcw = pathcompw; /* variable pointer to pathcomp */ + wchar_t *pEndw = *pEndFATw; /* variable pointer to buildpathFAT */ + wchar_t *pBeginw = *pEndFATw; /* constant pointer to start of this comp. */ + wchar_t *last_dotw = NULL; /* last dot not converted to underscore */ + register wchar_t workchw; /* hold the character being tested */ + + + /* Only need check those characters which are legal in NTFS but not + * in FAT: to get here, must already have passed through mapname. + * Also must truncate path component to ensure 8.3 compliance. + */ + while ((workchw = *ppcw++) != 0) { + switch (workchw) { + case '[': + case ']': + case '+': + case ',': + case ';': + case '=': + *pEndw++ = '_'; /* convert brackets to underscores */ + break; + + case '.': + if (pEndw == *pEndFATw) { /* nothing appended yet... */ + if (*ppcw == '\0') /* don't bother appending a */ + break; /* "./" component to the path */ + else if (*ppcw == '.' && ppcw[1] == '\0') { /* "../" */ + *pEndw++ = '.'; /* add first dot, */ + *pEndw++ = '.'; /* add second dot, and */ + ++ppcw; /* skip over to pathcomp's end */ + } else { /* FAT doesn't allow null filename */ + *pEndw++ = '_'; /* bodies, so map .exrc -> _exrc */ + } /* (_.exr would keep max 3 chars) */ + } else { /* found dot within path component */ + last_dotw = pEndw; /* point at last dot so far... */ + *pEndw++ = '_'; /* convert to underscore for now */ + } + break; + + default: + *pEndw++ = workchw; + + } /* end switch */ + } /* end while loop */ + + *pEndw = '\0'; /* terminate buildpathFAT */ + + /* NOTE: keep in mind that pEnd points to the end of the path + * component, and *pEndFAT still points to the *beginning* of it... + * Also note that the algorithm does not try to get too fancy: + * if there are no dots already, the name either gets truncated + * at 8 characters or the last underscore is converted to a dot + * (only if more characters are saved that way). In no case is + * a dot inserted between existing characters. + */ + if (last_dotw == NULL) { /* no dots: check for underscores... */ + wchar_t *pluw = wcschr(pBeginw, '_'); /* pointer to last underscore */ + + if ((pluw != NULL) && /* found underscore: convert to dot? */ + (IZ_MIN(pluw - pBeginw, 8) + IZ_MIN(pEndw - pluw - 1, 3) > 8)) { + last_dotw = pluw; /* be lazy: drop through to next if-blk */ + } else if ((pEndw - *pEndFATw) > 8) { + /* no underscore; or converting underscore to dot would save less + chars than leaving everything in the basename */ + *pEndFATw += 8; /* truncate at 8 chars */ + **pEndFATw = '\0'; + } else + *pEndFATw = pEndw; /* whole thing fits into 8 chars or less */ + } + + if (last_dotw != NULL) { /* one dot is OK: */ + *last_dotw = '.'; /* put it back in */ + + if ((last_dotw - pBeginw) > 8) { + wchar_t *pw, *qw; + int i; + + pw = last_dotw; + qw = last_dotw = pBeginw + 8; + for (i = 0; (i < 4) && *pw; ++i) /* too many chars in basename: */ + *qw++ = *pw++; /* shift .ext left and trun- */ + *qw = '\0'; /* cate/terminate it */ + *pEndFATw = qw; + } else if ((pEndw - last_dotw) > 4) { /* too many chars in extension */ + *pEndFATw = last_dotw + 4; + **pEndFATw = '\0'; + } else + *pEndFATw = pEndw; /* filename is fine; point at terminating zero */ + + if ((last_dotw - pBeginw) > 0 && last_dotw[-1] == ' ') + last_dotw[-1] = '_'; /* NO blank in front of '.'! */ + } +} /* end function map2fatw() */ + +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + + + +/***********************/ /* Borrowed from os2.c for UnZip 5.1. */ +/* Function checkdir() */ /* Difference: no EA stuff */ +/***********************/ /* HPFS stuff works on NTFS too */ + +int checkdir(__G__ pathcomp, flag) + __GDEF + char *pathcomp; + int flag; +/* + * returns: + * MPN_OK - no problem detected + * MPN_INF_TRUNC - (on APPEND_NAME) truncated filename + * MPN_INF_SKIP - path doesn't exist, not allowed to create + * MPN_ERR_SKIP - path doesn't exist, tried to create and failed; or path + * exists and is not a directory, but is supposed to be + * MPN_ERR_TOOLONG - path is too long + * MPN_NOMEM - can't allocate memory for filename buffers + */ +{ + /* static int rootlen = 0; */ /* length of rootpath */ + /* static char *rootpath; */ /* user's "extract-to" directory */ + /* static char *buildpathHPFS; */ /* full path (so far) to extracted file, */ + /* static char *buildpathFAT; */ /* both HPFS/EA (main) and FAT versions */ + /* static char *endHPFS; */ /* corresponding pointers to end of */ + /* static char *endFAT; */ /* buildpath ('\0') */ + +# define FN_MASK 7 +# define FUNCTION (flag & FN_MASK) + + + +/*--------------------------------------------------------------------------- + APPEND_DIR: append the path component to the path being built and check + for its existence. If doesn't exist and we are creating directories, do + so for this one; else signal success or error as appropriate. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == APPEND_DIR) { + char *p = pathcomp; + int too_long = FALSE; + + Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp))); + while ((*G.endHPFS = *p++) != '\0') /* copy to HPFS filename */ + ++G.endHPFS; + if (!IsVolumeOldFAT(__G__ G.buildpathHPFS)) { + p = pathcomp; + while ((*G.endFAT = *p++) != '\0') /* copy to FAT filename, too */ + ++G.endFAT; + } else + map2fat(pathcomp, &G.endFAT); /* map into FAT fn, update endFAT */ + + /* GRR: could do better check, see if overrunning buffer as we go: + * check endHPFS-buildpathHPFS after each append, set warning variable + * if within 20 of FILNAMSIZ; then if var set, do careful check when + * appending. Clear variable when begin new path. */ + + /* next check: need to append '/', at least one-char name, '\0' */ + if ((G.endHPFS-G.buildpathHPFS) > FILNAMSIZ-3) + too_long = TRUE; /* check if extracting dir? */ +# ifdef FIX_STAT_BUG + /* Borland C++ 5.0 does not handle a call to stat() well if the + * directory does not exist (it tends to crash in strange places.) + * This is apparently a problem only when compiling for GUI rather + * than console. The code below attempts to work around this problem. + */ + if (access(G.buildpathFAT, 0) != 0) { + if (!G.create_dirs) { /* told not to create (freshening) */ + izu_free(G.buildpathHPFS); + izu_free(G.buildpathFAT); + /* path doesn't exist: nothing to do */ + return MPN_INF_SKIP; + } + if (too_long) { /* GRR: should allow FAT extraction w/o EAs */ + Info(slide, 1, ((char *)slide, + "checkdir(1) error: path too long: %s\n", + FnFilter1(G.buildpathHPFS))); + izu_free(G.buildpathHPFS); + izu_free(G.buildpathFAT); + /* no room for filenames: fatal */ + return MPN_ERR_TOOLONG; + } + if (MKDIR(G.buildpathFAT, 0777) == -1) { /* create the directory */ + Info(slide, 1, ((char *)slide, + "checkdir(1) error: cannot create %s\n\ + unable to process %s.\n", + FnFilter2(G.buildpathFAT), FnFilter1(G.filename))); + izu_free(G.buildpathHPFS); + izu_free(G.buildpathFAT); + /* path didn't exist, tried to create, failed */ + return MPN_ERR_SKIP; + } + G.created_dir = TRUE; + } +# endif /* FIX_STAT_BUG */ + if (SSTAT(G.buildpathFAT, &G.statbuf)) /* path doesn't exist */ + { + if (!G.create_dirs) { /* told not to create (freshening) */ + izu_free(G.buildpathHPFS); + izu_free(G.buildpathFAT); + /* path doesn't exist: nothing to do */ + return MPN_INF_SKIP; + } + if (too_long) { /* GRR: should allow FAT extraction w/o EAs */ + Info(slide, 1, ((char *)slide, + "checkdir(2) error: path too long: %s\n", + FnFilter1(G.buildpathHPFS))); + izu_free(G.buildpathHPFS); + izu_free(G.buildpathFAT); + /* no room for filenames: fatal */ + return MPN_ERR_TOOLONG; + } + if (MKDIR(G.buildpathFAT, 0777) == -1) { /* create the directory */ + Info(slide, 1, ((char *)slide, + "checkdir(2) error: cannot create %s\n\ + unable to process %s.\n", + FnFilter2(G.buildpathFAT), FnFilter1(G.filename))); + izu_free(G.buildpathHPFS); + izu_free(G.buildpathFAT); + /* path didn't exist, tried to create, failed */ + return MPN_ERR_SKIP; + } + G.created_dir = TRUE; + } else if (!S_ISDIR(G.statbuf.st_mode)) { + Info(slide, 1, ((char *)slide, + "checkdir(1) error: %s exists but is not directory\n\ + unable to process %s.\n", + FnFilter2(G.buildpathFAT), FnFilter1(G.filename))); + izu_free(G.buildpathHPFS); + izu_free(G.buildpathFAT); + /* path existed but wasn't dir */ + return MPN_ERR_SKIP; + } + if (too_long) { + Info(slide, 1, ((char *)slide, + "checkdir(3) error: path too long: %s\n", + FnFilter1(G.buildpathHPFS))); + izu_free(G.buildpathHPFS); + izu_free(G.buildpathFAT); + /* no room for filenames: fatal */ + return MPN_ERR_TOOLONG; + } + *G.endHPFS++ = '/'; + *G.endFAT++ = '/'; + *G.endHPFS = *G.endFAT = '\0'; + Trace((stderr, "buildpathHPFS now = [%s]\nbuildpathFAT now = [%s]\n", + FnFilter1(G.buildpathHPFS), FnFilter2(G.buildpathFAT))); + return MPN_OK; + + } /* end if (FUNCTION == APPEND_DIR) */ + +/*--------------------------------------------------------------------------- + GETPATH: copy full FAT path to the string pointed at by pathcomp (want + filename to reflect name used on disk, not EAs; if full path is HPFS, + buildpathFAT and buildpathHPFS will be identical). Also free both paths. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == GETPATH) { + Trace((stderr, "getting and freeing FAT path [%s]\n", + FnFilter1(G.buildpathFAT))); + strcpy(pathcomp, G.buildpathFAT); + izu_free(G.buildpathFAT); + Trace((stderr, "freeing HPFS path [%s]\n", + FnFilter1(G.buildpathHPFS))); + izu_free(G.buildpathHPFS); + G.buildpathHPFS = G.buildpathFAT = G.endHPFS = G.endFAT = NULL; + return MPN_OK; + } + +/*--------------------------------------------------------------------------- + APPEND_NAME: assume the path component is the filename; append it and + return without checking for existence. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == APPEND_NAME) { + char *p = pathcomp; + int error = MPN_OK; + + Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp))); + /* The buildpathHPFS buffer has been allocated large enough to + * hold the complete combined name, so there is no need to check + * for OS filename size limit overflow within the copy loop. + */ + while ((*G.endHPFS = *p++) != '\0') { /* copy to HPFS filename */ + ++G.endHPFS; + } + /* Now, check for OS filename size overflow. When detected, the + * mapped HPFS name is truncated and a warning message is shown. + */ + if ((G.endHPFS-G.buildpathHPFS) >= FILNAMSIZ) { + G.buildpathHPFS[FILNAMSIZ-1] = '\0'; + Info(slide, 1, ((char *)slide, + "checkdir(1) warning: path too long; truncating\n\ + %s\n\ + -> %s\n", + FnFilter1(G.filename), FnFilter2(G.buildpathHPFS))); + error = MPN_INF_TRUNC; /* filename truncated */ + } + + /* The buildpathFAT buffer has the same allocated size as the + * buildpathHPFS buffer, so there is no need for an overflow check + * within the following copy loop, either. + */ + if (G.pInfo->vollabel || !IsVolumeOldFAT(__G__ G.buildpathHPFS)) { + /* copy to FAT filename, too */ + p = pathcomp; + while ((*G.endFAT = *p++) != '\0') + ++G.endFAT; + } else + /* map into FAT fn, update endFAT */ + map2fat(pathcomp, &G.endFAT); + + /* Check that the FAT path does not exceed the FILNAMSIZ limit, and + * truncate when neccessary. + * Note that truncation can only happen when the HPFS path (which is + * never shorter than the FAT path) has been already truncated. + * So, emission of the warning message and setting the error code + * has already happened. + */ + if ((G.endFAT-G.buildpathFAT) >= FILNAMSIZ) + G.buildpathFAT[FILNAMSIZ-1] = '\0'; + Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT: %s\n", + FnFilter1(G.buildpathHPFS), FnFilter2(G.buildpathFAT))); + + return error; /* could check for existence, prompt for new name... */ + + } /* end if (FUNCTION == APPEND_NAME) */ + +/*--------------------------------------------------------------------------- + INIT: allocate and initialize buffer space for the file currently being + extracted. If file was renamed with an absolute path, don't prepend the + extract-to path. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == INIT) { + Trace((stderr, "initializing buildpathHPFS and buildpathFAT to ")); +# ifdef ACORN_FTYPE_NFS + if ((G.buildpathHPFS = (char *)izu_malloc(G.fnlen+G.rootlen+ + (uO.acorn_nfs_ext ? 5 : 1))) +# else + if ((G.buildpathHPFS = (char *)izu_malloc(G.fnlen+G.rootlen+1)) +# endif + == NULL) + return MPN_NOMEM; +# ifdef ACORN_FTYPE_NFS + if ((G.buildpathFAT = (char *)izu_malloc(G.fnlen+G.rootlen+ + (uO.acorn_nfs_ext ? 5 : 1))) +# else + if ((G.buildpathFAT = (char *)izu_malloc(G.fnlen+G.rootlen+1)) +# endif + == NULL) { + izu_free(G.buildpathHPFS); + return MPN_NOMEM; + } + if (G.pInfo->vollabel) { /* use root or renamed path, but don't store */ +/* GRR: for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */ + if (G.renamed_fullpath && pathcomp[1] == ':') + *G.buildpathHPFS = (char)ToLower(*pathcomp); + else if (!G.renamed_fullpath && G.rootlen > 1 && + G.rootpath[1] == ':') + *G.buildpathHPFS = (char)ToLower(*G.rootpath); + else { + char tmpN[MAX_PATH], *tmpP; + if (GetFullPathNameA(".", MAX_PATH, tmpN, &tmpP) > MAX_PATH) + { /* by definition of MAX_PATH we should never get here */ + Info(slide, 1, ((char *)slide, + "checkdir(1) warning: current dir path too long\n")); + return MPN_INF_TRUNC; /* can't get drive letter */ + } + G.nLabelDrive = *tmpN - 'a' + 1; + *G.buildpathHPFS = (char)(G.nLabelDrive - 1 + 'a'); + } + G.nLabelDrive = *G.buildpathHPFS - 'a' + 1; /* save for mapname() */ + if (uO.volflag == 0 || *G.buildpathHPFS < 'a' /* no labels/bogus? */ + || (uO.volflag == 1 && !isfloppy(G.nLabelDrive))) { /* !fixed */ + izu_free(G.buildpathHPFS); + izu_free(G.buildpathFAT); + return MPN_VOL_LABEL; /* skipping with message */ + } + *G.buildpathHPFS = '\0'; + } else if (G.renamed_fullpath) /* pathcomp = valid data */ + strcpy(G.buildpathHPFS, pathcomp); + else if (G.rootlen > 0) + strcpy(G.buildpathHPFS, G.rootpath); + else + *G.buildpathHPFS = '\0'; + G.endHPFS = G.buildpathHPFS; + G.endFAT = G.buildpathFAT; + while ((*G.endFAT = *G.endHPFS) != '\0') { + ++G.endFAT; + ++G.endHPFS; + } + Trace((stderr, "[%s]\n", FnFilter1(G.buildpathHPFS))); + return MPN_OK; + } + +/*--------------------------------------------------------------------------- + ROOT: if appropriate, store the path in rootpath and create it if neces- + sary; else assume it's a zipfile member and return. This path segment + gets used in extracting all members from every zipfile specified on the + command line. Note that under OS/2 and MS-DOS, if a candidate extract-to + directory specification includes a drive letter (leading "x:"), it is + treated just as if it had a trailing '/'--that is, one directory level + will be created if the path doesn't exist, unless this is otherwise pro- + hibited (e.g., freshening). + ---------------------------------------------------------------------------*/ + +# if (!defined(SFX) || defined(SFX_EXDIR)) + if (FUNCTION == ROOT) { + Trace((stderr, "initializing root path to [%s]\n", + FnFilter1(pathcomp))); + if (pathcomp == NULL) { + G.rootlen = 0; + return MPN_OK; + } + if (G.rootlen > 0) /* rootpath was already set, nothing to do */ + return MPN_OK; + if ((G.rootlen = strlen(pathcomp)) > 0) { + int had_trailing_pathsep=FALSE, has_drive=FALSE, add_dot=FALSE; + char *tmproot; + + if ((tmproot = (char *)izu_malloc(G.rootlen+3)) == (char *)NULL) { + G.rootlen = 0; + return MPN_NOMEM; + } + strcpy(tmproot, pathcomp); + if (isalpha((uch)tmproot[0]) && tmproot[1] == ':') + has_drive = TRUE; /* drive designator */ + if (tmproot[G.rootlen-1] == '/' || tmproot[G.rootlen-1] == '\\') { + tmproot[--G.rootlen] = '\0'; + had_trailing_pathsep = TRUE; + } + if (has_drive && (G.rootlen == 2)) { + if (!had_trailing_pathsep) /* i.e., original wasn't "x:/" */ + add_dot = TRUE; /* relative path: add '.' before '/' */ + } else if (G.rootlen > 0) { /* need not check "x:." and "x:/" */ + if (SSTAT(tmproot, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode)) + { + /* path does not exist */ + if (!G.create_dirs /* || iswild(tmproot) */ ) { + izu_free(tmproot); + G.rootlen = 0; + /* treat as stored file */ + return MPN_INF_SKIP; + } + /* create directory (could add loop here scanning tmproot + * to create more than one level, but really necessary?) */ + if (MKDIR(tmproot, 0777) == -1) { + Info(slide, 1, ((char *)slide, + "checkdir(1): cannot create extraction directory: %s\n", + FnFilter1(tmproot))); + izu_free(tmproot); + G.rootlen = 0; + /* path didn't exist, tried to create, failed: */ + /* file exists, or need 2+ subdir levels */ + return MPN_ERR_SKIP; + } + } + } + if (add_dot) /* had just "x:", make "x:." */ + tmproot[G.rootlen++] = '.'; + tmproot[G.rootlen++] = '/'; + tmproot[G.rootlen] = '\0'; + if ((G.rootpath = (char *)izu_realloc( + tmproot, G.rootlen+1)) == NULL) { + izu_free(tmproot); + G.rootlen = 0; + return MPN_NOMEM; + } + Trace((stderr, "rootpath now = [%s]\n", FnFilter1(G.rootpath))); + } + return MPN_OK; + } +# endif /* !SFX || SFX_EXDIR */ + +/*--------------------------------------------------------------------------- + END: free rootpath, immediately prior to program exit. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == END) { + Trace((stderr, "freeing rootpath\n")); + if (G.rootlen > 0) { + izu_free(G.rootpath); + G.rootlen = 0; + } + return MPN_OK; + } + + return MPN_INVALID; /* should never reach */ + +} /* end function checkdir() */ + + + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + +/* WIN32 wide version */ + +int checkdirw(__G__ pathcompw, flag) + __GDEF + wchar_t *pathcompw; + int flag; +/* + * returns: + * MPN_OK - no problem detected + * MPN_INF_TRUNC - (on APPEND_NAME) truncated filename + * MPN_INF_SKIP - path doesn't exist, not allowed to create + * MPN_ERR_SKIP - path doesn't exist, tried to create and failed; or path + * exists and is not a directory, but is supposed to be + * MPN_ERR_TOOLONG - path is too long + * MPN_NOMEM - can't allocate memory for filename buffers + */ +{ + /* static int rootlen = 0; */ /* length of rootpath */ + /* static char *rootpath; */ /* user's "extract-to" directory */ + /* static char *buildpathHPFS; */ /* full path (so far) to extracted file, */ + /* static char *buildpathFAT; */ /* both HPFS/EA (main) and FAT versions */ + /* static char *endHPFS; */ /* corresponding pointers to end of */ + /* static char *endFAT; */ /* buildpath ('\0') */ + +# define FN_MASK 7 +# define FUNCTION (flag & FN_MASK) + + + +/*--------------------------------------------------------------------------- + APPEND_DIR: append the path component to the path being built and check + for its existence. If doesn't exist and we are creating directories, do + so for this one; else signal success or error as appropriate. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == APPEND_DIR) { + wchar_t *pw = pathcompw; + int too_long = FALSE; + char *buildpathFAT = wchar_to_local_string(G.buildpathFATw, G.unicode_escape_all); + char *buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all); + /* Could use G.filename from the standard path, but may + not work well on this port */ + char *fn = wchar_to_local_string(G.unipath_widefilename, G.unicode_escape_all); + + while ((*G.endHPFSw = *pw++) != '\0') /* copy to HPFS filename */ + ++G.endHPFSw; + if (!IsVolumeOldFATw(__G__ G.buildpathHPFSw)) { + pw = pathcompw; + while ((*G.endFATw = *pw++) != '\0') /* copy to FAT filename, too */ + ++G.endFATw; + } else + map2fatw(pathcompw, &G.endFATw); /* map into FAT fn, update endFAT */ + + /* GRR: could do better check, see if overrunning buffer as we go: + * check endHPFS-buildpathHPFS after each append, set warning variable + * if within 20 of FILNAMSIZ; then if var set, do careful check when + * appending. Clear variable when begin new path. */ + + /* next check: need to append '/', at least one-char name, '\0' */ + if ((G.endHPFSw-G.buildpathHPFSw) > FILNAMSIZ-3) + too_long = TRUE; /* check if extracting dir? */ +# ifdef FIX_STAT_BUG + /* Borland C++ 5.0 does not handle a call to stat() well if the + * directory does not exist (it tends to crash in strange places.) + * This is apparently a problem only when compiling for GUI rather + * than console. The code below attempts to work around this problem. + */ + if (_waccess(G.buildpathFATw, 0) != 0) { + if (!G.create_dirs) { /* told not to create (freshening) */ + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + izu_free(fn); + izu_free(G.buildpathHPFSw); + izu_free(G.buildpathFATw); + /* path doesn't exist: nothing to do */ + return MPN_INF_SKIP; + } + if (too_long) { /* GRR: should allow FAT extraction w/o EAs */ + Info(slide, 1, ((char *)slide, + "checkdir(4) error: path too long: %s\n", + FnFilter1(fn))); + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + izu_free(fn); + izu_free(G.buildpathHPFSw); + izu_free(G.buildpathFATw); + /* no room for filenames: fatal */ + return MPN_ERR_TOOLONG; + } + { + int i = MKDIRW(G.buildpathFATw, 0777); + if (i == -1) { /* create the directory */ + Info(slide, 1, ((char *)slide, + "checkdir(3) error: cannot create %s\n\ + unable to process %s.\n", + FnFilter2(buildpathFAT), FnFilter1(fn))); + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + izu_free(fn); + izu_free(G.buildpathHPFSw); + izu_free(G.buildpathFATw); + /* path didn't exist, tried to create, failed */ + return MPN_ERR_SKIP; + } + G.created_dir = TRUE; + } + } +# endif /* FIX_STAT_BUG */ + if (SSTATW(G.buildpathFATw, &G.statbuf)) /* path doesn't exist */ + { + if (!G.create_dirs) { /* told not to create (freshening) */ + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + izu_free(fn); + izu_free(G.buildpathHPFSw); + izu_free(G.buildpathFATw); + /* path doesn't exist: nothing to do */ + return MPN_INF_SKIP; + } + if (too_long) { /* GRR: should allow FAT extraction w/o EAs */ + Info(slide, 1, ((char *)slide, + "checkdir(5) error: path too long: %s\n", + FnFilter1(buildpathHPFS))); + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + izu_free(fn); + izu_free(G.buildpathHPFSw); + izu_free(G.buildpathFATw); + /* no room for filenames: fatal */ + return MPN_ERR_TOOLONG; + } + { + char *buildpathFAT = wchar_to_local_string(G.buildpathFATw, G.unicode_escape_all); + int i = MKDIRW(G.buildpathFATw, 0777); + if (i == -1) { /* create the directory */ + Info(slide, 1, ((char *)slide, + "checkdir(4) error: cannot create %s\n\ + unable to process %s.\n", + FnFilter2(buildpathFAT), FnFilter1(fn))); + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + izu_free(fn); + izu_free(G.buildpathHPFSw); + izu_free(G.buildpathFATw); + /* path didn't exist, tried to create, failed */ + return MPN_ERR_SKIP; + } + G.created_dir = TRUE; + } + } else if (!S_ISDIR(G.statbuf.st_mode)) { + Info(slide, 1, ((char *)slide, + "checkdir(2) error: %s exists but is not directory\n\ + unable to process %s.\n", + FnFilter2(buildpathFAT), FnFilter1(fn))); + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + izu_free(fn); + izu_free(G.buildpathHPFSw); + izu_free(G.buildpathFATw); + /* path existed but wasn't dir */ + return MPN_ERR_SKIP; + } + if (too_long) { + Info(slide, 1, ((char *)slide, + "checkdir(6) error: path too long: %s\n", + FnFilter1(buildpathHPFS))); + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + izu_free(fn); + izu_free(G.buildpathHPFSw); + izu_free(G.buildpathFATw); + /* no room for filenames: fatal */ + return MPN_ERR_TOOLONG; + } + *G.endHPFSw++ = '/'; + *G.endFATw++ = '/'; + *G.endHPFSw = *G.endFATw = '\0'; + Trace((stderr, "buildpathHPFS now = [%s]\nbuildpathFAT now = [%s]\n", + FnFilter1(buildpathHPFS), FnFilter2(buildpathFAT))); + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + izu_free(fn); + //izu_free(G.buildpathHPFSw); + //izu_free(G.buildpathFATw); + return MPN_OK; + + } /* end if (FUNCTION == APPEND_DIR) */ + +/*--------------------------------------------------------------------------- + GETPATH: copy full FAT path to the string pointed at by pathcomp (want + filename to reflect name used on disk, not EAs; if full path is HPFS, + buildpathFAT and buildpathHPFS will be identical). Free both local paths. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == GETPATH) { +# ifdef Tracing + char *buildpathFAT = wchar_to_local_string(G.buildpathFATw, G.unicode_escape_all); + char *buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all); + Trace((stderr, "getting and freeing FAT path [%s]\n", + FnFilter1(buildpathFAT))); + izu_free(buildpathFAT); +# endif /* def Tracing */ + wcscpy(pathcompw, G.buildpathFATw); + izu_free(G.buildpathFATw); +# ifdef Tracing + Trace((stderr, "freeing HPFS path [%s]\n", + FnFilter1(buildpathHPFS))); + izu_free(buildpathHPFS); +# endif /* def Tracing */ + izu_free(G.buildpathHPFSw); + G.buildpathHPFSw = G.buildpathFATw = G.endHPFSw = G.endFATw = NULL; + return MPN_OK; + } + +/*--------------------------------------------------------------------------- + APPEND_NAME: assume the path component is the filename; append it and + return without checking for existence. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == APPEND_NAME) { + wchar_t *pw = pathcompw; + int error = MPN_OK; + char *fn = wchar_to_local_string(G.unipath_widefilename, G.unicode_escape_all); +# ifdef Tracing + char *pathcomp = wchar_to_local_string(pathcompw, G.unicode_escape_all); + Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp))); + izu_free( pathcomp); +# endif /* def Tracing */ + /* The buildpathHPFS buffer has been allocated large enough to + * hold the complete combined name, so there is no need to check + * for OS filename size limit overflow within the copy loop. + */ + while ((*G.endHPFSw = *pw++) != '\0') { /* copy to HPFS filename */ + ++G.endHPFSw; + } + /* Now, check for OS filename size overflow. When detected, the + * mapped HPFS name is truncated and a warning message is shown. + */ + if ((G.endHPFSw-G.buildpathHPFSw) >= FILNAMSIZ) { + char *buildpathHPFS; + G.buildpathHPFSw[FILNAMSIZ-1] = '\0'; + buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all); + Info(slide, 1, ((char *)slide, + "checkdir(2) warning: path too long; truncating\n\ + %s\n\ + -> %s\n", + FnFilter1(fn), FnFilter2(buildpathHPFS))); + izu_free(buildpathHPFS); + izu_free( fn); + error = MPN_INF_TRUNC; /* filename truncated */ + } + + /* The buildpathFAT buffer has the same allocated size as the + * buildpathHPFS buffer, so there is no need for an overflow check + * within the following copy loop, either. + */ + if (G.pInfo->vollabel || !IsVolumeOldFATw(__G__ G.buildpathHPFSw)) { + /* copy to FAT filename, too */ + pw = pathcompw; + while ((*G.endFATw = *pw++) != '\0') + ++G.endFATw; + } else + /* map into FAT fn, update endFAT */ + map2fatw(pathcompw, &G.endFATw); + + /* Check that the FAT path does not exceed the FILNAMSIZ limit, and + * truncate when neccessary. + * Note that truncation can only happen when the HPFS path (which is + * never shorter than the FAT path) has been already truncated. + * So, emission of the warning message and setting the error code + * has already happened. + */ + if ((G.endFATw-G.buildpathFATw) >= FILNAMSIZ) + G.buildpathFATw[FILNAMSIZ-1] = '\0'; +# ifdef Tracing + { + char *buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all); + char *buildpathFAT = wchar_to_local_string(G.buildpathFATw,G.unicode_escape_all); + Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT: %s\n", + FnFilter1(buildpathHPFS), FnFilter2(buildpathFAT))); + izu_free(buildpathHPFS); + izu_free(buildpathFAT); + } +# endif /* def Tracing */ + izu_free(fn); + + return error; /* could check for existence, prompt for new name... */ + + } /* end if (FUNCTION == APPEND_NAME) */ + +/*--------------------------------------------------------------------------- + INIT: allocate and initialize buffer space for the file currently being + extracted. If file was renamed with an absolute path, don't prepend the + extract-to path. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == INIT) { + Trace((stderr, "initializing buildpathHPFSw and buildpathFATw to ")); + if ((G.buildpathHPFSw = (wchar_t *)izu_malloc( + (G.fnlen+G.rootlen+1) * sizeof(wchar_t))) == NULL) + return MPN_NOMEM; + if ((G.buildpathFATw = (wchar_t *)izu_malloc( + (G.fnlen+G.rootlen+1) * sizeof(wchar_t))) == NULL) { + izu_free(G.buildpathHPFSw); + return MPN_NOMEM; + } + if (G.pInfo->vollabel) { /* use root or renamed path, but don't store */ +/* GRR: for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */ + if (G.renamed_fullpath && pathcompw[1] == ':') + *G.buildpathHPFSw = (wchar_t)towlower(*pathcompw); + else if (!G.renamed_fullpath && G.rootlen > 1 && + G.rootpathw[1] == ':') + *G.buildpathHPFSw = (wchar_t)towlower(*G.rootpathw); + else { + wchar_t tmpNw[MAX_PATH], *tmpPw; + if (GetFullPathNameW(L".", MAX_PATH, tmpNw, &tmpPw) > MAX_PATH) + { /* by definition of MAX_PATH we should never get here */ + Info(slide, 1, ((char *)slide, + "checkdir(2) warning: current dir path too long\n")); + return MPN_INF_TRUNC; /* can't get drive letter */ + } + G.nLabelDrive = (char)(*G.buildpathHPFSw - 'a' + 1); /* save for mapname() */ + *G.buildpathHPFSw = (wchar_t)(G.nLabelDrive - 1 + 'a'); + } + if (uO.volflag == 0 || *G.buildpathHPFSw < 'a' /* no labels/bogus? */ + || (uO.volflag == 1 && !isfloppy(G.nLabelDrive))) { /* !fixed */ + izu_free(G.buildpathHPFSw); + izu_free(G.buildpathFATw); + return MPN_VOL_LABEL; /* skipping with message */ + } + *G.buildpathHPFSw = '\0'; + } else if (G.renamed_fullpath) /* pathcomp = valid data */ + wcscpy(G.buildpathHPFSw, pathcompw); + else if (G.rootlen > 0) + wcscpy(G.buildpathHPFSw, G.rootpathw); + else + *G.buildpathHPFSw = '\0'; + G.endHPFSw = G.buildpathHPFSw; + G.endFATw = G.buildpathFATw; + while ((*G.endFATw = *G.endHPFSw) != '\0') { + ++G.endFATw; + ++G.endHPFSw; + } +# ifdef Tracing + { + char *buildpathHPFS = wchar_to_local_string(G.buildpathHPFSw, G.unicode_escape_all); + Trace((stderr, "[%s]\n", FnFilter1(buildpathHPFS))); + izu_free(buildpathHPFS); + } +# endif /* def Tracing */ + + return MPN_OK; + } + +/*--------------------------------------------------------------------------- + ROOT: if appropriate, store the path in rootpath and create it if neces- + sary; else assume it's a zipfile member and return. This path segment + gets used in extracting all members from every zipfile specified on the + command line. Note that under OS/2 and MS-DOS, if a candidate extract-to + directory specification includes a drive letter (leading "x:"), it is + treated just as if it had a trailing '/'--that is, one directory level + will be created if the path doesn't exist, unless this is otherwise pro- + hibited (e.g., freshening). + ---------------------------------------------------------------------------*/ + +# if (!defined(SFX) || defined(SFX_EXDIR)) + if (FUNCTION == ROOT) { +# ifdef Tracing + char *pathcomp = wchar_to_local_string(pathcompw, G.unicode_escape_all); + Trace((stderr, "initializing root path to [%s]\n", + FnFilter1(pathcomp))); + izu_free(pathcomp); +# endif /* def Tracing */ + if (pathcompw == NULL) { + G.rootlen = 0; + return MPN_OK; + } + if (G.rootlen > 0) /* rootpath was already set, nothing to do */ + return MPN_OK; + if ((G.rootlen = wcslen(pathcompw)) > 0) { + int had_trailing_pathsep=FALSE, has_drive=FALSE, add_dot=FALSE; + wchar_t *tmprootw; + + if ((tmprootw = (wchar_t *)izu_malloc( + (G.rootlen+3) * sizeof(wchar_t))) == (wchar_t *)NULL) { + G.rootlen = 0; + return MPN_NOMEM; + } + wcscpy(tmprootw, pathcompw); + if (iswalpha(tmprootw[0]) && tmprootw[1] == ':') + has_drive = TRUE; /* drive designator */ + if (tmprootw[G.rootlen-1] == '/' || tmprootw[G.rootlen-1] == '\\') { + tmprootw[--G.rootlen] = '\0'; + had_trailing_pathsep = TRUE; + } + if (has_drive && (G.rootlen == 2)) { + if (!had_trailing_pathsep) /* i.e., original wasn't "x:/" */ + add_dot = TRUE; /* relative path: add '.' before '/' */ + } else if (G.rootlen > 0) { /* need not check "x:." and "x:/" */ + if (SSTATW(tmprootw, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode)) + { + /* path does not exist */ + if (!G.create_dirs /* || iswild(tmproot) */ ) { + izu_free(tmprootw); + G.rootlen = 0; + /* treat as stored file */ + return MPN_INF_SKIP; + } + /* create directory (could add loop here scanning tmproot + * to create more than one level, but really necessary?) */ + if (MKDIRW(tmprootw, 0777) == -1) { + char *tmproot = wchar_to_local_string(tmprootw, G.unicode_escape_all); + Info(slide, 1, ((char *)slide, + "checkdir(2): cannot create extraction directory: %s\n", + FnFilter1(tmproot))); + izu_free(tmproot); + izu_free(tmprootw); + G.rootlen = 0; + /* path didn't exist, tried to create, failed: */ + /* file exists, or need 2+ subdir levels */ + /* 2013-03-12 SMS. + * izu_free(pathcomp); + * Should be "izu_free(pathcompw);"??? + */ + return MPN_ERR_SKIP; + } + } + } + if (add_dot) /* had just "x:", make "x:." */ + tmprootw[G.rootlen++] = '.'; + tmprootw[G.rootlen++] = '/'; + tmprootw[G.rootlen] = '\0'; + if ((G.rootpathw = (wchar_t *)izu_realloc( + tmprootw, (G.rootlen+1) * sizeof(wchar_t))) == NULL) { + izu_free(tmprootw); + G.rootlen = 0; + return MPN_NOMEM; + } +# ifdef Tracing + { + char *rootpath = wchar_to_local_string(G.rootpathw, G.unicode_escape_all); + Trace((stderr, "rootpath now = [%s]\n", FnFilter1(rootpath))); + izu_free(rootpath); + } +# endif /* def Tracing */ + } + return MPN_OK; + } +# endif /* !SFX || SFX_EXDIR */ + +/*--------------------------------------------------------------------------- + END: free rootpath, immediately prior to program exit. + ---------------------------------------------------------------------------*/ + + if (FUNCTION == END) { + Trace((stderr, "freeing rootpath\n")); + if (G.rootlen > 0) { + izu_free(G.rootpathw); + G.rootlen = 0; + } + return MPN_OK; + } + + return MPN_INVALID; /* should never reach */ + +} /* end function checkdirw() */ + +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + + + + +# ifndef SFX + +/*************************/ +/* Function dateformat() */ +/*************************/ + +int dateformat() +{ + char df[2]; /* LOCALE_IDATE has a maximum value of 2 */ + + if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDATE, df, 2) != 0) { + switch (df[0]) + { + case '0': + return DF_MDY; + case '1': + return DF_DMY; + case '2': + return DF_YMD; + } + } + return DF_MDY; +} + + +/****************************/ +/* Function dateseparator() */ +/****************************/ + +char dateseparator() +{ + char df[2]; /* use only if it is one character */ + + if ((GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDATE, df, 2) != 0) && + (df[0] != '\0')) + return df[0]; + else + return '-'; +} + + +# ifndef WINDLL_OLD + +/************************/ +/* Function version() */ +/************************/ + +void version(__G) + __GDEF +{ + int len; +# if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__DJGPP__)) + char buf[80]; +# if (defined(_MSC_VER) && (_MSC_VER > 900)) + char buf2[80]; +# endif +# endif + + len = sprintf((char *)slide, CompiledWith, + +# if defined(_MSC_VER) /* MSC == VC++, but what about SDK compiler? */ + (sprintf(buf, "Microsoft C %d.%02d ", _MSC_VER/100, _MSC_VER%100), buf), +# if (_MSC_VER == 800) + "(Visual C++ v1.1)", +# elif (_MSC_VER == 850) + "(Windows NT v3.5 SDK)", +# elif (_MSC_VER == 900) + "(Visual C++ v2.x)", +# elif (_MSC_VER > 900) + (sprintf(buf2, "(Visual C++ %d.%d)", _MSC_VER/100 - 6, _MSC_VER%100/10), + buf2), +# else + "(bad version)", +# endif +# elif defined(__WATCOMC__) +# if (__WATCOMC__ % 10 > 0) + (sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100, + __WATCOMC__ % 100), buf), "", +# else + (sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100, + (__WATCOMC__ % 100) / 10), buf), "", +# endif +# elif defined(__BORLANDC__) + "Borland C++", +# if (__BORLANDC__ < 0x0200) + " 1.0", +# elif (__BORLANDC__ == 0x0200) + " 2.0", +# elif (__BORLANDC__ == 0x0400) + " 3.0", +# elif (__BORLANDC__ == 0x0410) /* __TURBOC__ = 0x0310 */ + " 3.1", +# elif (__BORLANDC__ == 0x0452) /* __TURBOC__ = 0x0320 */ + " 4.0 or 4.02", +# elif (__BORLANDC__ == 0x0460) /* __TURBOC__ = 0x0340 */ + " 4.5", +# elif (__BORLANDC__ == 0x0500) /* __TURBOC__ = 0x0340 */ + " 5.0", +# elif (__BORLANDC__ == 0x0520) /* __TURBOC__ = 0x0520 */ + " 5.2 (C++ Builder 1.0)", +# elif (__BORLANDC__ == 0x0530) /* __TURBOC__ = 0x0530 */ + " 5.3 (C++ Builder 3.0)", +# elif (__BORLANDC__ == 0x0540) /* __TURBOC__ = 0x0540 */ + " 5.4 (C++ Builder 4.0)", +# elif (__BORLANDC__ == 0x0550) /* __TURBOC__ = 0x0550 */ + " 5.5 (C++ Builder 5.0)", +# elif (__BORLANDC__ == 0x0551) /* __TURBOC__ = 0x0551 */ + " 5.5.1 (C++ Builder 5.0.1)", +# elif (__BORLANDC__ == 0x0560) /* __TURBOC__ = 0x0560 */ + " 6.0 (C++ Builder 6.0)", +# else + " later than 6.0", +# endif +# elif defined(__LCC__) + "LCC-Win32", "", +# elif defined(__GNUC__) +# if defined(__RSXNT__) +# if (defined(__DJGPP__) && !defined(__EMX__)) + (sprintf(buf, "rsxnt(djgpp v%d.%02d) / gcc ", + __DJGPP__, __DJGPP_MINOR__), buf), +# elif defined(__DJGPP__) + (sprintf(buf, "rsxnt(emx+djgpp v%d.%02d) / gcc ", + __DJGPP__, __DJGPP_MINOR__), buf), +# elif (defined(__GO32__) && !defined(__EMX__)) + "rsxnt(djgpp v1.x) / gcc ", +# elif defined(__GO32__) + "rsxnt(emx + djgpp v1.x) / gcc ", +# elif defined(__EMX__) + "rsxnt(emx)+gcc ", +# else + "rsxnt(unknown) / gcc ", +# endif +# elif defined(__CYGWIN__) + "cygnus win32 / gcc ", +# elif defined(__MINGW32__) + "mingw32 / gcc ", +# else + "gcc ", +# endif + __VERSION__, +# else /* !_MSC_VER, !__WATCOMC__, !__BORLANDC__, !__LCC__, !__GNUC__ */ + "unknown compiler (SDK?)", "", +# endif /* ?compilers */ + + "\nWindows 9x / Windows NT/2K/XP/2K3", " (32-bit)", + +# ifdef __DATE__ + " on ", __DATE__ +# else + "", "" +# endif + ); + + (*G.message)((zvoid *)&G, slide, (ulg)len, 0); + + return; + +} /* end function version() */ + +# endif /* ndef WINDLL_OLD */ +# endif /* !SFX */ + + + +# ifdef MORE + +int screensize(int *tt_rows, int *tt_cols) +{ + HANDLE hstdout; + CONSOLE_SCREEN_BUFFER_INFO scr; + + hstdout = GetStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(hstdout, &scr); + if (tt_rows != NULL) *tt_rows = scr.srWindow.Bottom - scr.srWindow.Top + 1; + if (tt_cols != NULL) *tt_cols = scr.srWindow.Right - scr.srWindow.Left + 1; + return 0; /* signal success */ +} + +# endif /* MORE */ + + + +# ifdef W32_STAT_BANDAID + +/* All currently known variants of WIN32 operating systems (Windows 95/98, + * WinNT 3.x, 4.0, 5.x) have a nasty bug in the OS kernel concerning + * conversions between UTC and local time: In the time conversion functions + * of the Win32 API, the timezone offset (including seasonal daylight saving + * shift) between UTC and local time evaluation is erratically based on the + * current system time. The correct evaluation must determine the offset + * value as it {was/is/will be} for the actual time to be converted. + * + * Newer versions of MS C runtime lib's stat() returns utc time-stamps so + * that localtime(timestamp) corresponds to the (potentially false) local + * time shown by the OS' system programs (Explorer, command shell dir, etc.) + * The RSXNT port follows the same strategy, but fails to recognize the + * access-time attribute. + * + * For the NTFS file system (and other filesystems that store time-stamps + * as UTC values), this results in st_mtime (, st_{c|a}time) fields which + * are not stable but vary according to the seasonal change of "daylight + * saving time in effect / not in effect". + * + * Other C runtime libs (CygWin), or the crtdll.dll supplied with Win9x/NT + * return the unix-time equivalent of the UTC FILETIME values as got back + * from the Win32 API call. This time, return values from NTFS are correct + * whereas utimes from files on (V)FAT volumes vary according to the DST + * switches. + * + * To achieve timestamp consistency of UTC (UT extra field) values in + * Zip archives, the Info-ZIP programs require work-around code for + * proper time handling in stat() (and other time handling routines). + * + * However, nowadays most other programs on Windows systems use the + * time conversion strategy of Microsofts C runtime lib "msvcrt.dll". + * To improve interoperability in environments where a "consistent" (but + * false) "UTC<-->LocalTime" conversion is preferred over "stable" time + * stamps, the Info-ZIP specific time conversion handling can be + * deactivated by defining the preprocessor flag NO_W32TIMES_IZFIX. + */ +/* stat() functions under Windows95 tend to fail for root directories. * + * Watcom and Borland, at least, are affected by this bug. Watcom made * + * a partial fix for 11.0 but still missed some cases. This substitute * + * detects the case and fills in reasonable values. Otherwise we get * + * effects like failure to extract to a root dir because it's not found. */ + +int zstat_win32(__W32STAT_GLOBALS__ const char *path, z_stat *buf) +{ + if (!zstat(path, buf)) + { + /* stat was successful, now redo the time-stamp fetches */ +# ifndef NO_W32TIMES_IZFIX + int fs_uses_loctime = FStampIsLocTime(__G__ path); +# endif + HANDLE h; + FILETIME Modft, Accft, Creft; +# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ + char *ansi_path = (char *)alloca(strlen(path) + 1); + + INTERN_TO_ISO(path, ansi_path); +# define Ansi_Path ansi_path +# else +# define Ansi_Path path +# endif + + TTrace((stdout, "stat(%s) finds modtime %08lx\n", path, buf->st_mtime)); + h = CreateFileA(Ansi_Path, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (h != INVALID_HANDLE_VALUE) { + BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft); + CloseHandle(h); + + if (ftOK) { + FTTrace((stdout, "GetFileTime returned Modft", 0, &Modft)); + FTTrace((stdout, "GetFileTime returned Creft", 0, &Creft)); +# ifndef NO_W32TIMES_IZFIX + if (!fs_uses_loctime) { + /* On a filesystem that stores UTC timestamps, we refill + * the time fields of the struct stat buffer by directly + * using the UTC values as returned by the Win32 + * GetFileTime() API call. + */ + NtfsFileTime2utime(&Modft, &(buf->st_mtime)); + if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0) + NtfsFileTime2utime(&Accft, &(buf->st_atime)); + else + buf->st_atime = buf->st_mtime; + if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0) + NtfsFileTime2utime(&Creft, &(buf->st_ctime)); + else + buf->st_ctime = buf->st_mtime; + TTrace((stdout,"NTFS, recalculated modtime %08lx\n", + buf->st_mtime)); + } else +# endif /* NO_W32TIMES_IZFIX */ + { + /* On VFAT and FAT-like filesystems, the FILETIME values + * are converted back to the stable local time before + * converting them to UTC unix time-stamps. + */ + VFatFileTime2utime(&Modft, &(buf->st_mtime)); + if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0) + VFatFileTime2utime(&Accft, &(buf->st_atime)); + else + buf->st_atime = buf->st_mtime; + if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0) + VFatFileTime2utime(&Creft, &(buf->st_ctime)); + else + buf->st_ctime = buf->st_mtime; + TTrace((stdout, "VFAT, recalculated modtime %08lx\n", + buf->st_mtime)); + } + } + } +# undef Ansi_Path + return 0; + } +# ifdef W32_STATROOT_FIX + else + { + DWORD flags; +# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ + char *ansi_path = (char *)alloca(strlen(path) + 1); + + INTERN_TO_ISO(path, ansi_path); +# define Ansi_Path ansi_path +# else +# define Ansi_Path path +# endif + + flags = GetFileAttributesA(Ansi_Path); + if ((flags != INVALID_FILE_ATTRIBUTES) && + (flags & FILE_ATTRIBUTE_DIRECTORY)) { + Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n", + FnFilter1(path))); + memset(buf, 0, sizeof(z_stat)); + buf->st_atime = buf->st_ctime = buf->st_mtime = + dos_to_unix_time(DOSTIME_MINIMUM); /* 1-1-80 */ + buf->st_mode = S_IFDIR | S_IREAD | + ((flags & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE); + return 0; + } /* assumes: stat() won't fail on non-dirs without good reason */ +# undef Ansi_Path + } +# endif /* W32_STATROOT_FIX */ + return -1; +} + + + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) + +int zstat_win32w(__W32STAT_GLOBALS__ const wchar_t *pathw, z_stat *buf) +{ + if (!zstatw(pathw, buf)) + { + char *path = wchar_to_local_string((wchar_t *)pathw, G.unicode_escape_all); + /* stat was successful, now redo the time-stamp fetches */ +# ifndef NO_W32TIMES_IZFIX + int fs_uses_loctime = FStampIsLocTimeW(__G__ pathw); +# endif + HANDLE h; + FILETIME Modft, Accft, Creft; + + TTrace((stdout, "stat(%s) finds modtime %08lx\n", path, buf->st_mtime)); + h = CreateFileW(pathw, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (h != INVALID_HANDLE_VALUE) { + BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft); + CloseHandle(h); + + if (ftOK) { + FTTrace((stdout, "GetFileTime returned Modft", 0, &Modft)); + FTTrace((stdout, "GetFileTime returned Creft", 0, &Creft)); +# ifndef NO_W32TIMES_IZFIX + if (!fs_uses_loctime) { + /* On a filesystem that stores UTC timestamps, we refill + * the time fields of the struct stat buffer by directly + * using the UTC values as returned by the Win32 + * GetFileTime() API call. + */ + NtfsFileTime2utime(&Modft, &(buf->st_mtime)); + if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0) + NtfsFileTime2utime(&Accft, &(buf->st_atime)); + else + buf->st_atime = buf->st_mtime; + if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0) + NtfsFileTime2utime(&Creft, &(buf->st_ctime)); + else + buf->st_ctime = buf->st_mtime; + TTrace((stdout,"NTFS, recalculated modtime %08lx\n", + buf->st_mtime)); + } else +# endif /* NO_W32TIMES_IZFIX */ + { + /* On VFAT and FAT-like filesystems, the FILETIME values + * are converted back to the stable local time before + * converting them to UTC unix time-stamps. + */ + VFatFileTime2utime(&Modft, &(buf->st_mtime)); + if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0) + VFatFileTime2utime(&Accft, &(buf->st_atime)); + else + buf->st_atime = buf->st_mtime; + if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0) + VFatFileTime2utime(&Creft, &(buf->st_ctime)); + else + buf->st_ctime = buf->st_mtime; + TTrace((stdout, "VFAT, recalculated modtime %08lx\n", + buf->st_mtime)); + } + } + } + izu_free(path); + + return 0; + } +# ifdef W32_STATROOT_FIX + else + { + DWORD flags; + + flags = GetFileAttributesW(pathw); + if ((flags != INVALID_FILE_ATTRIBUTES) && + (flags & FILE_ATTRIBUTE_DIRECTORY)) { +# ifdef Tracing + char *path = wchar_to_local_string((wchar_t *)pathw, G.unicode_escape_all); + Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n", + + + FnFilter1(path))); + izu_free(path); +# endif /* def Tracing */ + memset(buf, 0, sizeof(z_stat)); + buf->st_atime = buf->st_ctime = buf->st_mtime = + dos_to_unix_time(DOSTIME_MINIMUM); /* 1-1-80 */ + buf->st_mode = S_IFDIR | S_IREAD | + ((flags & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE); + return 0; + } /* assumes: stat() won't fail on non-dirs without good reason */ + } +# endif /* W32_STATROOT_FIX */ + return -1; +} + +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + +# endif /* W32_STAT_BANDAID */ + + + +# ifdef W32_USE_IZ_TIMEZONE +#include "timezone.h" +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule); + +static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule) +{ + if (lpw32tm->wYear != 0) { + ptrule->r_type = JULIAN_DAY; + ptrule->r_day = ydays[lpw32tm->wMonth - 1] + lpw32tm->wDay; + } else { + ptrule->r_type = MONTH_NTH_DAY_OF_WEEK; + ptrule->r_mon = lpw32tm->wMonth; + ptrule->r_day = lpw32tm->wDayOfWeek; + ptrule->r_week = lpw32tm->wDay; + } + ptrule->r_time = (long)lpw32tm->wHour * SECSPERHOUR + + (long)(lpw32tm->wMinute * SECSPERMIN) + + (long)lpw32tm->wSecond; +} + +int GetPlatformLocalTimezone(register struct state * ZCONST sp, + void (*fill_tzstate_from_rules)(struct state * ZCONST sp_res, + ZCONST struct rule * ZCONST start, + ZCONST struct rule * ZCONST end)) +{ + TIME_ZONE_INFORMATION tzinfo; + DWORD res; + + /* read current timezone settings from registry if TZ envvar missing */ + res = GetTimeZoneInformation(&tzinfo); + if (res != TIME_ZONE_ID_INVALID) + { + struct rule startrule, stoprule; + + conv_to_rule(&(tzinfo.StandardDate), &stoprule); + conv_to_rule(&(tzinfo.DaylightDate), &startrule); + sp->timecnt = 0; + sp->ttis[0].tt_abbrind = 0; + if ((sp->charcnt = + WideCharToMultiByte(CP_ACP, 0, tzinfo.StandardName, -1, + sp->chars, sizeof(sp->chars), NULL, NULL)) + == 0) + sp->chars[sp->charcnt++] = '\0'; + sp->ttis[1].tt_abbrind = sp->charcnt; + sp->charcnt += + WideCharToMultiByte(CP_ACP, 0, tzinfo.DaylightName, -1, + sp->chars + sp->charcnt, + sizeof(sp->chars) - sp->charcnt, NULL, NULL); + if ((sp->charcnt - sp->ttis[1].tt_abbrind) == 0) + sp->chars[sp->charcnt++] = '\0'; + sp->ttis[0].tt_gmtoff = - (tzinfo.Bias + tzinfo.StandardBias) + * MINSPERHOUR; + sp->ttis[1].tt_gmtoff = - (tzinfo.Bias + tzinfo.DaylightBias) + * MINSPERHOUR; + sp->ttis[0].tt_isdst = 0; + sp->ttis[1].tt_isdst = 1; + sp->typecnt = (startrule.r_mon == 0 && stoprule.r_mon == 0) ? 1 : 2; + + if (sp->typecnt > 1) + (*fill_tzstate_from_rules)(sp, &startrule, &stoprule); + return TRUE; + } + return FALSE; +} +# endif /* W32_USE_IZ_TIMEZONE */ + +#endif /* !FUNZIP */ + + + +#ifndef WINDLL +/* This replacement getch() function was originally created for Watcom C + * and then additionally used with CYGWIN. Since UnZip 5.4, all other Win32 + * ports apply this replacement rather that their supplied getch() (or + * alike) function. There are problems with unabsorbed LF characters left + * over in the keyboard buffer under Win95 (and 98) when ENTER was pressed. + * (Under Win95, ENTER returns two(!!) characters: CR-LF.) This problem + * does not appear when run on a WinNT console prompt! + */ + +/* Watcom 10.6's getch() does not handle Alt+. */ +/* Note that if PASSWD_FROM_STDIN is defined, the file containing */ +/* the password must have a carriage return after the word, not a */ +/* Unix-style newline (linefeed only). This discards linefeeds. */ + +int getch_win32(void) +{ + HANDLE stin; + DWORD rc; + unsigned char buf[2]; + int ret = -1; + DWORD odemode = ~(DWORD)0; + +# ifdef PASSWD_FROM_STDIN + stin = GetStdHandle(STD_INPUT_HANDLE); +# else + stin = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (stin == INVALID_HANDLE_VALUE) + return -1; +# endif + if (GetConsoleMode(stin, &odemode)) + SetConsoleMode(stin, ENABLE_PROCESSED_INPUT); /* raw except ^C noticed */ + if (ReadFile(stin, &buf, 1, &rc, NULL) && rc == 1) + ret = buf[0]; + /* when the user hits return we get CR LF. We discard the LF, not the CR, + * because when we call this for the first time after a previous input + * such as the one for "replace foo? [y]es, ..." the LF may still be in + * the input stream before whatever the user types at our prompt. */ + if (ret == '\n') + if (ReadFile(stin, &buf, 1, &rc, NULL) && rc == 1) + ret = buf[0]; + if (odemode != ~(DWORD)0) + SetConsoleMode(stin, odemode); +# ifndef PASSWD_FROM_STDIN + CloseHandle(stin); +# endif + return ret; +} +#endif /* !WINDLL */ + + + +#if (defined(UNICODE_SUPPORT) && !defined(FUNZIP)) +/* convert wide character string to multi-byte character string */ +char *wide_to_local_string(wide_string, escape_all) + ZCONST zwchar *wide_string; + int escape_all; +{ + int i; + wchar_t wc; + int bytes_char; + int default_used; + int wsize = 0; + int max_bytes = 9; + char buf[9]; + char *buffer = NULL; + char *local_string = NULL; + + for (wsize = 0; wide_string[wsize]; wsize++) ; + + if (max_bytes < MB_CUR_MAX) + max_bytes = MB_CUR_MAX; + + if ((buffer = (char *)izu_malloc(wsize * max_bytes + 1)) == NULL) { + return NULL; + } + + /* convert it */ + buffer[0] = '\0'; + for (i = 0; i < wsize; i++) { + if (sizeof(wchar_t) < 4 && wide_string[i] > 0xFFFF) { + /* wchar_t probably 2 bytes */ + /* could do surrogates if state_dependent and wctomb can do */ + wc = zwchar_to_wchar_t_default_char; + } else { + wc = (wchar_t)wide_string[i]; + } + /* Under some vendor's C-RTL, the Wide-to-MultiByte conversion functions + * (like wctomb() et. al.) do not use the same codepage as the other + * string arguments I/O functions (fopen, mkdir, rmdir etc.). + * Therefore, we have to fall back to the underlying Win32-API call to + * achieve a consistent behaviour for all supported compiler environments. + * Failing RTLs are for example: + * Borland (locale uses OEM-CP as default, but I/O functions expect ANSI + * names) + * Watcom (only "C" locale, wctomb() always uses OEM CP) + * (in other words: all supported environments except the Microsoft RTLs) + */ + bytes_char = WideCharToMultiByte( + CP_ACP, WC_COMPOSITECHECK, + &wc, 1, + (LPSTR)buf, sizeof(buf), + NULL, &default_used); + if (default_used) + bytes_char = -1; + if (escape_all) { + if (bytes_char == 1 && (uch)buf[0] <= 0x7f) { + /* ASCII */ + strncat(buffer, buf, 1); + } else { + /* use escape for wide character */ + char *escape_string = wide_to_escape_string(wide_string[i]); + strcat(buffer, escape_string); + izu_free(escape_string); + } + } else if (bytes_char > 0) { + /* multi-byte char */ + strncat(buffer, buf, bytes_char); + } else { + /* no MB for this wide */ + /* use escape for wide character */ + char *escape_string = wide_to_escape_string(wide_string[i]); + strcat(buffer, escape_string); + izu_free(escape_string); + } + } + if ((local_string = (char *)izu_realloc( + buffer, strlen(buffer) + 1)) == NULL) { + izu_free(buffer); + return NULL; + } + + return local_string; +} + + +wchar_t *local_to_wchar_string(local_string) + char *local_string; /* path of local name */ +{ + wchar_t *qw; + int ulen; + int ulenw; + + if (local_string == NULL) + return NULL; + + /* get length */ + ulenw = MultiByteToWideChar( + CP_ACP, /* ANSI code page */ + 0, /* flags for character-type options */ + local_string, /* string to convert */ + -1, /* string length (-1 = NULL terminated) */ + NULL, /* buffer */ + 0 ); /* buffer length (0 = return length) */ + + if (ulenw == 0) { + /* failed */ + return NULL; + } + /* Allocate bytes for returned wide char count (which includes NUL). */ + if ((qw = (wchar_t *)izu_malloc( ulenw* sizeof(wchar_t))) == NULL) { + return NULL; + } + /* convert multibyte to wide */ + ulen = MultiByteToWideChar( + CP_ACP, /* ANSI code page */ + 0, /* flags for character-type options */ + local_string, /* string to convert */ + -1, /* string length (-1 = NULL terminated) */ + qw, /* buffer */ + ulenw); /* buffer length (0 = return length) */ + if (ulen == 0) { + /* failed */ + izu_free(qw); + return NULL; + } + + return qw; +} + +# if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) +# if defined( DYNAMIC_WIDE_NAME) || defined( SYMLINKS) +wchar_t *utf8_to_wchar_string_dyn(utf8_string) + const char *utf8_string; /* path to get utf-8 name for */ +{ + wchar_t *qw; + int ulen; + int ulenw; + + if (utf8_string == NULL) + return NULL; + + /* get length */ + ulenw = MultiByteToWideChar( + CP_UTF8, /* UTF-8 code page */ + 0, /* flags for character-type options */ + utf8_string, /* string to convert */ + -1, /* string length (-1 = NULL terminated) */ + NULL, /* buffer */ + 0); /* buffer length (0 = return length) */ + + if (ulenw == 0) { + /* failed */ + return NULL; + } + + /* Allocate bytes for returned wide char count (which includes NUL). */ + if ((qw = (wchar_t *)izu_malloc( ulenw* sizeof(wchar_t))) == NULL) { + return NULL; + } + + /* convert multibyte to wide */ + ulen = MultiByteToWideChar( + CP_UTF8, /* UTF-8 code page */ + 0, /* flags for character-type options */ + utf8_string, /* string to convert */ + -1, /* string length (-1 = NULL terminated) */ + qw, /* buffer */ + ulenw); /* buffer length (0 = return length) */ + + if (ulen == 0) { + /* failed */ + izu_free(qw); + return NULL; + } + + return qw; +} +# endif /* defined( DYNAMIC_WIDE_NAME) || defined( SYMLINKS) */ + +# ifndef DYNAMIC_WIDE_NAME +void utf8_to_wchar_string_stat( resultw, utf8_string) + wchar_t *resultw; /* User's result buffer. */ + const char *utf8_string; /* path to get utf-8 name for */ +{ + int ulen; + + *resultw = L'\0'; /* Default to failure (null result). */ + + if (utf8_string == NULL) + return; + + /* Convert multibyte to wide. */ + ulen = MultiByteToWideChar( + CP_UTF8, /* UTF-8 code page. */ + 0, /* Flags for character-type options. */ + utf8_string, /* String to convert. */ + -1, /* String length (-1 = NULL terminated). */ + resultw, /* User's buffer. */ + FILNAMSIZ); /* Buffer length (chars, incl. NUL). */ + + if (ulen == 0) { + /* failed */ + *resultw = L'\0'; /* Unnecessessary? */ + } + + return; +} +# endif /* ndef DYNAMIC_WIDE_NAME */ + +int has_win32_wide() +{ + int is_win32_wide; + + /* test if we have wide function support */ + /* first guess: On "real" WinNT, the WIN32 wide API >>is<< supported. */ + is_win32_wide = IsWinNT(); + + if (!is_win32_wide) + { + /* On a non-WinNT environment (Win9x or Win32s), wide functions + * might be supported when program is linked against the + * Win9x Unicode support library. + * => run a check whether a needed API function is supported. + */ + DWORD r; + /* get attributes for this directory */ + r = GetFileAttributesA("."); + + /* r should include 16 = FILE_ATTRIBUTE_DIRECTORY */ + if ((r != INVALID_FILE_ATTRIBUTES) && (r & FILE_ATTRIBUTE_DIRECTORY)) { + /* now see if it works for the wide version */ + r = GetFileAttributesW(L"."); + /* if this fails then we probably don't have wide functions */ + /* error is probably "This function is only valid in Win32 mode." */ + if ((r != INVALID_FILE_ATTRIBUTES) && (r & FILE_ATTRIBUTE_DIRECTORY)) { + /* worked, so conclude we have wide support */ + is_win32_wide = TRUE; + } + } + } + return is_win32_wide; +} + +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ + +#endif /* (defined(UNICODE_SUPPORT) && !defined(FUNZIP)) */ + + +/* Symbolic link (symlink) support. */ + +#ifdef SYMLINKS + +/* symlink[w](): Create a symbolic link. + * Return zero, if success; non-zero, if failure. + */ + +int symlink( const char *target, const char *name, int is_dir) +{ + int sts; + + /* Flags arg (3) is SYMBOLIC_LINK_FLAG_DIRECTORY if the target is a + * directory. + */ + if (CreateSymbolicLinkA( name, target, + (is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0))) + { + sts = 0; + } + else + { + sts = GetLastError(); + } + return sts; +} + + +# ifdef UNICODE_SUPPORT + +int symlinkw( const char *target, const wchar_t *namew, int is_dir) +{ + int sts; + wchar_t *targetw; + + /* Convert UTF-8 target to UTF-16. */ + targetw = utf8_to_wchar_string_dyn( target); + if (targetw == NULL) + { + sts = -1; + } + else + { + /* Flags arg (3) is SYMBOLIC_LINK_FLAG_DIRECTORY if the target is a + * directory. + */ + if (CreateSymbolicLinkW( namew, targetw, + (is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0))) + { + sts = 0; + } + else + { + sts = GetLastError(); + } + free( targetw); + } + return sts; +} + +# endif /* def UNICODE_SUPPORT */ + +#endif /* def SYMLINKS */ + + +/* --------------------------------------------------- */ +/* Large File Support + * + * Initial functions by E. Gordon and R. Nausedat + * 9/10/2003 + * Lifted from Zip 3b, win32.c and place here by Myles Bennett + * 7/6/2004 + * + * These implement 64-bit file support for Windows. The + * defines and headers are in win32/w32cfg.h. + * + * Moved to win32i64.c by Mike White to avoid conflicts in + * same name functions in WiZ using UnZip and Zip libraries. + * 9/25/2003 + */ diff --git a/process.c b/process.c index ea41c09..7b9bc5b 100644 --- a/process.c +++ b/process.c @@ -2961,7 +2961,7 @@ zwchar *wchar_to_wide_string(wchar_string) zwchar *local_to_wide_string(local_string) ZCONST char *local_string; { - int wsize; + size_t wsize; wchar_t *wc_string; zwchar *wide_string; diff --git a/unzip.c b/unzip.c index 0528ce5..a91fe34 100644 --- a/unzip.c +++ b/unzip.c @@ -3762,7 +3762,7 @@ static void show_options(__G) __GDEF { extent i; - int lolen; + size_t lolen; char optiontext[200]; char gr[4]; char sh[7]; @@ -4580,7 +4580,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar, int depth; { ZCONST char *shortopt; - int clen; + size_t clen; ZCONST char *nextchar; ZCONST char *s; ZCONST char *start; @@ -4595,7 +4595,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar, nextchar = arg + (*optchar); clen = MB_CLEN(nextchar); /* next char in arg */ - (*optchar) += clen; + (*optchar) += (int)clen; /* get first char of short option */ shortopt = arg + (*optchar); /* no value */ @@ -4653,7 +4653,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar, } else { *negated = 1; /* set up to skip negating dash */ - (*optchar) += clen; + (*optchar) += (int)clen; clen = 1; } } @@ -4683,7 +4683,7 @@ static unsigned long get_shortopt(__G__ option_group, args, argnum, optchar, } (*value)[0] = *(arg + (*optchar) + clen); (*value)[1] = '\0'; - *optchar += clen; + *optchar += (int)clen; clen = 1; } else { /* one char values require a value */ diff --git a/unzpriv.h b/unzpriv.h index f14f536..4ac907f 100644 --- a/unzpriv.h +++ b/unzpriv.h @@ -1081,10 +1081,16 @@ void izu_md_check( void); # endif #endif +/* Zlib includes its own CRC32 code, obviating ours. */ #if (defined(USE_ZLIB) && defined(ASM_CRC)) # undef ASM_CRC #endif +/* Do not use our (32-bit) assembly code for 64-bit Windows. */ +#if (defined(_WIN64) && defined(ASM_CRC)) +# undef ASM_CRC +#endif + #ifdef USE_ZLIB # ifdef IZ_CRC_BE_OPTIMIZ # undef IZ_CRC_BE_OPTIMIZ @@ -3285,7 +3291,7 @@ char *GetLoadPath OF((__GPRO)); /* local */ #ifdef _MBCS # define STRLOWER(str1, str2) \ { \ - char *p, *q, c; unsigned i; \ + char *p, *q, c; size_t i; \ p = (char *)(str1); \ q = (char *)(str2); \ while ((c = *p) != '\0') { \ diff --git a/unzvers.h b/unzvers.h index 21e34e3..7f8cf21 100644 --- a/unzvers.h +++ b/unzvers.h @@ -24,8 +24,8 @@ # endif # ifdef BETA -# define UZ_BETALEVEL "c11 BETA" -# define UZ_VERSION_DATE "10 Oct 2014" /* Internal beta version. */ +# define UZ_BETALEVEL "c12 BETA" +# define UZ_VERSION_DATE "11 Nov 2014" /* Internal beta version. */ # else # define UZ_BETALEVEL "" # define UZ_VERSION_DATE "?? ??? 2014" /* Official release version. */ diff --git a/vms/INSTALL_VMS.txt b/vms/INSTALL_VMS.txt index cc692a2..c55b753 100644 --- a/vms/INSTALL_VMS.txt +++ b/vms/INSTALL_VMS.txt @@ -1,7 +1,7 @@ INSTALL_VMS.txt -- UnZip Installation Supplement for VMS (OpenVMS) ================================================================== - UnZip version 6.10. Revised: 2014-10-10. + UnZip version 6.10. Revised: 2014-10-20. ------------------------------------------------------------------------ @@ -154,7 +154,7 @@ the user to request large-file support explicitly. Now it must be disabled explicitly, if it's not desired.) On Alpha, the builders will initially assume that large-file - support is available, but will test large-file support before + support is available, but will test large-file support before continuing. If large-file support is not available, the build will fail, and a message will advise the user to add "NOLARGE" to the build command. @@ -278,6 +278,15 @@ adding NO_CRYPT to the LOCAL_UNZIP symbol/macro. For example: More Complex Build Examples --------------------------- + When doing complex or multiple builds, note that the MMS (or MMK) +builders offer a set of CLEAN* targets, which can be used to remove some +or all old build products (object files, object libraries, executables, +and so on). It's usually a good idea to do some kind of "MMS CLEAN" +before making significant changes to the build options. The DCL-script +builder, [.vms]build_zip.com, has no such options, so its users must +manually clean out any old build products when necessary, including any +bzip2 products which are created under the [.bzip2] subdirectory. + Here are some more complex build examples: o Build with the large-file option disabled (non-VAX, typically used @@ -352,7 +361,7 @@ the default UNIX-like command-line interface, UNZIP_CLI.HLP for the VMS-like command-line interface) are placed in the main directory. With a mixed-architecture VMS cluster, the same main directory on a shared disk may be used by all system types. (Using the NOHELP option with -BUILD_UNZIP.COM can keep it from making the same help files repeatedly.) +build_unzip.com can keep it from making the same help files repeatedly.) Building the help files is detailed below. ------------------------------------------------------------------------ @@ -458,11 +467,11 @@ a command like: HELP /LIBRARY = device:[directory]UNZIP.HLB For greater ease, the user (or system manager) may define a -HLP$LIBRARY logical name to allow the HELP utility to find the UnZip help -library automatically. See HELP HELP /USERLIBRARY for more details. -The command procedure [.vms]hlp_lib_next.com may be used to determine -the next available HLP$LIBRARY logical name, and could be adapted to -define a HLP$LIBRARY logical name for an UnZip help library. +HLP$LIBRARY logical name to allow the HELP utility to find the UnZip +help library automatically. See HELP HELP /USERLIBRARY for more +details. The command procedure [.vms]hlp_lib_next.com may be used to +determine the next available HLP$LIBRARY logical name, and could be +adapted to define a HLP$LIBRARY logical name for an UnZip help library. The builders also create VMS message files, UNZIP_MSG.EXE, in the destination directory with the program executables. A user may gain DCL diff --git a/vms/build_unzip.com b/vms/build_unzip.com index 858dc02..5431d64 100755 --- a/vms/build_unzip.com +++ b/vms/build_unzip.com @@ -2,7 +2,7 @@ $! BUILD_UNZIP.COM $! $! UnZip 6.10 for VMS -- DCL Build procedure. $! -$! Last revised: 2014-10-09 SMS. +$! Last revised: 2014-10-20 SMS. $! $!---------------------------------------------------------------------- $! Copyright (c) 2004-2014 Info-ZIP. All rights reserved. @@ -28,7 +28,7 @@ $! - Direct bzip2 support: "IZ_BZIP2=dev:[dir]" $! Disable bzip2 support: "NOIZ_BZIP2" $! By default, bzip2 support is enabled, and uses the bzip2 source $! kit supplied in the [.bzip2] directory. Specify NOIZ_BZIP2 -$! to disable bzip2 support. Specify IZ_BZIP2 with a value +$! to disable bzip2 support. Specify IZ_BZIP2 with a value $! ("dev:[dir]", or a suitable logical name) to use the bzip2 $! header file and object library found there. The bzip2 object $! library (LIBBZ2_NS.OLB) is expected to be in a simple "[.dest]" @@ -120,6 +120,18 @@ $! of "VMSCLI" now is the selection of the VMS CLI style UnZip $! executable in the foreign command definition.) $! $! +$! Save the current default disk:[directory], and set default to the +$! directory above where this procedure is situated (which had better be +$! the main distribution directory). +$! +$ here = f$environment( "default") +$ here = f$parse( here, , , "device")+ f$parse( here, , , "directory") +$! +$ proc = f$environment( "procedure") +$ proc_dir = f$parse( proc, , , "device")+ f$parse( proc, , , "directory") +$ set default 'proc_dir' +$ set default [-] +$! $ on error then goto error $ on control_y then goto error $ OLD_VERIFY = f$verify( 0) @@ -127,7 +139,7 @@ $! $ edit := edit ! override customized edit commands $ say := write sys$output $! -$!##################### Read settings from environment ######################## +$! Get LOCAL_UNZIP symbol options. $! $ if (f$type( LOCAL_UNZIP) .eqs. "") $ then @@ -159,7 +171,7 @@ $ endif $ delete /symbol /local pos_cli $ delete /symbol /local len_local_unzip $! -$!##################### Customizing section ############################# +$! Various library and program names. $! $ unzx_unx = "UNZIP" $ unzx_cli = "UNZIP_CLI" @@ -171,6 +183,8 @@ $ lib_unzipcli_name = "UNZIPCLI.OLB" $ lib_unzipsfx_name = "UNZIPSFX.OLB" $ lib_unzipsfxcli_name = "UNZSFXCLI.OLB" $! +$! Analyze command-line options. +$! $ AES_WG = 0 $ BUILD_BZIP2 = 0 $ CCOPTS = "" @@ -226,6 +240,12 @@ $ DASHV = 1 $ goto argloop_end $ endif $! +$ if (f$extract( 0, 9, curr_arg) .eqs. "HELP_TEXT") +$ then +$ MAKE_HELP_TEXT = 1 +$ goto argloop_end +$ endif +$! $ if (f$extract( 0, 7, curr_arg) .eqs. "IZ_BZIP") $ then $ opts = f$edit( curr_arg, "COLLAPSE") @@ -234,6 +254,14 @@ $ IZ_BZIP2 = f$extract( (eq+ 1), 1000, opts) $ goto argloop_end $ endif $! +$ if (f$extract( 0, 7, curr_arg) .eqs. "IZ_ZLIB") +$ then +$ opts = f$edit( curr_arg, "COLLAPSE") +$ eq = f$locate( "=", opts) +$ IZ_ZLIB = f$extract( (eq+ 1), 1000, opts) +$ goto argloop_end +$ endif +$! $ if ((f$extract( 0, 8, curr_arg) .eqs. "NOAES_WG") .or. - (f$extract( 0, 9, curr_arg) .eqs. "NO_AES_WG")) $ then @@ -248,12 +276,6 @@ $ NOIZ_BZIP2 = 1 $ goto argloop_end $ endif $! -$ if (f$extract( 0, 9, curr_arg) .eqs. "HELP_TEXT") -$ then -$ MAKE_HELP_TEXT = 1 -$ goto argloop_end -$ endif -$! $ if (f$extract( 0, 7, curr_arg) .eqs. "IZ_ZLIB") $ then $ opts = f$edit( curr_arg, "COLLAPSE") @@ -397,6 +419,7 @@ $ TEST_PPMD = 1 $ goto argloop_end $ endif $! +$ say "" $ say "Unrecognized command-line option: ''curr_arg'" $ goto error $! @@ -412,12 +435,7 @@ $ else $ UNZEXEC = unzx_unx $ endif $! -$!####################################################################### -$! -$! Find out current disk, directory, compiler and options -$! -$ workdir = f$environment( "default") -$ here = f$parse( workdir, , , "device")+ f$parse( workdir, , , "directory") +$! Build. $! $! Sense the host architecture (Alpha, Itanium, or VAX). $! @@ -450,6 +468,7 @@ $ USE_DECC_VAX = 0 $! $ if (MAY_USE_GNUC) $ then +$ say "" $ say "GNU C is not supported for ''arch'." $ say "You must use DEC/Compaq/HP C to build UnZip." $ goto error @@ -457,6 +476,7 @@ $ endif $! $ if (.not. MAY_USE_DECC) $ then +$ say "" $ say "VAX C is not supported for ''arch'." $ say "You must use DEC/Compaq/HP C to build UnZip." $ goto error @@ -473,7 +493,7 @@ $ if (LARGE_FILE .gt. 0) $ then $ say "LARGE_FILE_SUPPORT is not available on VAX." $ endif - LARGE_FILE = -1 +$ LARGE_FILE = -1 $ HAVE_DECC_VAX = (f$search( "SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "") $ HAVE_VAXC_VAX = (f$search( "SYS$SYSTEM:VAXC.EXE") .nes. "") $ MAY_HAVE_GNUC = (f$trnlnm( "GNU_CC") .nes. "") @@ -556,7 +576,7 @@ $ if (vaxc .ne. 0) $ then $ defs = defs+ ", NO_SIGNED_CHAR" $ endif -$ if (NOLZMA .le. 0) +$ if (NOLZMA .gt. 0) $ then $ defs = defs+ ", _SZ_NO_INT_64" $ endif @@ -675,6 +695,7 @@ $ then $ @ [.VMS]FIND_BZIP2_LIB.COM 'IZ_BZIP2' 'seek_bz' 'bz2_olb' lib_bzip2 $ if (f$trnlnm( "lib_bzip2") .eqs. "") $ then +$ say "" $ say "Can't find BZIP2 object library. Can't link." $ goto error $ else @@ -695,6 +716,7 @@ $ defs = "''defs', USE_ZLIB" $ @ [.VMS]FIND_BZIP2_LIB.COM 'IZ_ZLIB' 'seek_zl' 'zlib_olb' lib_zlib $ if (f$trnlnm( "lib_zlib") .eqs. "") $ then +$ say "" $ say "Can't find ZLIB object library. Can't link." $ goto error $ else @@ -714,6 +736,7 @@ $ create /directory [.'dest'] $ else $ if (MAKE_EXE .or. MAKE_MSG) $ then +$ say "" $ say "Can't find directory ""[.''dest']"". Can't link." $ goto error $ endif @@ -727,11 +750,11 @@ $ then $ @ [.vms]check_large.com 'dest' large_file_ok $ if (f$trnlnm( "large_file_ok") .eqs. "") $ then -$ deassign large_file_ok +$ say "" $ say "Large-file support not available (OS/CRTL too old?)." +$ say "Add ""NOLARGE"" to the command." $ goto error $ endif -$ deassign large_file_ok $ endif $! $ if (MAKE_OBJ) @@ -926,11 +949,10 @@ $ cc 'DEF_UNX' /object = [.'dest']PPMD8.OBJ [.SZIP]PPMD8.C $ cc 'DEF_UNX' /object = [.'dest']PPMD8DEC.OBJ [.SZIP]PPMD8DEC.C $ endif $! +$! Create the callable library link options file, if needed. +$! $ if (LIBUNZIP .ne. 0) $ then -$! -$! Create the callable library link options file. -$! $ def_dev_dir_orig = f$environment( "default") $ set default [.'dest'] $ def_dev_dir = f$environment( "default") @@ -957,7 +979,6 @@ $ then $ write opt_file_lib "''libunzip_opt'" - ", " - "," $ endif $ close opt_file_lib -$! $ endif $! $ endif @@ -1092,7 +1113,6 @@ $ @ [.vms]optgen.com UnZip iz_unzip_versn $ open /write opt_file_ln SYS$DISK:[.'dest']UNZIP.OPT $ write opt_file_ln "Ident = ""UnZip ''f$trnlnm( "iz_unzip_versn")'""" $ close opt_file_ln -$ deassign iz_unzip_versn $ tmp = f$verify( optgen_verify) $! $! Link the executable. @@ -1273,7 +1293,6 @@ $ @ [.vms]optgen.com UnZip iz_unzip_versn $ open /write opt_file_ln SYS$DISK:[.'dest']UNZIPSFX.OPT $ write opt_file_ln "Ident = ""UnZipSFX ''f$trnlnm( "iz_unzip_versn")'""" $ close opt_file_ln -$ deassign iz_unzip_versn $ tmp = f$verify( optgen_verify) $! $! Link the SFX executable. @@ -1358,6 +1377,14 @@ $ then $ deassign iz_unzip_versn $ endif $! +$ if (arch .eqs. "ALPHA") +$ then +$ if (f$trnlnm( "large_file_ok", "LNM$PROCESS_TABLE") .nes. "") +$ then +$ deassign large_file_ok +$ endif +$ endif +$! $ if (IZ_BZIP2 .nes. "") $ then $ if (f$trnlnm( "incl_bzip2", "LNM$PROCESS_TABLE") .nes. "") diff --git a/vms/descrip.mms b/vms/descrip.mms index 48f1321..6c8a3f5 100644 --- a/vms/descrip.mms +++ b/vms/descrip.mms @@ -2,7 +2,7 @@ # # UnZip 6.10 for VMS -- MMS (or MMK) Description File. # -# Last revised: 2014-10-08 +# Last revised: 2014-11-10 # #---------------------------------------------------------------------- # Copyright (c) 2001-2014 Info-ZIP. All rights reserved. @@ -22,12 +22,13 @@ # # Optional macros: # -# AES_WG=1 Enable/disable AES_WG encryption support. Specify -# NOAES_WG=1 either AES_WG=1 or NOAES_WG=1 to skip the [.aes_wg] -# source directory test. By default, the SFX programs -# are built without AES_WG support. Add -# "CRYPT_AES_WG_SFX=1" to the LOCAL_UNZIP C macros to -# enable it. (See LOCAL_UNZIP, below.) +# AES_WG=1 Enable/disable AES (WinZip/Gladman) encryption +# NOAES_WG=1 support. Specify either AES_WG=1 or NOAES_WG=1 to +# skip the [.aes_wg] source directory test. +# By default, the SFX programs are built without +# AES_WG support. Add "CRYPT_AES_WG_SFX=1" to the +# LOCAL_UNZIP C macros to enable it. (See +# LOCAL_UNZIP, below.) # # CCOPTS=xxx Compile with CC options xxx. For example: # CCOPTS=/ARCH=HOST @@ -36,15 +37,15 @@ # TRC=1 Default is /NOTRACEBACK, but TRC=1 enables link with # /TRACEBACK without compiling for debug. # -# IZ_BZIP2=dev:[dir] Direct/disable with optional bzip2 support. -# NOIZ_BZIP2=1 By default, bzip2 support is enabled, and uses -# the bzip2 source kit supplied in the [.bzip2] -# directory. Specify NOIZ_BZIP2=1 to disable bzip2 -# support. Specify IZ_BZIP2 with a value -# ("dev:[dir]", or a suitable logical name) to use the -# bzip2 header file and object library found there. -# The bzip2 object library (LIBBZ2_NS.OLB) is expected -# to be in a simple "[.dest]" directory under that one +# IZ_BZIP2=dev:[dir] Direct/disable optional bzip2 support. By +# NOIZ_BZIP2=1 default, bzip2 support is enabled, and uses the +# bzip2 source kit supplied in the [.bzip2] directory. +# Specify NOIZ_BZIP2=1 to disable bzip2 support. +# Specify IZ_BZIP2 with a value ("dev:[dir]", or a +# suitable logical name) to use the bzip2 header file +# and object library found there. The bzip2 object +# library (LIBBZ2_NS.OLB) is expected to be in a +# simple "[.dest]" directory under that one # ("dev:[dir.ALPHAL]", for example), or in that # directory itself.) By default, the SFX programs are # built without bzip2 support. Add "BZIP2_SFX=1" to @@ -52,11 +53,11 @@ # LOCAL_UNZIP, below.) # # IZ_ZLIB=dev:[dir] Use ZLIB compression library instead of internal -# compression routines. The value of the MMS -# macro ("dev:[dir]", or a suitable logical name) -# tells where to find "zlib.h". The ZLIB object -# library (LIBZ.OLB) is expected to be in a -# "[.dest]" directory under that one +# Deflate compression routines. The value of the +# MMS macro IZ_ZLIB ("dev:[dir]", or a suitable +# logical name) tells where to find "zlib.h". The +# ZLIB object library (LIBZ.OLB) is expected to be in +# a "[.dest]" directory under that one # ("dev:[dir.ALPHAL]", for example), or in that # directory itself. # @@ -92,8 +93,8 @@ # support. Add "PPMD_SFX=1" to the LOCAL_UNZIP C # macros to enable it. (See LOCAL_UNZIP, above.) # -# NOSHARE=1 Link /NOSYSSHR (not using shareable images). -# NOSHARE=OLDVAX Link /NOSYSSHR on VAX for: +# NOSYSSHR=1 Link /NOSYSSHR (not using shareable images). +# NOSYSSHR=OLDVAX Link /NOSYSSHR on VAX for: # DEC C with VMS before V7.3. # VAX C without DEC C RTL (DEC C not installed). # @@ -149,29 +150,37 @@ # # Example commands: # -# To build the conventional small-file product using the DEC/Compaq/HP C -# compiler (Note: DESCRIP.MMS is the default description file name.): +# To build the large-file product (except on VAX) with all the available +# optional compression methods using the DEC/Compaq/HP C compiler (Note: +# DESCRIP.MMS is the default description file name.): # # MMS /DESCRIP = [.VMS] # -# To get the large-file executables (on a non-VAX system): +# To get small-file executables (on a non-VAX system): # -# MMS /DESCRIP = [.VMS] /MACRO = (LARGE=1) +# MMS /DESCRIP = [.VMS] /MACRO = (NOLARGE=1) # # To delete the architecture-specific generated files for this system # type: # -# MMS /DESCRIP = [.VMS] /MACRO = (LARGE=1) CLEAN ! Large-file. -# or -# MMS /DESCRIP = [.VMS] CLEAN ! Small-file. +# MMS /DESCRIP = [.VMS] CLEAN +# MMS /DESCRIP = [.VMS] /MACRO = (NOLARGE=1) CLEAN ! Non-VAX, +# ! small-file. # -# To build a complete small-file product for debug with compiler -# listings and link maps: +# To build a complete product for debug with compiler listings and link +# maps: # # MMS /DESCRIP = [.VMS] CLEAN # MMS /DESCRIP = [.VMS] /MACRO = (DBG=1, LIST=1) # # +# Note that option macros like NOLARGE or PROD affect the destination +# directory for various product files, including executables, and +# various clean and test targets (CLEAN, DASHV, TEST, and so on) need +# to use the proper destination directory. Thus, if NOLARGE or PROD +# is specified for a build, then the same macro must be specified for +# the various clean and test targets, too. +# # Note that on a Unix system, LOCAL_UNZIP contains compiler # options, such as "-g" or "-DCRYPT_AES_WG_SFX", but on a VMS # system, LOCAL_UNZIP contains only C macros, such as @@ -243,15 +252,28 @@ ALL : $(UNZIP) $(UNZIP_CLI) $(UNZIPSFX) $(UNZIPSFX_CLI) $(UNZIP_HELP) \ $(UNZIP_MSG_EXE) $(LIB_LIBUNZIP) $(LIBUNZIP_OPT) @ write sys$output "Done." -# CLEAN target. Delete the [.$(DEST)] directory and everything in it. +# CLEAN* targets. These also similarly clean a local bzip2 directory. + +# CLEAN target. Delete: +# The [.$(DEST)] directory and everything in it. CLEAN : if (f$search( "[.$(DEST)]*.*") .nes. "") then - - delete [.$(DEST)]*.*;* - if (f$search( "$(DEST).dir") .nes. "") then - - set protection = w:d $(DEST).dir;* - if (f$search( "$(DEST).dir") .nes. "") then - - delete $(DEST).dir;* + delete /noconfirm [.$(DEST)]*.*;* + if (f$search( "$(DEST).DIR") .nes. "") then - + set protection = w:d $(DEST).DIR;* + if (f$search( "$(DEST).DIR") .nes. "") then - + delete /noconfirm $(DEST).DIR;* +.IFDEF BUILD_BZIP2 # BUILD_BZIP2 + @ write sys$output "" + @ write sys$output "Cleaning bzip2..." + def_dev_dir_orig = f$environment( "default") + set default $(IZ_BZIP2) + $(MMS) $(MMSQUALIFIERS) /DESCR=[.vms]descrip.mms - + $(IZ_BZIP2_MACROS) - + $(MMSTARGETS) + set default 'def_dev_dir_orig' +.ENDIF # BUILD_BZIP2 # CLEAN_ALL target. Delete: # The [.$(DEST)] directory and everything in it (CLEAN), @@ -264,49 +286,49 @@ CLEAN : # CLEAN_ALL : CLEAN if (f$search( "[.ALPHA*]*.*") .nes. "") then - - delete [.ALPHA*]*.*;* - if (f$search( "ALPHA*.dir", 1) .nes. "") then - - set protection = w:d ALPHA*.dir;* - if (f$search( "ALPHA*.dir", 2) .nes. "") then - - delete ALPHA*.dir;* + delete /noconfirm [.ALPHA*]*.*;* + if (f$search( "ALPHA*.DIR", 1) .nes. "") then - + set protection = w:d ALPHA*.DIR;* + if (f$search( "ALPHA*.DIR", 2) .nes. "") then - + delete /noconfirm ALPHA*.DIR;* if (f$search( "[.IA64*]*.*") .nes. "") then - - delete [.IA64*]*.*;* - if (f$search( "IA64*.dir", 1) .nes. "") then - - set protection = w:d IA64*.dir;* - if (f$search( "IA64*.dir", 2) .nes. "") then - - delete IA64*.dir;* + delete /noconfirm [.IA64*]*.*;* + if (f$search( "IA64*.DIR", 1) .nes. "") then - + set protection = w:d IA64*.DIR;* + if (f$search( "IA64*.DIR", 2) .nes. "") then - + delete /noconfirm IA64*.DIR;* if (f$search( "[.VAX*]*.*") .nes. "") then - - delete [.VAX*]*.*;* - if (f$search( "VAX*.dir", 1) .nes. "") then - - set protection = w:d VAX*.dir;* - if (f$search( "VAX*.dir", 2) .nes. "") then - - delete VAX*.dir;* + delete /noconfirm [.VAX*]*.*;* + if (f$search( "VAX*.DIR", 1) .nes. "") then - + set protection = w:d VAX*.DIR;* + if (f$search( "VAX*.DIR", 2) .nes. "") then - + delete /noconfirm VAX*.DIR;* if (f$search( "help_temp_*.*") .nes. "") then - - delete help_temp_*.*;* + delete /noconfirm help_temp_*.*;* if (f$search( "[.VMS]UNZIP_CLI.RNH") .nes. "") then - - delete [.VMS]UNZIP_CLI.RNH;* + delete /noconfirm [.VMS]UNZIP_CLI.RNH;* if (f$search( "UNZIP_CLI.HLP") .nes. "") then - - delete UNZIP_CLI.HLP;* + delete /noconfirm UNZIP_CLI.HLP;* if (f$search( "UNZIP_CLI.HTX") .nes. "") then - - delete UNZIP_CLI.HTX;* + delete /noconfirm UNZIP_CLI.HTX;* if (f$search( "UNZIP.HLP") .nes. "") then - - delete UNZIP.HLP;* + delete /noconfirm UNZIP.HLP;* if (f$search( "UNZIP.HTX") .nes. "") then - - delete UNZIP.HTX;* - if (f$search( "test_dir_*.dir;*") .nes. "") then - + delete /noconfirm UNZIP.HTX;* + if (f$search( "test_dir_*.DIR;*") .nes. "") then - set protection = w:d [.test_dir_*...]*.*;* - if (f$search( "test_dir_*.dir;*") .nes. "") then - - set protection = w:d test_dir_*.dir;* + if (f$search( "test_dir_*.DIR;*") .nes. "") then - + set protection = w:d test_dir_*.DIR;* if (f$search( "[.test_dir_*.*]*.*") .nes. "") then - - delete [.test_dir_*.*]*.*;* + delete /noconfirm [.test_dir_*.*]*.*;* if (f$search( "[.test_dir_*]*.*") .nes. "") then - - delete [.test_dir_*]*.*;* - if (f$search( "test_dir_*.dir;*") .nes. "") then - - delete test_dir_*.dir;* + delete /noconfirm [.test_dir_*]*.*;* + if (f$search( "test_dir_*.DIR;*") .nes. "") then - + delete /noconfirm test_dir_*.DIR;* if (f$search( "*.MMSD") .nes. "") then - - delete *.MMSD;* + delete /noconfirm *.MMSD;* if (f$search( "[.VMS]*.MMSD") .nes. "") then - - delete [.VMS]*.MMSD;* + delete /noconfirm [.VMS]*.MMSD;* @ write sys$output "" @ write sys$output "Note: This procedure will not" @ write sys$output " DELETE [.VMS]DESCRIP_DEPS.MMS;*" @@ -324,27 +346,57 @@ CLEAN_ALL : CLEAN CLEAN_EXE : if (f$search( "[.$(DEST)]*.EXE") .nes. "") then - - delete [.$(DEST)]*.EXE;* + delete /noconfirm [.$(DEST)]*.EXE;* +.IFDEF BUILD_BZIP2 # BUILD_BZIP2 + @ write sys$output "" + @ write sys$output "Cleaning bzip2..." + def_dev_dir_orig = f$environment( "default") + set default $(IZ_BZIP2) + $(MMS) $(MMSQUALIFIERS) /DESCR=[.vms]descrip.mms - + $(IZ_BZIP2_MACROS) - + $(MMSTARGETS) + set default 'def_dev_dir_orig' +.ENDIF # BUILD_BZIP2 # CLEAN_OLB target. Delete the object libraries in [.$(DEST)]. CLEAN_OLB : if (f$search( "[.$(DEST)]*.OLB") .nes. "") then - - delete [.$(DEST)]*.OLB;* + delete /noconfirm [.$(DEST)]*.OLB;* +.IFDEF BUILD_BZIP2 # BUILD_BZIP2 + @ write sys$output "" + @ write sys$output "Cleaning bzip2..." + def_dev_dir_orig = f$environment( "default") + set default $(IZ_BZIP2) + $(MMS) $(MMSQUALIFIERS) /DESCR=[.vms]descrip.mms - + $(IZ_BZIP2_MACROS) - + $(MMSTARGETS) + set default 'def_dev_dir_orig' +.ENDIF # BUILD_BZIP2 # CLEAN_TEST target. Delete the test directories, [.test_dir_*...]. CLEAN_TEST : - if (f$search( "test_dir_*.dir;*") .nes. "") then - + if (f$search( "test_dir_*.DIR;*") .nes. "") then - set protection = w:d [.test_dir_*...]*.*;* - if (f$search( "test_dir_*.dir;*") .nes. "") then - - set protection = w:d test_dir_*.dir;* + if (f$search( "test_dir_*.DIR;*") .nes. "") then - + set protection = w:d test_dir_*.DIR;* if (f$search( "[.test_dir_*.*]*.*") .nes. "") then - - delete [.test_dir_*.*]*.*;* + delete /noconfirm [.test_dir_*.*]*.*;* if (f$search( "[.test_dir_*]*.*") .nes. "") then - - delete [.test_dir_*]*.*;* - if (f$search( "test_dir_*.dir;*") .nes. "") then - - delete test_dir_*.dir;* + delete /noconfirm [.test_dir_*]*.*;* + if (f$search( "test_dir_*.DIR;*") .nes. "") then - + delete /noconfirm test_dir_*.DIR;* +.IFDEF BUILD_BZIP2 # BUILD_BZIP2 + @ write sys$output "" + @ write sys$output "Cleaning bzip2..." + def_dev_dir_orig = f$environment( "default") + set default $(IZ_BZIP2) + $(MMS) $(MMSQUALIFIERS) /DESCR=[.vms]descrip.mms - + $(IZ_BZIP2_MACROS) - + $(MMSTARGETS) + set default 'def_dev_dir_orig' +.ENDIF # BUILD_BZIP2 # DASHV target. Generate an "unzip -v" report. @@ -371,7 +423,7 @@ SLASHV : TEST : @[.vms]test_unzip.com testmake.zip [.$(DEST)] -# TEST_PPMD target. Runs a PPMdtest procedure. +# TEST_PPMD target. Runs a PPMd test procedure. TEST_PPMD : @[.vms]test_unzip.com testmake_ppmd.zip [.$(DEST)] NOSFX @@ -422,7 +474,7 @@ OPT_ID_SFX = SYS$DISK:[.$(DEST)]UNZIPSFX.OPT [.$(DEST)]UNZ_CLI.CLD : [.VMS]UNZ_CLI.CLD @[.vms]cppcld.com "$(CC) $(CFLAGS_ARCH)" - - $(MMS$SOURCE) $(MMS$TARGET) "$(CDEFS)" + $(MMS$SOURCE) $(MMS$TARGET) "$(CDEFS)" [.$(DEST)]ZIPINFO_C.OBJ : ZIPINFO.C $(CC) $(CFLAGS) $(CDEFS_CLI) $(MMS$SOURCE) @@ -551,17 +603,21 @@ $(OPT_ID_SFX) : # Local BZIP2 object library. $(LIB_BZ2_LOCAL) : + @ write sys$output "" + @ write sys$output "Building bzip2..." def_dev_dir_orig = f$environment( "default") set default $(IZ_BZIP2) $(MMS) $(MMSQUALIFIERS) /DESCR=[.vms]descrip.mms - $(IZ_BZIP2_MACROS) - $(MMSTARGETS) set default 'def_dev_dir_orig' + @ write sys$output "" # Normal UnZip executable. $(UNZIP) : [.$(DEST)]UNZIP.OBJ \ - $(LIB_UNZIP) $(LIB_BZ2_DEP) $(OPT_FILE) $(OPT_ID) + $(LIB_UNZIP) $(LIB_BZ2_DEP) \ + $(OPT_FILE) $(OPT_ID) $(LINK) $(LINKFLAGS) $(MMS$SOURCE), - $(LIB_UNZIP) /library, - $(LIB_BZIP2_OPTS) - @@ -569,12 +625,13 @@ $(UNZIP) : [.$(DEST)]UNZIP.OBJ \ $(LIB_ZLIB_OPTS) - $(LFLAGS_ARCH) - $(OPT_ID) /options - - $(NOSHARE_OPTS) + $(NOSYSSHR_OPTS) # CLI UnZip executable. $(UNZIP_CLI) : [.$(DEST)]UNZIPCLI.OBJ \ - $(LIB_UNZIP_CLI) $(LIB_BZ2_DEP) $(OPT_FILE) $(OPT_ID) + $(LIB_UNZIP_CLI) $(LIB_BZ2_DEP) \ + $(OPT_FILE) $(OPT_ID) $(LINK) $(LINKFLAGS) $(MMS$SOURCE), - $(LIB_UNZIP_CLI) /library, - $(LIB_UNZIP) /library, - @@ -583,12 +640,13 @@ $(UNZIP_CLI) : [.$(DEST)]UNZIPCLI.OBJ \ $(LIB_ZLIB_OPTS) - $(LFLAGS_ARCH) - $(OPT_ID) /options - - $(NOSHARE_OPTS) + $(NOSYSSHR_OPTS) # SFX UnZip executable. $(UNZIPSFX) : [.$(DEST)]UNZIPSFX.OBJ \ - $(LIB_UNZIPSFX) $(LIB_BZ2_DEP) $(OPT_FILE) $(OPT_ID_SFX) + $(LIB_UNZIPSFX) $(LIB_BZ2_DEP) \ + $(OPT_FILE) $(OPT_ID_SFX) $(LINK) $(LINKFLAGS) $(MMS$SOURCE), - $(LIB_UNZIPSFX) /library, - $(LIB_BZIP2_OPTS) - @@ -596,13 +654,13 @@ $(UNZIPSFX) : [.$(DEST)]UNZIPSFX.OBJ \ $(LIB_ZLIB_OPTS) - $(LFLAGS_ARCH) - $(OPT_ID_SFX) /options - - $(NOSHARE_OPTS) + $(NOSYSSHR_OPTS) # SFX CLI UnZip executable. $(UNZIPSFX_CLI) : [.$(DEST)]UNZSFXCLI.OBJ \ - $(LIB_UNZIPSFX_CLI) $(LIB_UNZIPSFX) $(LIB_BZ2_DEP) \ - $(OPT_FILE) $(OPT_ID_SFX) + $(LIB_UNZIPSFX_CLI) $(LIB_UNZIPSFX) $(LIB_BZ2_DEP) \ + $(OPT_FILE) $(OPT_ID_SFX) $(LINK) $(LINKFLAGS) $(MMS$SOURCE), - $(LIB_UNZIPSFX_CLI) /library, - $(LIB_UNZIPSFX) /library, - @@ -611,7 +669,7 @@ $(UNZIPSFX_CLI) : [.$(DEST)]UNZSFXCLI.OBJ \ $(LIB_ZLIB_OPTS) - $(LFLAGS_ARCH) - $(OPT_ID_SFX) /options - - $(NOSHARE_OPTS) + $(NOSYSSHR_OPTS) # Help library source files. @@ -631,16 +689,16 @@ UNZIP_CLI.HLP : [.VMS]UNZIP_CLI.HELP [.VMS]CVTHELP.TPU .HLP.HTX : help_temp_name = "help_temp_"+ f$getjpi( 0, "PID") if (f$search( help_temp_name+ ".HLB") .nes. "") then - - delete 'help_temp_name'.HLB;* + delete /noconfirm 'help_temp_name'.HLB;* library /create /help 'help_temp_name'.HLB $(MMS$SOURCE) help /library = sys$disk:[]'help_temp_name'.HLB - /output = 'help_temp_name'.OUT unzip... - delete 'help_temp_name'.HLB;* + delete /noconfirm 'help_temp_name'.HLB;* create /fdl = [.VMS]STREAM_LF.FDL $(MMS$TARGET) open /append help_temp $(MMS$TARGET) copy 'help_temp_name'.OUT help_temp close help_temp - delete 'help_temp_name'.OUT;* + delete /noconfirm 'help_temp_name'.OUT;* UNZIP.HTX : UNZIP.HLP [.VMS]STREAM_LF.FDL diff --git a/vms/descrip_mkdeps.mms b/vms/descrip_mkdeps.mms index 89135f3..2940574 100644 --- a/vms/descrip_mkdeps.mms +++ b/vms/descrip_mkdeps.mms @@ -2,7 +2,7 @@ # # UnZip 6.10 for VMS -- MMS Dependency Description File. # -# Last revised: 2014-10-09 +# Last revised: 2014-10-19 # #---------------------------------------------------------------------- # Copyright (c) 2004-2014 Info-ZIP. All rights reserved. @@ -101,7 +101,7 @@ UNK_MMSD = 1 " To retain the .MMSD files, specify ""/MACRO = NOSKIP=1""." @ exit %x00000004 .ENDIF - $(CC) $(CFLAGS_INCL) $(CDEFS_UNX) $(MMS$SOURCE) /NOLIST /NOOBJECT - + $(CC) $(CFLAGS_DEP) $(CDEFS_UNX) $(MMS$SOURCE) /NOLIST /NOOBJECT - /MMS_DEPENDENCIES = (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) # List of MMS dependency files. @@ -254,92 +254,92 @@ CLEAN_ALL : # the /SKIP warning code in each rule here. CRC32_.MMSD : CRC32.C CRC32.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) CRYPT_.MMSD : CRYPT.C CRYPT.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) EXTRACT_.MMSD : EXTRACT.C EXTRACT.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) FILEIO_.MMSD : FILEIO.C FILEIO.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) GLOBALS_.MMSD : GLOBALS.C GLOBALS.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) INFLATE_.MMSD : INFLATE.C INFLATE.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) MATCH_.MMSD : MATCH.C MATCH.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) PROCESS_.MMSD : PROCESS.C PROCESS.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) TTYIO_.MMSD : TTYIO.C TTYIO.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) UBZ2ERR_.MMSD : UBZ2ERR.C UBZ2ERR.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) [.VMS]VMS_.MMSD : [.VMS]VMS.C [.VMS]VMS.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) UNZIP_CLI.MMSD : UNZIP.C UNZIP.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) UNZIPSFX.MMSD : UNZIP.C UNZIP.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_SFX) $(CDEFS_SFX) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_SFX) $(CDEFS_SFX) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) UNZIPSFX_CLI.MMSD : UNZIP.C UNZIP.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CFLAGS_SFX) $(CDEFS_SFX_CLI) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CFLAGS_SFX) $(CDEFS_SFX_CLI) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) ZIPINFO_C.MMSD : ZIPINFO.C ZIPINFO.MMSD - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) @@ -356,7 +356,7 @@ ZIPINFO_C.MMSD : ZIPINFO.C ZIPINFO.MMSD " To retain the .MMSD files, specify ""/MACRO = NOSKIP=1""." @ exit %x00000004 .ENDIF - $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - + $(CC) $(CFLAGS_DEP) $(CFLAGS_CLI) $(CDEFS_CLI) $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) @@ -364,112 +364,112 @@ ZIPINFO_C.MMSD : ZIPINFO.C ZIPINFO.MMSD # UnZip library modules. APIHELP_L.MMSD : APIHELP.C - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) API_L.MMSD : API.C API.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) CRYPT_L.MMSD : CRYPT.C CRYPT.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) EXPLODE_L.MMSD : EXPLODE.C EXPLODE.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) EXTRACT_L.MMSD : EXTRACT.C EXTRACT.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) FILEIO_L.MMSD : FILEIO.C FILEIO.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) GLOBALS_L.MMSD : GLOBALS.C GLOBALS.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) INFLATE_L.MMSD : INFLATE.C INFLATE.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) LIST_L.MMSD : LIST.C LIST.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) PROCESS_L.MMSD : PROCESS.C PROCESS.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) TTYIO_L.MMSD : TTYIO.C TTYIO.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) UBZ2ERR_L.MMSD : UBZ2ERR.C UBZ2ERR.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) UNSHRINK_L.MMSD : UNSHRINK.C UNSHRINK.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) UNZIP_L.MMSD : UNZIP.C UNZIP.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) [.VMS]VMS_L.MMSD : [.VMS]VMS.C [.VMS]VMS.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) @$(MOD_DEP) $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET) ZIPINFO_L.MMSD : ZIPINFO.C ZIPINFO.MMSD - $(CC) $(CFLAGS_INCL) $(CDEFS_LIBUNZIP) - + $(CC) $(CFLAGS_DEP) $(CDEFS_LIBUNZIP) - $(MMS$SOURCE) - /NOLIST /NOOBJECT /MMS_DEPENDENCIES = - (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES) diff --git a/vms/descrip_src.mms b/vms/descrip_src.mms index 02af7b3..80432f6 100644 --- a/vms/descrip_src.mms +++ b/vms/descrip_src.mms @@ -2,7 +2,7 @@ # # UnZip 6.10 for VMS -- MMS (or MMK) Source Description File. # -# Last revised: 2014-10-10 +# Last revised: 2014-10-20 # #---------------------------------------------------------------------- # Copyright (c) 2004-2014 Info-ZIP. All rights reserved. @@ -52,8 +52,6 @@ VAXC_OR_FORCE_VAXC = 1 # Analyze architecture-related and option macros. -# Compiler options on VAX. - .IFDEF __ALPHA__ # __ALPHA__ DECC = 1 DESTM = ALPHA @@ -192,27 +190,6 @@ GCC_C = GCC_L = .ENDIF # GNUC -# Check for option problems. - -.IFDEF __VAX__ # __VAX__ -.IFDEF LARGE # LARGE -LARGE_VAX = 1 -.ENDIF # LARGE -.IFDEF VAXC_OR_FORCE_VAXC # VAXC_OR_FORCE_VAXC -.IFDEF GNUC # GNUC -VAX_MULTI_CMPL = 1 -.ENDIF # GNUC -.ENDIF # VAXC_OR_FORCE_VAXC -.ELSE # __VAX__ -.IFDEF VAXC_OR_FORCE_VAXC # VAXC_OR_FORCE_VAXC -NON_VAX_CMPL = 1 -.ELSE # VAXC_OR_FORCE_VAXC -.IFDEF GNUC # GNUC -NON_VAX_CMPL = 1 -.ENDIF # GNUC -.ENDIF # VAXC_OR_FORCE_VAXC -.ENDIF # __VAX__ - # BZIP2 options. (Default: IZ_BZIP2=[.bzip2]. To disable, define # NO_IZ_BZIP2 or NOIZ_BZIP2.) @@ -309,6 +286,27 @@ PPMD = 1 .ENDIF # PPMD .ENDIF # NOPPMD +# Check for option problems. + +.IFDEF __VAX__ # __VAX__ +.IFDEF LARGE # LARGE +LARGE_VAX = 1 +.ENDIF # LARGE +.IFDEF VAXC_OR_FORCE_VAXC # VAXC_OR_FORCE_VAXC +.IFDEF GNUC # GNUC +VAX_MULTI_CMPL = 1 +.ENDIF # GNUC +.ENDIF # VAXC_OR_FORCE_VAXC +.ELSE # __VAX__ +.IFDEF VAXC_OR_FORCE_VAXC # VAXC_OR_FORCE_VAXC +NON_VAX_CMPL = 1 +.ELSE # VAXC_OR_FORCE_VAXC +.IFDEF GNUC # GNUC +NON_VAX_CMPL = 1 +.ENDIF # GNUC +.ENDIF # VAXC_OR_FORCE_VAXC +.ENDIF # __VAX__ + # Complain about any problems (and die) if warranted. Otherwise, show # optional package directories being used, and the destination # directory. Make the destination directory, if necessary. @@ -472,6 +470,8 @@ PPMD = 1 CDEFS_AES = , CRYPT_AES_WG .ENDIF # AES_WG +# PPMd options. + .IFDEF PPMD # PPMD .IFDEF LZMA # LZMA .IFDEF __VAX__ # __VAX__ @@ -544,8 +544,8 @@ CDEFS_LARGE = , LARGE_FILE_SUPPORT C_LOCAL_UNZIP = , $(LOCAL_UNZIP) .ENDIF -CDEFS = VMS $(CDEFS_AES) $(CDEFS_BZ) $(CDEFS_LARGE) $(CDEFS_LZMA) \ - $(CDEFS_PPMD) $(CDEFS_ZL) $(C_LOCAL_UNZIP) +CDEFS = VMS $(CDEFS_AES) $(CDEFS_BZ) $(CDEFS_LARGE) \ + $(CDEFS_LZMA) $(CDEFS_PPMD) $(CDEFS_ZL) $(C_LOCAL_UNZIP) CDEFS_UNX = /define = ($(CDEFS)) @@ -573,68 +573,68 @@ CFLAGS_ARCH = .ENDIF # FORCE_VAXC .ENDIF # DECC -# LINK (share) library options. -# Omit shareable image options file for NOSHARE. +# LINK (sysshr) library options. +# Omit shareable image options file for NOSYSSHR. .IFDEF VAXC_OR_FORCE_VAXC # VAXC_OR_FORCE_VAXC -.IFDEF NOSHARE # NOSHARE +.IFDEF NOSYSSHR # NOSYSSHR OPT_FILE = LFLAGS_ARCH = -.ELSE # NOSHARE +.ELSE # NOSYSSHR OPT_FILE = [.$(DEST)]VAXCSHR.OPT LFLAGS_ARCH = $(OPT_FILE) /options, -.ENDIF # NOSHARE +.ENDIF # NOSYSSHR .ELSE # VAXC_OR_FORCE_VAXC .IFDEF GNUC # GNUC LFLAGS_GNU = GNU_CC:[000000]GCCLIB.OLB /LIBRARY -.IFDEF NOSHARE # NOSHARE +.IFDEF NOSYSSHR # NOSYSSHR OPT_FILE = LFLAGS_ARCH = $(LFLAGS_GNU), -.ELSE # NOSHARE +.ELSE # NOSYSSHR OPT_FILE = [.$(DEST)]VAXCSHR.OPT LFLAGS_ARCH = $(LFLAGS_GNU), SYS$DISK:$(OPT_FILE) /options, -.ENDIF # NOSHARE +.ENDIF # NOSYSSHR .ELSE # GNUC OPT_FILE = LFLAGS_ARCH = .ENDIF # GNUC .ENDIF # VAXC_OR_FORCE_VAXC -# LINK NOSHARE options. +# LINK NOSYSSHR options. -.IFDEF NOSHARE # NOSHARE +.IFDEF NOSYSSHR # NOSYSSHR .IFDEF __ALPHA__ # __ALPHA__ -NOSHARE_OPTS = , SYS$LIBRARY:STARLET.OLB /LIBRARY\ +NOSYSSHR_OPTS = , SYS$LIBRARY:STARLET.OLB /LIBRARY\ /INCLUDE = CMA$TIS /NOSYSSHR .ELSE # __ALPHA__ .IFDEF __IA64__ # __IA64__ -NOSHARE_OPTS = , SYS$LIBRARY:STARLET.OLB /LIBRARY\ +NOSYSSHR_OPTS = , SYS$LIBRARY:STARLET.OLB /LIBRARY\ /INCLUDE = CMA$TIS /NOSYSSHR .ELSE # __IA64__ OLDVAX_OLDVAX = 1 .IFDEF DECC # DECC -.IFDEF OLDVAX_$(NOSHARE) # OLDVAX_$(NOSHARE) -NOSHARE_OPTS = , SYS$LIBRARY:DECCRTL.OLB /LIBRARY\ +.IFDEF OLDVAX_$(NOSYSSHR) # OLDVAX_$(NOSYSSHR) +NOSYSSHR_OPTS = , SYS$LIBRARY:DECCRTL.OLB /LIBRARY\ /INCLUDE = CMA$TIS /NOSYSSHR -.ELSE # OLDVAX_$(NOSHARE) -NOSHARE_OPTS = , SYS$LIBRARY:DECCRTL.OLB /LIBRARY\ +.ELSE # OLDVAX_$(NOSYSSHR) +NOSYSSHR_OPTS = , SYS$LIBRARY:DECCRTL.OLB /LIBRARY\ /INCLUDE = (CMA$TIS, CMA$TIS_VEC) /NOSYSSHR -.ENDIF # OLDVAX_$(NOSHARE) +.ENDIF # OLDVAX_$(NOSYSSHR) .ELSE # DECC -.IFDEF OLDVAX_$(NOSHARE) # OLDVAX_$(NOSHARE) -NOSHARE_OPTS = , SYS$LIBRARY:VAXCRTL.OLB /LIBRARY,\ +.IFDEF OLDVAX_$(NOSYSSHR) # OLDVAX_$(NOSYSSHR) +NOSYSSHR_OPTS = , SYS$LIBRARY:VAXCRTL.OLB /LIBRARY,\ SYS$LIBRARY:IMAGELIB.OLB /LIBRARY /NOSYSSHR -.ELSE # OLDVAX_$(NOSHARE) -NOSHARE_OPTS = , SYS$LIBRARY:VAXCRTL.OLB /LIBRARY,\ +.ELSE # OLDVAX_$(NOSYSSHR) +NOSYSSHR_OPTS = , SYS$LIBRARY:VAXCRTL.OLB /LIBRARY,\ SYS$LIBRARY:DECCRTL.OLB /LIBRARY /INCLUDE = CMA$TIS,\ SYS$LIBRARY:IMAGELIB.OLB /LIBRARY /NOSYSSHR -.ENDIF # OLDVAX_$(NOSHARE) +.ENDIF # OLDVAX_$(NOSYSSHR) .ENDIF # DECC .ENDIF # __IA64__ .ENDIF # __ALPHA__ -.ELSE # NOSHARE -NOSHARE_OPTS = -.ENDIF # NOSHARE +.ELSE # NOSYSSHR +NOSYSSHR_OPTS = +.ENDIF # NOSYSSHR # LIST options. @@ -656,6 +656,8 @@ CFLAGS = \ $(CFLAGS_ARCH) $(CFLAGS_DBG) $(CFLAGS_INCL) $(CFLAGS_LIST) $(CCOPTS) \ /object = $(MMS$TARGET) +CFLAGS_DEP = $(CFLAGS_ARCH) $(CFLAGS_INCL) $(CCOPTS) + LINKFLAGS = \ $(LINKFLAGS_DBG) $(LINKFLAGS_LIST) $(LINKOPTS) \ /executable = $(MMS$TARGET) diff --git a/win32/vc10/funzip/funzip.vcxproj b/win32/vc10/funzip/funzip.vcxproj index 5be9c19..d1c59e1 100644 --- a/win32/vc10/funzip/funzip.vcxproj +++ b/win32/vc10/funzip/funzip.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {EDCE1136-BD07-469D-B8E6-57A161C577D0} @@ -21,30 +29,55 @@ true Unicode + + Application + true + Unicode + Application false true Unicode + + Application + false + true + Unicode + + + + + + + true + + true + false ..\..\..\bzip2;$(IncludePath) $(SolutionDir)\$(Configuration);$(LibraryPath) + + false + ..\..\..\bzip2;$(IncludePath) + $(SolutionDir)\$(Configuration);$(LibraryPath) + @@ -58,6 +91,19 @@ true + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;FUNZIP;x_ASM_CRC;%(PreprocessorDefinitions) + + + Console + true + + Level3 @@ -75,6 +121,23 @@ true + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;FUNZIP;x_ASM_CRC;%(PreprocessorDefinitions) + + + Console + true + true + true + + diff --git a/win32/vc10/libbz2/libbz2.vcxproj b/win32/vc10/libbz2/libbz2.vcxproj index 4c58232..f7daea1 100644 --- a/win32/vc10/libbz2/libbz2.vcxproj +++ b/win32/vc10/libbz2/libbz2.vcxproj @@ -1,14 +1,22 @@ - + Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {645768EE-A938-492D-A6F5-F97964E2FAAD} @@ -21,21 +29,38 @@ true Unicode + + StaticLibrary + true + Unicode + StaticLibrary false true Unicode + + StaticLibrary + false + true + Unicode + + + + + + + @@ -51,6 +76,19 @@ true + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;BZ_NO_STDIO;%(PreprocessorDefinitions) + + + Windows + true + + Level3 @@ -68,6 +106,23 @@ true + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;BZ_NO_STDIO;%(PreprocessorDefinitions) + + + Windows + true + true + true + + diff --git a/win32/vc10/unzip.sln b/win32/vc10/unzip.sln index 87b24e3..ce1adfa 100644 --- a/win32/vc10/unzip.sln +++ b/win32/vc10/unzip.sln @@ -17,25 +17,43 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {B55AC1E0-01E0-4BDC-9E68-BB8C450A79D7}.Debug|Win32.ActiveCfg = Debug|Win32 {B55AC1E0-01E0-4BDC-9E68-BB8C450A79D7}.Debug|Win32.Build.0 = Debug|Win32 + {B55AC1E0-01E0-4BDC-9E68-BB8C450A79D7}.Debug|x64.ActiveCfg = Debug|x64 + {B55AC1E0-01E0-4BDC-9E68-BB8C450A79D7}.Debug|x64.Build.0 = Debug|x64 {B55AC1E0-01E0-4BDC-9E68-BB8C450A79D7}.Release|Win32.ActiveCfg = Release|Win32 {B55AC1E0-01E0-4BDC-9E68-BB8C450A79D7}.Release|Win32.Build.0 = Release|Win32 + {B55AC1E0-01E0-4BDC-9E68-BB8C450A79D7}.Release|x64.ActiveCfg = Release|x64 + {B55AC1E0-01E0-4BDC-9E68-BB8C450A79D7}.Release|x64.Build.0 = Release|x64 {645768EE-A938-492D-A6F5-F97964E2FAAD}.Debug|Win32.ActiveCfg = Debug|Win32 {645768EE-A938-492D-A6F5-F97964E2FAAD}.Debug|Win32.Build.0 = Debug|Win32 + {645768EE-A938-492D-A6F5-F97964E2FAAD}.Debug|x64.ActiveCfg = Debug|x64 + {645768EE-A938-492D-A6F5-F97964E2FAAD}.Debug|x64.Build.0 = Debug|x64 {645768EE-A938-492D-A6F5-F97964E2FAAD}.Release|Win32.ActiveCfg = Release|Win32 {645768EE-A938-492D-A6F5-F97964E2FAAD}.Release|Win32.Build.0 = Release|Win32 + {645768EE-A938-492D-A6F5-F97964E2FAAD}.Release|x64.ActiveCfg = Release|x64 + {645768EE-A938-492D-A6F5-F97964E2FAAD}.Release|x64.Build.0 = Release|x64 {D0C91394-54C1-41A2-A9EC-0810FE2ACFAC}.Debug|Win32.ActiveCfg = Debug|Win32 {D0C91394-54C1-41A2-A9EC-0810FE2ACFAC}.Debug|Win32.Build.0 = Debug|Win32 + {D0C91394-54C1-41A2-A9EC-0810FE2ACFAC}.Debug|x64.ActiveCfg = Debug|x64 + {D0C91394-54C1-41A2-A9EC-0810FE2ACFAC}.Debug|x64.Build.0 = Debug|x64 {D0C91394-54C1-41A2-A9EC-0810FE2ACFAC}.Release|Win32.ActiveCfg = Release|Win32 {D0C91394-54C1-41A2-A9EC-0810FE2ACFAC}.Release|Win32.Build.0 = Release|Win32 + {D0C91394-54C1-41A2-A9EC-0810FE2ACFAC}.Release|x64.ActiveCfg = Release|x64 + {D0C91394-54C1-41A2-A9EC-0810FE2ACFAC}.Release|x64.Build.0 = Release|x64 {EDCE1136-BD07-469D-B8E6-57A161C577D0}.Debug|Win32.ActiveCfg = Debug|Win32 {EDCE1136-BD07-469D-B8E6-57A161C577D0}.Debug|Win32.Build.0 = Debug|Win32 + {EDCE1136-BD07-469D-B8E6-57A161C577D0}.Debug|x64.ActiveCfg = Debug|x64 + {EDCE1136-BD07-469D-B8E6-57A161C577D0}.Debug|x64.Build.0 = Debug|x64 {EDCE1136-BD07-469D-B8E6-57A161C577D0}.Release|Win32.ActiveCfg = Release|Win32 {EDCE1136-BD07-469D-B8E6-57A161C577D0}.Release|Win32.Build.0 = Release|Win32 + {EDCE1136-BD07-469D-B8E6-57A161C577D0}.Release|x64.ActiveCfg = Release|x64 + {EDCE1136-BD07-469D-B8E6-57A161C577D0}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/win32/vc10/unzip/unzip.vcxproj b/win32/vc10/unzip/unzip.vcxproj index 425dbec..a372e45 100644 --- a/win32/vc10/unzip/unzip.vcxproj +++ b/win32/vc10/unzip/unzip.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {B55AC1E0-01E0-4BDC-9E68-BB8C450A79D7} @@ -21,45 +29,86 @@ true Unicode + + Application + true + Unicode + Application false true Unicode + + Application + false + true + Unicode + + + + + + + true ..\..\..\bzip2;$(IncludePath) $(SolutionDir)\$(Configuration);$(LibraryPath) + + true + ..\..\..\bzip2;$(IncludePath) + $(SolutionDir)\$(Configuration);$(LibraryPath) + false ..\..\..\bzip2;$(IncludePath) $(SolutionDir)\$(Configuration);$(LibraryPath) + + false + ..\..\..\bzip2;$(IncludePath) + $(SolutionDir)\$(Configuration);$(LibraryPath) + Level3 Disabled - WIN32;_DEBUG;_CONSOLE;ASM_CRC;x_BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions) Console true + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;x_ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions) + + + Console + true + $(OutDir);%(AdditionalLibraryDirectories) + + Level3 @@ -68,13 +117,31 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;ASM_CRC;x_BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;x_ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS;%(PreprocessorDefinitions) Console true true true + $(OutDir);%(AdditionalLibraryDirectories) diff --git a/win32/vc10/unzipsfx/unzipsfx.vcxproj b/win32/vc10/unzipsfx/unzipsfx.vcxproj index d887284..5866a40 100644 --- a/win32/vc10/unzipsfx/unzipsfx.vcxproj +++ b/win32/vc10/unzipsfx/unzipsfx.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {D0C91394-54C1-41A2-A9EC-0810FE2ACFAC} @@ -21,30 +29,57 @@ true Unicode + + Application + true + Unicode + Windows7.1SDK + Application false true Unicode + + Application + false + true + Unicode + Windows7.1SDK + + + + + + + true ..\..\..\bzip2;$(IncludePath) $(SolutionDir)$(Configuration);$(LibraryPath) + + true + ..\..\..\bzip2;$(IncludePath) + $(SolutionDir)$(Configuration);$(LibraryPath) + false + + false + @@ -58,6 +93,20 @@ true + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;SFX;DIAG_SFX;x_ASM_CRC;x_BZIP2_SUPPORT;x_BZIP2_SFX;x_CHEAP_SFX_AUTORUN;x_CRYPT_AES_WG;x_CRYPT_AES_WG_SFX;x_CRYPT_TRAD_SFX;x_LZMA_SUPPORT;x_LZMA_SFX;x_PPMD_SUPPORT;x_PPMD_SFX;x_SYMLINKS;%(PreprocessorDefinitions) + + + Console + true + $(OutDir);%(AdditionalLibraryDirectories) + + Level3 @@ -75,6 +124,24 @@ true + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;SFX;x_ASM_CRC;x_BZIP2_SUPPORT;x_BZIP2_SFX;x_CHEAP_SFX_AUTORUN;x_CRYPT_AES_WG;x_CRYPT_AES_WG_SFX;x_CRYPT_TRAD_SFX;x_LZMA_SUPPORT;x_LZMA_SFX;x_PPMD_SUPPORT;x_PPMD_SFX;x_SYMLINKS;%(PreprocessorDefinitions) + + + Console + true + true + true + $(OutDir);%(AdditionalLibraryDirectories) + + diff --git a/win32/w32cfg.h b/win32/w32cfg.h index ee14ab6..4e85e16 100644 --- a/win32/w32cfg.h +++ b/win32/w32cfg.h @@ -352,7 +352,9 @@ /* Static variables that we have to add to Uz_Globs: */ #if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) #define SYSTEM_SPECIFIC_GLOBALS \ - int created_dir, renamed_fullpath, fnlen;\ + int created_dir;\ + int renamed_fullpath;\ + size_t fnlen;\ unsigned nLabelDrive;\ char lastRootPath[4];\ wchar_t lastRootPathw[4];\ @@ -363,18 +365,24 @@ ZCONST wchar_t *wildnamew;\ char *dirname, matchname[FILNAMSIZ];\ wchar_t *dirnamew, matchnamew[FILNAMSIZ];\ - int rootlen, have_dirname, dirnamelen, notfirstcall;\ + size_t dirnamelen;\ + size_t rootlen;\ + int have_dirname, notfirstcall;\ zvoid *wild_dir; #else /* (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ #define SYSTEM_SPECIFIC_GLOBALS \ - int created_dir, renamed_fullpath, fnlen;\ + int created_dir;\ + int renamed_fullpath;\ + size_t fnlen;\ unsigned nLabelDrive;\ char lastRootPath[4];\ int lastVolOldFAT, lastVolLocTim;\ char *rootpath, *buildpathHPFS, *buildpathFAT, *endHPFS, *endFAT;\ ZCONST char *wildname;\ char *dirname, matchname[FILNAMSIZ];\ - int rootlen, have_dirname, dirnamelen, notfirstcall;\ + size_t dirnamelen;\ + size_t rootlen;\ + int have_dirname, notfirstcall;\ zvoid *wild_dir; #endif /* ?(defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ diff --git a/win32/win32.c b/win32/win32.c index 4a7d1bc..82d504b 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -58,7 +58,7 @@ #include "../unzip.h" #include /* must be AFTER unzip.h to avoid struct G problems */ #ifdef __RSXNT__ -# include "../win32/rsxntwin.h" +# include "../win32/rsxntwin.h" #endif #include "../win32/nt.h" @@ -77,9 +77,9 @@ # if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) # if (defined(__EMX__) || defined(__CYGWIN__)) -# define MKDIRW(pathw,mode) _wmkdir(pathw,mode) +# define MKDIRW(pathw,mode) _wmkdir(pathw,mode) # else -# define MKDIRW(pathw,mode) _wmkdir(pathw) +# define MKDIRW(pathw,mode) _wmkdir(pathw) # endif # endif @@ -93,29 +93,29 @@ # ifndef SFX # ifdef HAVE_WORKING_DIRENT_H -# include /* use readdir() */ -# define zdirent dirent -# define zDIR DIR -# define Opendir opendir -# define Readdir readdir -# define Closedir closedir -# else /* !HAVE_WORKING_DIRENT_H */ - typedef struct zdirent { - char reserved [21]; - char ff_attrib; - short ff_ftime; - short ff_fdate; - long size; - char d_name[MAX_PATH]; - int d_first; - HANDLE d_hFindFile; - } zDIR; - - static zDIR *Opendir (const char *n); - static struct zdirent *Readdir (zDIR *d); - static void Closedir (zDIR *d); -# endif /* ?HAVE_WORKING_DIRENT_H */ -# endif /* !SFX */ +# include /* use readdir() */ +# define zdirent dirent +# define zDIR DIR +# define Opendir opendir +# define Readdir readdir +# define Closedir closedir +# else /* def HAVE_WORKING_DIRENT_H */ +typedef struct zdirent { + char reserved [21]; + char ff_attrib; + short ff_ftime; + short ff_fdate; + long size; + char d_name[MAX_PATH]; + int d_first; + HANDLE d_hFindFile; +} zDIR; + + static zDIR *Opendir (const char *n); + static struct zdirent *Readdir (zDIR *d); + static void Closedir (zDIR *d); +# endif /* def HAVE_WORKING_DIRENT_H [else] */ +# endif /* ndef SFX */ # ifdef SET_DIR_ATTRIB typedef struct NTdirattr { /* struct for holding unix style directory */ @@ -131,55 +131,54 @@ typedef struct NTdirattr { /* struct for holding unix style directory */ # endif char buf[1]; /* buffer stub for directory SD and name */ } NTdirattr; -#define NtAtt(d) ((NTdirattr *)d) /* typecast shortcut */ +# define NtAtt(d) ((NTdirattr *)d) /* typecast shortcut */ # if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) - typedef struct NTdirattrw { /* struct for holding unix style directory */ - struct NTdirattrw *next; /* info until can be sorted and set at end */ - wchar_t *fnw; /* filename of directory */ - FILETIME Modft; /* File time type defined in NT, `last modified' time */ - FILETIME Accft; /* NT file time type, `last access' time */ - FILETIME Creft; /* NT file time type, `file creation' time */ +typedef struct NTdirattrw { /* struct for holding unix style directory */ + struct NTdirattrw *next; /* info until can be sorted and set at end */ + wchar_t *fnw; /* filename of directory */ + FILETIME Modft; /* File time type defined in NT, `last modified' time */ + FILETIME Accft; /* NT file time type, `last access' time */ + FILETIME Creft; /* NT file time type, `file creation' time */ int gotTime; unsigned perms; /* same as min_info.file_attr */ # ifdef NTSD_EAS unsigned SDlen; /* length of SD data in buf */ # endif - wchar_t buf[1]; /* buffer stub for directory SD and name */ - } NTdirattrw; -# define NtAttw(dw) ((NTdirattrw *)dw) /* typecast shortcut */ + wchar_t buf[1]; /* buffer stub for directory SD and name */ +} NTdirattrw; +# define NtAttw(dw) ((NTdirattrw *)dw) /* typecast shortcut */ # endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ - -# endif /* SET_DIR_ATTRIB */ +# endif /* def SET_DIR_ATTRIB */ /* Function prototypes */ # ifdef NTSD_EAS # if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) - static int SetSD(__GPRO__ wchar_t *path, unsigned fperms, - uch *eb_ptr, unsigned eb_len); +static int SetSD(__GPRO__ wchar_t *path, unsigned fperms, + uch *eb_ptr, unsigned eb_len); # else - static int SetSD(__GPRO__ char *path, unsigned fperms, - uch *eb_ptr, unsigned eb_len); +static int SetSD(__GPRO__ char *path, unsigned fperms, + uch *eb_ptr, unsigned eb_len); # endif - static int FindSDExtraField(__GPRO__ - uch *ef_ptr, unsigned ef_len, - uch **p_ebSD_ptr, unsigned *p_ebSD_len); -# endif /* NTSD_EAS */ +static int FindSDExtraField(__GPRO__ + uch *ef_ptr, unsigned ef_len, + uch **p_ebSD_ptr, unsigned *p_ebSD_len); +# endif /* def NTSD_EAS */ # ifndef NO_W32TIMES_IZFIX - static void utime2NtfsFileTime(time_t ut, FILETIME *pft); +static void utime2NtfsFileTime(time_t ut, FILETIME *pft); # endif static void utime2VFatFileTime(time_t ut, FILETIME *pft, int clipDosMin); # if (defined(W32_STAT_BANDAID) && !defined(NO_W32TIMES_IZFIX)) - static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut); +static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut); # endif # ifdef W32_STAT_BANDAID - static int VFatFileTime2utime(const FILETIME *pft, time_t *ut); +static int VFatFileTime2utime(const FILETIME *pft, time_t *ut); # endif static int FStampIsLocTime(__GPRO__ const char *path); # if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) - static int FStampIsLocTimeW(__GPRO__ const wchar_t *pathw); +static int FStampIsLocTimeW(__GPRO__ const wchar_t *pathw); # endif @@ -192,30 +191,30 @@ static int getNTfiletimeW (__GPRO__ FILETIME *pModFT, FILETIME *pAccFT, static int isfloppy (int nDrive); static int NTQueryVolInfo (__GPRO__ const char *name); # if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) - static int NTQueryVolInfoW (__GPRO__ const wchar_t *namew); +static int NTQueryVolInfoW (__GPRO__ const wchar_t *namew); # endif static int IsVolumeOldFAT (__GPRO__ const char *name); static void maskDOSdevice (__GPRO__ char *pathcomp); static void map2fat (char *pathcomp, char **pEndFAT); # if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) - static void maskDOSdevicew (__GPRO__ wchar_t *pathcompw); - static void map2fatw (wchar_t *pathcompw, wchar_t **pEndFATw); +static void maskDOSdevicew (__GPRO__ wchar_t *pathcompw); +static void map2fatw (wchar_t *pathcompw, wchar_t **pEndFATw); # endif # if (defined(__MINGW32__) && !defined(USE_MINGW_GLOBBING)) - int _CRT_glob = 0; /* suppress command line globbing by C RTL */ +int _CRT_glob = 0; /* suppress command line globbing by C RTL */ # endif # ifdef ACORN_FTYPE_NFS /* Acorn bits for NFS filetyping */ typedef struct { - uch ID[2]; - uch size[2]; - uch ID_2[4]; - uch loadaddr[4]; - uch execaddr[4]; - uch attr[4]; + uch ID[2]; + uch size[2]; + uch ID_2[4]; + uch loadaddr[4]; + uch execaddr[4]; + uch attr[4]; } RO_extra_block; # endif /* ACORN_FTYPE_NFS */ @@ -226,7 +225,6 @@ typedef struct { /* static unsigned nLabelDrive; */ /* ditto */ - # ifdef SFX /**************************/ @@ -239,20 +237,17 @@ char *GetLoadPath(__GPRO) extern char *_pgmptr; return _pgmptr; -# else /* use generic API call */ +# else /* def MSC */ /* use generic API call */ GetModuleFileName(NULL, G.filename, FILNAMSIZ); _ISO_INTERN(G.filename); /* translate to codepage of C rtl's stdio */ return G.filename; -# endif +# endif /* def MSC [else] */ } /* end function GetLoadPath() */ - - - -# else /* !SFX */ +# else /* def SFX */ # ifndef HAVE_WORKING_DIRENT_H @@ -300,8 +295,6 @@ static zDIR *Opendir(n) } /* end of function Opendir() */ - - /**********************/ /* Borrowed from ZIP 2.0 sources */ /* Function Readdir() */ /* Difference: no special handling for */ /**********************/ /* hidden or system files. */ @@ -327,8 +320,6 @@ static struct zdirent *Readdir(d) } /* end of function Readdir() */ - - /***********************/ /* Function Closedir() */ /* Borrowed from ZIP 2.0 sources */ /***********************/ @@ -340,10 +331,8 @@ static void Closedir(d) izu_free(d); } -# endif /* !HAVE_WORKING_DIRENT_H */ -# endif /* ?SFX */ - - +# endif /* ndef HAVE_WORKING_DIRENT_H */ +# endif /* def SFX [else] */ # ifdef NTSD_EAS @@ -413,7 +402,6 @@ static int SetSD(__G__ path, fperms, eb_ptr, eb_len) - /********************************/ /* scan extra fields for something */ /* Function FindSDExtraField() */ /* we happen to know */ /********************************/ @@ -522,7 +510,7 @@ static int FindSDExtraField(__GPRO__ # ifdef __BORLANDC__ /* Turn off warning about not using all parameters for this function only */ -# pragma argsused +# pragma argsused # endif int test_NTSD(__G__ eb, eb_size, eb_ucptr, eb_ucsize) __GDEF @@ -534,10 +522,8 @@ int test_NTSD(__G__ eb, eb_size, eb_ucptr, eb_ucsize) return (ValidateSecurity(eb_ucptr) ? PK_OK : PK_WARN); } /* end function test_NTSD() */ -# endif /* !SFX */ -# endif /* NTSD_EAS */ - - +# endif /* ndef SFX */ +# endif /* def NTSD_EAS */ /**********************/ @@ -559,7 +545,6 @@ int IsWinNT(void) /* returns TRUE if real NT, FALSE if Win9x or Win32s */ } -/* DEBUG_TIME insertion: */ # ifdef DEBUG_TIME static int show_NTFileTime(FILE *hdo, char *TTmsg, int isloc, FILETIME *pft); @@ -581,11 +566,11 @@ static int show_NTFileTime(FILE *hdo, char *TTmsg, int isloc, FILETIME *pft) } return rval; } -#define FTTrace(x) show_NTFileTime x +# define FTTrace(x) show_NTFileTime x # else -#define FTTrace(x) -# endif /* DEBUG_TIME */ -/* end of DEBUG_TIME insertion */ +# define FTTrace(x) +# endif /* def DEBUG_TIME */ + # ifndef IZ_USE_INT64 # if (defined(__GNUC__) || defined(ULONG_LONG_MAX)) @@ -609,23 +594,23 @@ static int show_NTFileTime(FILE *hdo, char *TTmsg, int isloc, FILETIME *pft) typedef unsigned __int64 ULLNG64; # define IZ_USE_INT64 # endif -# endif +# endif /* ndef IZ_USE_INT64 */ /* scale factor and offset for conversion time_t -> FILETIME */ -#define NT_QUANTA_PER_UNIX 10000000L -#define UNIX_TIME_ZERO_HI 0x019DB1DEUL -#define UNIX_TIME_ZERO_LO 0xD53E8000UL +# define NT_QUANTA_PER_UNIX 10000000L +# define UNIX_TIME_ZERO_HI 0x019DB1DEUL +# define UNIX_TIME_ZERO_LO 0xD53E8000UL /* special FILETIME values for bound-checks */ -#define UNIX_TIME_UMAX_HI 0x0236485EUL -#define UNIX_TIME_UMAX_LO 0xD4A5E980UL -#define UNIX_TIME_SMIN_HI 0x0151669EUL -#define UNIX_TIME_SMIN_LO 0xD53E8000UL -#define UNIX_TIME_SMAX_HI 0x01E9FD1EUL -#define UNIX_TIME_SMAX_LO 0xD4A5E980UL -#define DOSTIME_MIN_FT_HI 0x01A8E79FUL -#define DOSTIME_MIN_FT_LO 0xE1D58000UL +# define UNIX_TIME_UMAX_HI 0x0236485EUL +# define UNIX_TIME_UMAX_LO 0xD4A5E980UL +# define UNIX_TIME_SMIN_HI 0x0151669EUL +# define UNIX_TIME_SMIN_LO 0xD53E8000UL +# define UNIX_TIME_SMAX_HI 0x01E9FD1EUL +# define UNIX_TIME_SMAX_LO 0xD4A5E980UL +# define DOSTIME_MIN_FT_HI 0x01A8E79FUL +# define DOSTIME_MIN_FT_LO 0xE1D58000UL /* time_t equivalent of DOSTIME_MINIMUM */ -#define UTIME_1980_JAN_01_00_00 315532800L +# define UTIME_1980_JAN_01_00_00 315532800L # ifndef NO_W32TIMES_IZFIX @@ -646,7 +631,7 @@ static void utime2NtfsFileTime(time_t ut, FILETIME *pft) pft->dwLowDateTime = (DWORD)NTtime; pft->dwHighDateTime = (DWORD)(NTtime >> 32); -# else /* !IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */ +# else /* def IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */ unsigned int b1, b2, carry = 0; unsigned long r0, r1, r2, r3; long r4; /* signed, to catch environments with signed time_t */ @@ -669,10 +654,10 @@ static void utime2NtfsFileTime(time_t ut, FILETIME *pft) carry++; pft->dwHighDateTime = r4 + (r2 >> 16) + (r3 >> 16) + UNIX_TIME_ZERO_HI + carry; -# endif /* ?IZ_USE_INT64 */ +# endif /* def IZ_USE_INT64 [else] */ } /* end function utime2NtfsFileTime() */ -# endif /* !NO_W32TIMES_IZFIX */ +# endif /* ndef NO_W32TIMES_IZFIX */ @@ -736,9 +721,9 @@ static void utime2VFatFileTime(time_t ut, FILETIME *pft, int clipDosMin) /* nonzero if `y' is a leap year, else zero */ -#define leap(y) (((y)%4 == 0 && (y)%100 != 0) || (y)%400 == 0) +# define leap(y) (((y)%4 == 0 && (y)%100 != 0) || (y)%400 == 0) /* number of leap years from 1970 to `y' (not including `y' itself) */ -#define nleap(y) (((y)-1969)/4 - ((y)-1901)/100 + ((y)-1601)/400) +# define nleap(y) (((y)-1969)/4 - ((y)-1901)/100 + ((y)-1601)/400) extern ZCONST ush ydays[]; /* defined in fileio.c */ @@ -772,7 +757,7 @@ static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut) } } else -# endif /* CHECK_UTIME_SIGNED_UNSIGNED */ +# endif /* def CHECK_UTIME_SIGNED_UNSIGNED */ { if (NTtime < ((ULLNG64)UNIX_TIME_ZERO_LO + ((ULLNG64)UNIX_TIME_ZERO_HI << 32))) { @@ -785,13 +770,13 @@ static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut) return FALSE; } } -# endif /* !TIME_T_TYPE_DOUBLE */ +# endif /* ndef TIME_T_TYPE_DOUBLE */ NTtime -= ((ULLNG64)UNIX_TIME_ZERO_LO + ((ULLNG64)UNIX_TIME_ZERO_HI << 32)); *ut = (time_t)(NTtime / (unsigned long)NT_QUANTA_PER_UNIX); return TRUE; -# else /* !IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */ +# else /* def IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */ time_t days; SYSTEMTIME w32tm; @@ -813,7 +798,7 @@ static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut) } } else -# endif /* CHECK_UTIME_SIGNED_UNSIGNED */ +# endif /* def CHECK_UTIME_SIGNED_UNSIGNED */ { if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) || ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) && @@ -828,7 +813,7 @@ static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut) return FALSE; } } -# endif /* !TIME_T_TYPE_DOUBLE */ +# endif /* ndef TIME_T_TYPE_DOUBLE */ FileTimeToSystemTime(pft, &w32tm); @@ -843,7 +828,7 @@ static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut) *ut = (time_t)(86400L * days + 3600L * (time_t)w32tm.wHour + (time_t)(60 * w32tm.wMinute + w32tm.wSecond)); return TRUE; -# endif /* ?IZ_USE_INT64 */ +# endif /* def IZ_USE_INT64 [else] */ } /* end function NtfsFileTime2utime() */ # endif /* W32_STAT_BANDAID && !NO_W32TIMES_IZFIX */ @@ -900,7 +885,7 @@ static int VFatFileTime2utime(const FILETIME *pft, time_t *ut) * a resolution of 2 seconds and are therefore even numbers. */ return (((*ut)&1) == (time_t)0); -# else /* HAVE_MKTIME */ +# else /* ndef HAVE_MKTIME */ FileTimeToSystemTime(&lft, &w32tm); # ifndef TIME_T_TYPE_DOUBLE /* underflow and overflow handling */ @@ -924,7 +909,7 @@ static int VFatFileTime2utime(const FILETIME *pft, time_t *ut) } } else -# endif /* CHECK_UTIME_SIGNED_UNSIGNED */ +# endif /* def CHECK_UTIME_SIGNED_UNSIGNED */ { if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) || ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) && @@ -939,7 +924,7 @@ static int VFatFileTime2utime(const FILETIME *pft, time_t *ut) return FALSE; } } -# endif /* !TIME_T_TYPE_DOUBLE */ +# endif /* ndef TIME_T_TYPE_DOUBLE [else] */ ltm.tm_year = w32tm.wYear - 1900; ltm.tm_mon = w32tm.wMonth - 1; ltm.tm_mday = w32tm.wDay; @@ -956,11 +941,10 @@ static int VFatFileTime2utime(const FILETIME *pft, time_t *ut) * (The only known exception is creation time on VFAT partitions.) */ return (*ut != (time_t)-1L); -# endif /* ?HAVE_MKTIME */ +# endif /* ndef HAVE_MKTIME [else] */ } /* end function VFatFileTime2utime() */ -# endif /* W32_STAT_BANDAID */ - +# endif /* def W32_STAT_BANDAID */ /******************************/ @@ -981,22 +965,17 @@ static int FStampIsLocTimeW(__GPRO__ const wchar_t *pathw) - # ifndef NO_W32TIMES_IZFIX -# define UTIME_2_IZFILETIME(ut, pft) \ - if (fs_uses_loctime) {utime2VFatFileTime(ut, pft, TRUE);} \ - else {utime2NtfsFileTime(ut, pft);} +# define UTIME_2_IZFILETIME(ut, pft) \ + if (fs_uses_loctime) {utime2VFatFileTime(ut, pft, TRUE);} \ + else {utime2NtfsFileTime(ut, pft);} # else -# define UTIME_2_IZFILETIME(ut, pft) \ - utime2VFatFileTime(ut, pft, fs_uses_loctime); +# define UTIME_2_IZFILETIME(ut, pft) \ + utime2VFatFileTime(ut, pft, fs_uses_loctime); # endif - - - - /****************************/ /* Get the file time in a format that */ /* Function getNTfiletime() */ /* can be used by SetFileTime() in NT */ /****************************/ @@ -1035,7 +1014,7 @@ static int getNTfiletime(__G__ pModFT, pAccFT, pCreFT) } return (int)eb_izux_flg; } -# endif /* USE_EF_UT_TIME */ +# endif /* def USE_EF_UT_TIME */ # ifndef NO_W32TIMES_IZFIX if (!fs_uses_loctime) { time_t ux_modtime; @@ -1093,7 +1072,7 @@ static int getNTfiletime(__G__ pModFT, pAccFT, pCreFT) } return (int)eb_izux_flg; } -# endif /* USE_EF_UT_TIME */ +# endif /* def USE_EF_UT_TIME */ # ifndef NO_W32TIMES_IZFIX if (!fs_uses_loctime) { time_t ux_modtime; @@ -1101,7 +1080,7 @@ static int getNTfiletime(__G__ pModFT, pAccFT, pCreFT) ux_modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime); utime2NtfsFileTime(ux_modtime, pModFT); } else -# endif /* NO_W32TIMES_IZFIX */ +# endif /* ndef NO_W32TIMES_IZFIX */ { FILETIME lft; @@ -1114,8 +1093,7 @@ static int getNTfiletime(__G__ pModFT, pAccFT, pCreFT) return (EB_UT_FL_MTIME | EB_UT_FL_ATIME); } /* end function getNTfiletime() */ -# endif /* (UNICODE_SUPPORT && WIN32_WIDE) */ - +# endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ @@ -1129,7 +1107,7 @@ int SetFileSize(FILE *file, zusz_t filesize) /* RSXNT environment lacks a translation function from C file pointer to Win32-API file handle. So, simply do nothing. */ return 0; -# else /* !__RSXNT__ */ +# else /* def __RSXNT__ */ /* not yet verified, if that really creates an unfragmented file rommel@ars.de */ @@ -1165,12 +1143,11 @@ int SetFileSize(FILE *file, zusz_t filesize) } /* move file position pointer back to the start of the file! */ return (SetFilePointer(os_fh, 0, 0, FILE_BEGIN) == 0xFFFFFFFF) ? -1 : 0; -# endif /* ?__RSXNT__ */ +# endif /* def __RSXNT__ [else] */ } /* end function SetFileSize() */ - /****************************/ /* Function close_outfile() */ /****************************/ @@ -1342,16 +1319,16 @@ void close_outfile(__G) * Perhaps the count or time interval should depend on the file * size? */ -#ifdef RETRY_CREATEFILE +# ifdef RETRY_CREATEFILE for (cf_tries = IZ_CREATEFILE_TRY_COUNT; cf_tries > 0 ; cf_tries--) { -#endif /* def RETRY_CREATEFILE */ +# endif /* def RETRY_CREATEFILE */ hFile = CreateFileA( Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -#ifdef RETRY_CREATEFILE +# ifdef RETRY_CREATEFILE if (hFile == INVALID_HANDLE_VALUE) { if (GetLastError() != ERROR_SHARING_VIOLATION) @@ -1363,7 +1340,7 @@ void close_outfile(__G) break; /* Not a sharing error. (Success?) Get out now. */ } } -#endif /* def RETRY_CREATEFILE */ +# endif /* def RETRY_CREATEFILE */ /* sfield@microsoft.com: set attributes before time in case we decide to support other filetime members later. This also allows us to apply @@ -1404,7 +1381,7 @@ void close_outfile(__G) } # endif /* ? (defined(UNICODE_SUPPORT) && defined(WIN32_WIDE)) */ } -# endif /* NTSD_EAS */ +# endif /* def NTSD_EAS */ /* skip restoring time stamps on user's request */ if (uO.D_flag <= 1) { @@ -1428,7 +1405,7 @@ void close_outfile(__G) return; -#undef Ansi_Fname +# undef Ansi_Fname # if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) } else { @@ -1442,15 +1419,15 @@ void close_outfile(__G) worry about overflowing unsigned ints with unsigned longs. ---------------------------------------------------------------------------*/ -# ifdef SYMLINKS +# ifdef SYMLINKS if (G.symlnk) { extent ucsize = (extent)G.lrec.ucsize; -# ifdef SET_SYMLINK_ATTRIBS +# ifdef SET_SYMLINK_ATTRIBS extent attribsize = sizeof(unsigned) + (have_uidgid_flg ? sizeof( z_uidgid) : 0); -# else +# else extent attribsize = 0; -# endif +# endif /* Note: Hard-coded assumption that sizeof( wchar_t) = 2. */ int fname_aligner = (attribsize+ ucsize+ 1)& 1; /* Necessary? */ @@ -1486,13 +1463,13 @@ void close_outfile(__G) slnk_entry->targetlen = ucsize; slnk_entry->attriblen = attribsize; slnk_entry->wide = 1; -# ifdef SET_SYMLINK_ATTRIBS +# ifdef SET_SYMLINK_ATTRIBS memcpy(slnk_entry->buf, &(G.pInfo->file_attr), sizeof(unsigned)); if (have_uidgid_flg) memcpy( (slnk_entry->buf + sizeof( unsigned)), z_uidgid, sizeof( z_uidgid)); -# endif +# endif slnk_entry->target = slnk_entry->buf + slnk_entry->attriblen; slnk_entry->fname = slnk_entry->target + ucsize + 1 + fname_aligner; wcscpy( (wchar_t *)slnk_entry->fname, G.unipath_widefilename); @@ -1526,7 +1503,7 @@ void close_outfile(__G) fclose( G.outfile); return; } -# endif /* def SYMLINKS */ +# endif /* def SYMLINKS */ # ifndef __RSXNT__ if (IsWinNT()) { @@ -1554,16 +1531,16 @@ void close_outfile(__G) time stamps */ /* 2013-07-08 SMS. See note above. */ -#ifdef RETRY_CREATEFILE +# ifdef RETRY_CREATEFILE for (cf_tries = IZ_CREATEFILE_TRY_COUNT; cf_tries > 0 ; cf_tries--) { -#endif /* def RETRY_CREATEFILE */ +# endif /* def RETRY_CREATEFILE */ hFile = CreateFileW(G.unipath_widefilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -#ifdef RETRY_CREATEFILE +# ifdef RETRY_CREATEFILE if (hFile == INVALID_HANDLE_VALUE) { if (GetLastError() != ERROR_SHARING_VIOLATION) @@ -1575,7 +1552,7 @@ void close_outfile(__G) break; /* Not a sharing error. (Success?) Get out now. */ } } -#endif /* def RETRY_CREATEFILE */ +# endif /* def RETRY_CREATEFILE */ /* sfield@microsoft.com: set attributes before time in case we decide to support other filetime members later. This also allows us to apply @@ -1640,7 +1617,6 @@ void close_outfile(__G) - # ifdef SET_DIR_ATTRIB int defer_dir_attribs(__G__ pd) @@ -1797,9 +1773,9 @@ int set_direc_attribs(__G__ d) # ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ ansi_name = (char *)alloca(strlen(d->fn) + 1); INTERN_TO_ISO(d->fn, ansi_name); -# define Ansi_Dirname ansi_name +# define Ansi_Dirname ansi_name # else -# define Ansi_Dirname d->fn +# define Ansi_Dirname d->fn # endif /* Skip restoring directory time stamps on user' request. */ @@ -2000,11 +1976,11 @@ int stamp_file(__GPRO__ ZCONST char *fname, time_t modtime) int fs_uses_loctime = FStampIsLocTime(__G__ fname); /* 2013-07-08 SMS. See note above. */ -# ifdef RETRY_CREATEFILE +# ifdef RETRY_CREATEFILE int cf_tries; -# endif +# endif -# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ +# ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ char *ansi_name = (char *)alloca(strlen(fname) + 1); INTERN_TO_ISO(fname, ansi_name); @@ -2015,16 +1991,16 @@ int stamp_file(__GPRO__ ZCONST char *fname, time_t modtime) /* open a handle to the file to prepare setting the mod-time stamp */ -#ifdef RETRY_CREATEFILE +# ifdef RETRY_CREATEFILE for (cf_tries = IZ_CREATEFILE_TRY_COUNT; cf_tries > 0 ; cf_tries--) { -#endif /* def RETRY_CREATEFILE */ +# endif /* def RETRY_CREATEFILE */ hFile = CreateFileA( Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -#ifdef RETRY_CREATEFILE +# ifdef RETRY_CREATEFILE if (hFile == INVALID_HANDLE_VALUE) { if (GetLastError() != ERROR_SHARING_VIOLATION) @@ -2036,7 +2012,7 @@ int stamp_file(__GPRO__ ZCONST char *fname, time_t modtime) break; /* Not a sharing error. (Success?) Get out now. */ } } -#endif /* def RETRY_CREATEFILE */ +# endif /* def RETRY_CREATEFILE */ if ( hFile == INVALID_HANDLE_VALUE ) { errstat = -1; @@ -2052,11 +2028,10 @@ int stamp_file(__GPRO__ ZCONST char *fname, time_t modtime) return errstat; -#undef Ansi_Fname +# undef Ansi_Fname } /* end function stamp_file() */ -# endif /* TIMESTAMP */ - +# endif /* def TIMESTAMP */ @@ -2214,7 +2189,6 @@ static int NTQueryVolInfoW(__GPRO__ const wchar_t *namew) - /*****************************/ /* Function IsVolumeOldFAT() */ /*****************************/ @@ -2233,7 +2207,6 @@ static int IsVolumeOldFATw(__GPRO__ const wchar_t *namew) - # ifndef SFX /************************/ @@ -2372,7 +2345,7 @@ char *do_wild(__G__ wildspec) } /* end function do_wild() */ -# endif /* !SFX */ +# endif /* ndef SFX */ @@ -2711,7 +2684,7 @@ int mapname(__G__ renamed) } /* success: skip the "extraction" quietly */ return (error & ~MPN_MASK) | MPN_INF_SKIP; -#undef Ansi_Fname +# undef Ansi_Fname } Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n", FnFilter1(G.filename), error)); @@ -2722,7 +2695,6 @@ int mapname(__G__ renamed) # if defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) - int mapnamew(__G__ renamed) __GDEF int renamed; @@ -3002,7 +2974,6 @@ int mapnamew(__G__ renamed) - /****************************/ /* Function maskDOSdevice() */ /****************************/ @@ -3321,8 +3292,8 @@ int checkdir(__G__ pathcomp, flag) /* static char *endHPFS; */ /* corresponding pointers to end of */ /* static char *endFAT; */ /* buildpath ('\0') */ -# define FN_MASK 7 -# define FUNCTION (flag & FN_MASK) +# define FN_MASK 7 +# define FUNCTION (flag & FN_MASK) @@ -3388,7 +3359,7 @@ int checkdir(__G__ pathcomp, flag) } G.created_dir = TRUE; } -# endif /* FIX_STAT_BUG */ +# endif /* def FIX_STAT_BUG */ if (SSTAT(G.buildpathFAT, &G.statbuf)) /* path doesn't exist */ { if (!G.create_dirs) { /* told not to create (freshening) */ @@ -3667,7 +3638,7 @@ int checkdir(__G__ pathcomp, flag) } return MPN_OK; } -# endif /* !SFX || SFX_EXDIR */ +# endif /* (!defined(SFX) || defined(SFX_EXDIR)) */ /*--------------------------------------------------------------------------- END: free rootpath, immediately prior to program exit. @@ -3797,7 +3768,7 @@ int checkdirw(__G__ pathcompw, flag) G.created_dir = TRUE; } } -# endif /* FIX_STAT_BUG */ +# endif /* def FIX_STAT_BUG */ if (SSTATW(G.buildpathFATw, &G.statbuf)) /* path doesn't exist */ { if (!G.create_dirs) { /* told not to create (freshening) */ @@ -4138,7 +4109,7 @@ int checkdirw(__G__ pathcompw, flag) } return MPN_OK; } -# endif /* !SFX || SFX_EXDIR */ +# endif /* (!defined(SFX) || defined(SFX_EXDIR)) */ /*--------------------------------------------------------------------------- END: free rootpath, immediately prior to program exit. @@ -4161,7 +4132,6 @@ int checkdirw(__G__ pathcompw, flag) - # ifndef SFX /*************************/ @@ -4306,7 +4276,11 @@ void version(__G) "unknown compiler (SDK?)", "", # endif /* ?compilers */ - "\nWindows 9x / Windows NT/2K/XP/2K3", " (32-bit)", +# ifdef _WIN64 + "\nWindows NT family", " (64-bit)", +# else + "\nWindows 9x or NT family", " (32-bit)", +# endif # ifdef __DATE__ " on ", __DATE__ @@ -4322,7 +4296,7 @@ void version(__G) } /* end function version() */ # endif /* ndef WINDLL_OLD */ -# endif /* !SFX */ +# endif /* ndef SFX */ @@ -4340,7 +4314,7 @@ int screensize(int *tt_rows, int *tt_cols) return 0; /* signal success */ } -# endif /* MORE */ +# endif /* def MORE */ @@ -4437,7 +4411,7 @@ int zstat_win32(__W32STAT_GLOBALS__ const char *path, z_stat *buf) TTrace((stdout,"NTFS, recalculated modtime %08lx\n", buf->st_mtime)); } else -# endif /* NO_W32TIMES_IZFIX */ +# endif /* ndef NO_W32TIMES_IZFIX */ { /* On VFAT and FAT-like filesystems, the FILETIME values * are converted back to the stable local time before @@ -4487,7 +4461,7 @@ int zstat_win32(__W32STAT_GLOBALS__ const char *path, z_stat *buf) } /* assumes: stat() won't fail on non-dirs without good reason */ # undef Ansi_Path } -# endif /* W32_STATROOT_FIX */ +# endif /* def W32_STATROOT_FIX */ return -1; } @@ -4537,7 +4511,7 @@ int zstat_win32w(__W32STAT_GLOBALS__ const wchar_t *pathw, z_stat *buf) TTrace((stdout,"NTFS, recalculated modtime %08lx\n", buf->st_mtime)); } else -# endif /* NO_W32TIMES_IZFIX */ +# endif /* ndef NO_W32TIMES_IZFIX */ { /* On VFAT and FAT-like filesystems, the FILETIME values * are converted back to the stable local time before @@ -4585,21 +4559,21 @@ int zstat_win32w(__W32STAT_GLOBALS__ const wchar_t *pathw, z_stat *buf) return 0; } /* assumes: stat() won't fail on non-dirs without good reason */ } -# endif /* W32_STATROOT_FIX */ +# endif /* def W32_STATROOT_FIX */ return -1; } # endif /* defined(UNICODE_SUPPORT) && defined(WIN32_WIDE) */ -# endif /* W32_STAT_BANDAID */ +# endif /* def W32_STAT_BANDAID */ # ifdef W32_USE_IZ_TIMEZONE -#include "timezone.h" -#define SECSPERMIN 60 -#define MINSPERHOUR 60 -#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +# include "timezone.h" +# define SECSPERMIN 60 +# define MINSPERHOUR 60 +# define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule); static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule) @@ -4664,7 +4638,7 @@ int GetPlatformLocalTimezone(register struct state * ZCONST sp, } # endif /* W32_USE_IZ_TIMEZONE */ -#endif /* !FUNZIP */ +#endif /* ndef FUNZIP */ @@ -4717,7 +4691,7 @@ int getch_win32(void) # endif return ret; } -#endif /* !WINDLL */ +#endif /* ndef WINDLL */ diff --git a/windll/vc10/libbz2/libbz2.vcxproj b/windll/vc10/libbz2/libbz2.vcxproj index 0816634..fd728ce 100644 --- a/windll/vc10/libbz2/libbz2.vcxproj +++ b/windll/vc10/libbz2/libbz2.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {A78C1242-16DD-4F61-B2A4-0740165B414E} @@ -21,21 +29,38 @@ true Unicode + + StaticLibrary + true + Unicode + StaticLibrary false true Unicode + + StaticLibrary + false + true + Unicode + + + + + + + @@ -51,6 +76,19 @@ true + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;BZ_NO_STDIO;%(PreprocessorDefinitions) + + + Windows + true + + Level3 @@ -68,6 +106,23 @@ true + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;BZ_NO_STDIO;%(PreprocessorDefinitions) + + + Windows + true + true + true + + diff --git a/windll/vc10/unzip32_dll.sln b/windll/vc10/unzip32_dll.sln index 2859cf9..740e911 100644 --- a/windll/vc10/unzip32_dll.sln +++ b/windll/vc10/unzip32_dll.sln @@ -7,7 +7,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unzip32_dll", "unzip32_dll\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uzexampl", "uzexampl\uzexampl.vcxproj", "{BE884407-2908-4690-846D-60031B5D17FA}" ProjectSection(ProjectDependencies) = postProject - {A78C1242-16DD-4F61-B2A4-0740165B414E} = {A78C1242-16DD-4F61-B2A4-0740165B414E} {24CEFBE3-3307-4F78-88CB-A625631CC333} = {24CEFBE3-3307-4F78-88CB-A625631CC333} EndProjectSection EndProject @@ -21,25 +20,43 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {24CEFBE3-3307-4F78-88CB-A625631CC333}.Debug|Win32.ActiveCfg = Debug|Win32 {24CEFBE3-3307-4F78-88CB-A625631CC333}.Debug|Win32.Build.0 = Debug|Win32 + {24CEFBE3-3307-4F78-88CB-A625631CC333}.Debug|x64.ActiveCfg = Debug|x64 + {24CEFBE3-3307-4F78-88CB-A625631CC333}.Debug|x64.Build.0 = Debug|x64 {24CEFBE3-3307-4F78-88CB-A625631CC333}.Release|Win32.ActiveCfg = Release|Win32 {24CEFBE3-3307-4F78-88CB-A625631CC333}.Release|Win32.Build.0 = Release|Win32 + {24CEFBE3-3307-4F78-88CB-A625631CC333}.Release|x64.ActiveCfg = Release|x64 + {24CEFBE3-3307-4F78-88CB-A625631CC333}.Release|x64.Build.0 = Release|x64 {BE884407-2908-4690-846D-60031B5D17FA}.Debug|Win32.ActiveCfg = Debug|Win32 {BE884407-2908-4690-846D-60031B5D17FA}.Debug|Win32.Build.0 = Debug|Win32 + {BE884407-2908-4690-846D-60031B5D17FA}.Debug|x64.ActiveCfg = Debug|x64 + {BE884407-2908-4690-846D-60031B5D17FA}.Debug|x64.Build.0 = Debug|x64 {BE884407-2908-4690-846D-60031B5D17FA}.Release|Win32.ActiveCfg = Release|Win32 {BE884407-2908-4690-846D-60031B5D17FA}.Release|Win32.Build.0 = Release|Win32 + {BE884407-2908-4690-846D-60031B5D17FA}.Release|x64.ActiveCfg = Release|x64 + {BE884407-2908-4690-846D-60031B5D17FA}.Release|x64.Build.0 = Release|x64 {A78C1242-16DD-4F61-B2A4-0740165B414E}.Debug|Win32.ActiveCfg = Debug|Win32 {A78C1242-16DD-4F61-B2A4-0740165B414E}.Debug|Win32.Build.0 = Debug|Win32 + {A78C1242-16DD-4F61-B2A4-0740165B414E}.Debug|x64.ActiveCfg = Debug|x64 + {A78C1242-16DD-4F61-B2A4-0740165B414E}.Debug|x64.Build.0 = Debug|x64 {A78C1242-16DD-4F61-B2A4-0740165B414E}.Release|Win32.ActiveCfg = Release|Win32 {A78C1242-16DD-4F61-B2A4-0740165B414E}.Release|Win32.Build.0 = Release|Win32 + {A78C1242-16DD-4F61-B2A4-0740165B414E}.Release|x64.ActiveCfg = Release|x64 + {A78C1242-16DD-4F61-B2A4-0740165B414E}.Release|x64.Build.0 = Release|x64 {FDD441BF-F3BC-4628-B383-CB974C40A055}.Debug|Win32.ActiveCfg = Debug|Win32 {FDD441BF-F3BC-4628-B383-CB974C40A055}.Debug|Win32.Build.0 = Debug|Win32 + {FDD441BF-F3BC-4628-B383-CB974C40A055}.Debug|x64.ActiveCfg = Debug|x64 + {FDD441BF-F3BC-4628-B383-CB974C40A055}.Debug|x64.Build.0 = Debug|x64 {FDD441BF-F3BC-4628-B383-CB974C40A055}.Release|Win32.ActiveCfg = Release|Win32 {FDD441BF-F3BC-4628-B383-CB974C40A055}.Release|Win32.Build.0 = Release|Win32 + {FDD441BF-F3BC-4628-B383-CB974C40A055}.Release|x64.ActiveCfg = Release|x64 + {FDD441BF-F3BC-4628-B383-CB974C40A055}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/windll/vc10/unzip32_dll/unzip32_dll.vcxproj b/windll/vc10/unzip32_dll/unzip32_dll.vcxproj index 99ba9ec..f4cefa6 100644 --- a/windll/vc10/unzip32_dll/unzip32_dll.vcxproj +++ b/windll/vc10/unzip32_dll/unzip32_dll.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {24CEFBE3-3307-4F78-88CB-A625631CC333} @@ -22,21 +30,38 @@ true Unicode + + DynamicLibrary + true + Unicode + DynamicLibrary false true Unicode + + DynamicLibrary + false + true + Unicode + + + + + + + true @@ -44,19 +69,31 @@ $(SolutionDir)\$(Configuration);$(LibraryPath) unzip32 + + true + ..\..\..;..\..\..\bzip2;$(IncludePath) + $(SolutionDir)\$(Configuration);$(LibraryPath) + unzip32 + false ..\..\..;..\..\..\bzip2;$(IncludePath) $(SolutionDir)\$(Configuration);$(LibraryPath) unzip32 + + false + ..\..\..;..\..\..\bzip2;$(IncludePath) + $(SolutionDir)\$(Configuration);$(LibraryPath) + unzip32 + Level3 Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;ASM_CRC;x_BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS + WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS Windows @@ -68,6 +105,25 @@ + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;x_ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS + + + Windows + true + ..\..\windll32.def + $(OutDir);%(AdditionalLibraryDirectories) + + + + + + Level3 @@ -76,7 +132,25 @@ MaxSpeed true true - WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;ASM_CRC;x_BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS + + + Windows + true + true + true + ..\..\windll32.def + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL;WINDLL;x_ASM_CRC;BZIP2_SUPPORT;x_CRYPT_AES_WG;LZMA_SUPPORT;PPMD_SUPPORT;x_SYMLINKS Windows @@ -84,6 +158,7 @@ true true ..\..\windll32.def + $(OutDir);%(AdditionalLibraryDirectories) diff --git a/windll/vc10/unzipstb/unzipstb.vcxproj b/windll/vc10/unzipstb/unzipstb.vcxproj index cf87b9d..f7ebf77 100644 --- a/windll/vc10/unzipstb/unzipstb.vcxproj +++ b/windll/vc10/unzipstb/unzipstb.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + @@ -29,30 +37,55 @@ true Unicode + + Application + true + Unicode + Application false true Unicode + + Application + false + true + Unicode + + + + + + + true ..\..\..;$(IncludePath) + + true + ..\..\..;$(IncludePath) + false ..\..\..;$(IncludePath) + + false + ..\..\..;$(IncludePath) + @@ -72,6 +105,25 @@ unzip32.lib;%(AdditionalDependencies) + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;DLL;WINDLL + + + + + + + Console + true + $(OutDir);%(AdditionalLibraryDirectories) + unzip32.lib;%(AdditionalDependencies) + + Level3 @@ -91,6 +143,25 @@ unzip32.lib;%(AdditionalDependencies) + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;DLL;WINDLL + + + Console + true + true + true + $(OutDir);%(AdditionalLibraryDirectories) + unzip32.lib;%(AdditionalDependencies) + + diff --git a/windll/vc10/uzexampl/uzexampl.vcxproj b/windll/vc10/uzexampl/uzexampl.vcxproj index 1fcbc3f..b4b25a1 100644 --- a/windll/vc10/uzexampl/uzexampl.vcxproj +++ b/windll/vc10/uzexampl/uzexampl.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {BE884407-2908-4690-846D-60031B5D17FA} @@ -21,30 +29,55 @@ true Unicode + + Application + true + Unicode + Application false true Unicode + + Application + false + true + Unicode + + + + + + + true ..\..\..;$(IncludePath) + + true + ..\..\..;$(IncludePath) + false ..\..\..;$(IncludePath) + + false + ..\..\..;$(IncludePath) + @@ -59,6 +92,20 @@ Version.lib;%(AdditionalDependencies) + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE + + + Console + true + Version.lib;%(AdditionalDependencies) + + Level3 @@ -77,6 +124,24 @@ Version.lib;%(AdditionalDependencies) + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE + + + Console + true + true + true + Version.lib;%(AdditionalDependencies) + + diff --git a/windll/windll.c b/windll/windll.c index cf8ff28..cfb885e 100644 --- a/windll/windll.c +++ b/windll/windll.c @@ -1031,7 +1031,8 @@ int WINAPI Wiz_Grep(LPSTR archive, LPSTR file, LPSTR pattern, int cmd, int SkipBin, LPUSERFUNCTIONS lpUserFunctions) { int retcode = FALSE, compare; - ulg i, j, patternLen, buflen; + ulg i, j, buflen; + size_t patternLen; char * sz, *p; UzpBuffer retstr; diff --git a/zipinfo.c b/zipinfo.c index 0fe49c1..2a0cc29 100644 --- a/zipinfo.c +++ b/zipinfo.c @@ -2041,7 +2041,8 @@ static int zi_long(__G__ pEndprev, error_in_archive) case EF_TIME: if (eb_len > 0) { char types[80]; - int num = 0, len; + int num = 0; + size_t len; *types = '\0'; if (*ef_ptr & 1) { -- 2.7.4