summaryrefslogtreecommitdiff
path: root/msdos
diff options
context:
space:
mode:
authorLorry <lorry@roadtrain.codethink.co.uk>2012-07-20 19:30:57 +0100
committerLorry <lorry@roadtrain.codethink.co.uk>2012-07-20 19:30:57 +0100
commit04664087ad66f5614f82a2cfba3ae4eda15e792b (patch)
tree332090b15fd2db1b93abf40dccf06211d9aba297 /msdos
downloadzip-04664087ad66f5614f82a2cfba3ae4eda15e792b.tar.gz
Tarball conversion
Diffstat (limited to 'msdos')
-rw-r--r--msdos/README.DOS132
-rw-r--r--msdos/crc_i86.asm497
-rw-r--r--msdos/makebz2.dj2148
-rw-r--r--msdos/makefile.bor197
-rw-r--r--msdos/makefile.dj1126
-rw-r--r--msdos/makefile.dj2136
-rw-r--r--msdos/makefile.emx169
-rw-r--r--msdos/makefile.msc209
-rw-r--r--msdos/makefile.tc177
-rw-r--r--msdos/makefile.wat256
-rw-r--r--msdos/match.asm477
-rw-r--r--msdos/msdos.c1126
-rw-r--r--msdos/osdep.h218
-rw-r--r--msdos/zipup.h16
14 files changed, 3884 insertions, 0 deletions
diff --git a/msdos/README.DOS b/msdos/README.DOS
new file mode 100644
index 0000000..0b9a57b
--- /dev/null
+++ b/msdos/README.DOS
@@ -0,0 +1,132 @@
+README.DOS
+
+Some notes about the supplied MSDOS executables and their compilers:
+
+A) The 32-bit DOS executables "zip.exe" and the auxilary utilities
+ "zipnote.exe", "zipsplit.exe", "zipcloak.exe" (crypt-enabled distribution
+ only) were compiled with DJGPP v 2.03, using gcc 2.95.3 as compiler.
+ They require a DPMI server to run, e.g.: a DOS command prompt window
+ under WINDOWS 3.x or Windows 9x. To use this program under plain DOS,
+ you should install the free (GPL'ed) DPMI server CWSDPMI.EXE. Look
+ for "csdpmi5b.zip" under "simtelnet/gnu/djgpp/v2misc/" on the SimTelNet
+ home site "ftp.cdrom.com" or any mirror site of the SimtelNet archive.
+
+ We have decided to provide 32-bit rather than 16-bit executables of
+ the auxilary tools for the following reasons:
+ - Nowadays, it has become quite unlikely to find PC computers "in action"
+ that do not at least have an i386 CPU.
+ - the 32-bit versions do not impose additional archive handling limits
+ beyond those defined by the Zip archive format
+ - the 32-bit DJGPP executables can handle long filenames on systems running
+ Windows 95/98/Me and Windows 2K/XP.
+
+B) There are two 16-bit MSDOS executables provided in zcr2?x.zip:
+ zip16.exe regular Zip program, requires ca. 455 KBytes of contiguous
+ free DOS memory or more.
+ zip16-sm.exe a variant that was compiled with the SMALL_MEM option
+ for minimal memory consumption; requires at minimum
+ 322 KBytes of contiguous free DOS memory.
+
+ The SMALL_MEM variant requires much less space for the compression
+ buffers, but at the cost of some compression efficiency.
+ Therefore, we recommend to use the "SMALL_MEM" 16-bit "zip16-sm.exe" only
+ in case of "out of memory" problems (DOS memory is low and/or very large
+ number of archive entries), when the 32-bit program cannot be used for
+ some reason (286 or older; no DPMI server; ...).
+
+C) Hard limits of the Zip archive format:
+ Number of entries in Zip archive: 64 k (2^16 - 1 entries)
+ Compressed size of archive entry: 4 GByte (2^32 - 1 Bytes)
+ Uncompressed size of entry: 4 GByte (2^32 - 1 Bytes)
+ Size of single-volume Zip archive: 4 GByte (2^32 - 1 Bytes)
+ Per-volume size of multi-volume archives: 4 GByte (2^32 - 1 Bytes)
+ Number of parts for multi-volume archives: 64 k (1^16 - 1 parts)
+ Total size of multi-volume archive: 256 TByte (4G * 64k)
+
+ The number of archive entries and of multivolume parts are limited by
+ the structure of the "end-of-central-directory" record, where the these
+ numbers are stored in 2-Byte fields.
+ Some Zip and/or UnZip implementations (for example Info-ZIP's) allow
+ handling of archives with more than 64k entries. (The information
+ from "number of entries" field in the "end-of-central-directory" record
+ is not really neccessary to retrieve the contents of a Zip archive;
+ it should rather be used for consistency checks.)
+
+ Length of an archive entry name: 64 kByte (2^16 - 1)
+ Length of archive member comment: 64 kByte (2^16 - 1)
+ Total length of "extra field": 64 kByte (2^16 - 1)
+ Length of a single e.f. block: 64 kByte (2^16 - 1)
+ Length of archive comment: 64 KByte (2^16 - 1)
+
+ Additional limitation claimed by PKWARE:
+ Size of local-header structure (fixed fields of 30 Bytes + filename
+ local extra field): < 64 kByte
+ Size of central-directory structure (46 Bytes + filename +
+ central extra field + member comment): < 64 kByte
+
+D) Implementation limits of the Zip executables:
+
+ 1. Size limits caused by file I/O and compression handling:
+ Size of Zip archive: 2 GByte (2^31 - 1 Bytes)
+ Compressed size of archive entry: 2 GByte (2^31 - 1 Bytes)
+ Uncompressed size of entry: 2 GByte (2^31 - 1 Bytes),
+ (could/should be 4 GBytes...)
+ Multi-volume archive creation is not supported.
+
+ 2. Limits caused by handling of archive contents lists
+
+ 2.1. Number of archive entries (freshen, update, delete)
+ a) 16-bit executable: 64k (2^16 -1) or 32k (2^15 - 1),
+ (unsigned vs. signed type of size_t)
+ a1) 16-bit executable: <16k ((2^16)/4)
+ (The smaller limit a1) results from the array size limit of
+ the "qsort()" function.)
+ 32-bit executables <1G ((2^32)/4)
+ (usual system limit of the "qsort()" function on 32-bit systems)
+
+ b) stack space needed by qsort to sort list of archive entries
+
+ NOTE: In the current executables, overflows of limits a) and b) are NOT
+ checked!
+
+ c) amount of free memory to hold "central directory information" of
+ all archive entries; one entry needs:
+ 96 bytes (32-bit) resp. 80 bytes (16-bit)
+ + 3 * length of entry name
+ + length of zip entry comment (when present)
+ + length of extra field(s) (when present, e.g.: UT needs 9 bytes)
+ + some bytes for book-keeping of memory allocation
+
+ Conclusion:
+ For systems with limited memory space (MSDOS, small AMIGAs, other
+ environments without virtual memory), the number of archive entries
+ is most often limited by condition c).
+ For example, with approx. 100 kBytes of free memory after loading and
+ initializing the program, a 16-bit DOS Zip cannot process more than 600
+ to 1000 (+) archive entries. (For the 16-bit Windows DLL or the 16-bit
+ OS/2 port, limit c) is less important because Windows or OS/2 executables
+ are not restricted to the 1024k area of real mode memory. These 16-bit
+ ports are limited by conditions a1) and b), say: at maximum approx.
+ 16000 entries!)
+
+
+ 2.2. Number of "new" entries (add operation)
+ In addition to the restrictions above (2.1.), the following limits
+ caused by the handling of the "new files" list apply:
+
+ a) 16-bit executable: <16k ((2^64)/4)
+
+ b) stack size required for "qsort" operation on "new entries" list.
+
+ NOTE: In the current executables, the overflow checks for these limits
+ are missing!
+
+ c) amount of free memory to hold the directory info list for new entries;
+ one entry needs:
+ 24 bytes (32-bit) resp. 22 bytes (16-bit)
+ + 3 * length of filename
+
+
+Please report any problems to: Zip-Bugs@lists.wku.edu
+
+Last updated: 07 July 2001
diff --git a/msdos/crc_i86.asm b/msdos/crc_i86.asm
new file mode 100644
index 0000000..3ad0349
--- /dev/null
+++ b/msdos/crc_i86.asm
@@ -0,0 +1,497 @@
+;===========================================================================
+; Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; (the contents of which are also included in zip.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
+;===========================================================================
+; Created by Christian Spieler, last modified 07 Jan 2007.
+;
+ TITLE crc_i86.asm
+ NAME crc_i86
+;
+; Optimized 8086 assembler version of the CRC32 calculation loop, intended
+; for real mode Info-ZIP programs (Zip 2.1, UnZip 5.2, and later versions).
+; Supported compilers are Microsoft C (DOS real mode) and Borland C(++)
+; (Turbo C). Watcom C (16bit) should also work.
+; This module was inspired by a similar module for the Amiga (Paul Kienitz).
+;
+; It replaces the `ulg crc32(ulg crc, ZCONST uch *buf, extent len)' function
+; in crc32.c.
+;
+; In March/April 1997, the code has been revised to incorporate Rodney Brown's
+; ideas for optimized access to the data buffer. For 8086 real mode code,
+; the data buffer is now accessed by aligned word-wide read operations.
+; This new optimization may be turned off by defining the macro switch
+; NO_16_BIT_LOADS.
+;
+; In December 1998, the loop branch commands were changed from "loop dest"
+; into "dec cx; jnz dest". On modern systems (486 and newer), the latter
+; code is usually much faster (e.g. 1 clock cycle compared to 5 for "loop"
+; on Pentium MMX). For the 286, the penalty of "dec cx; jnz" is one clock
+; cycle (12 vs. 11 cycles); on an 8088 the cycle counts are 22 (dec cx; jnz)
+; vs. 18 (loop). I decided to optimize for newer CPU models by default, because
+; I expect that old 80286 or 8088 dinosaurier machines may be rarely used
+; nowadays. In case you want optimum performance for these old CPU models
+; you should define the OPTIMIZE_286_88 macro switch on the assembler's
+; command line.
+; Likewise, "jcxz" was replaced by "jz", because the latter is faster on
+; 486 and newer CPUs (without any penalty on 80286 and older CPU models).
+;
+; In January 2007, the "hand-made" memory model setup section has been guarded
+; against redefinition of @CodeSize and @DataSize symbols, to work around a
+; problem with current Open Watcom (version 1.6) wasm assembler.
+;
+; The code in this module should work with all kinds of C memory models
+; (except Borland's __HUGE__ model), as long as the following
+; restrictions are not violated:
+;
+; - The implementation assumes that the char buffer is confined to a
+; 64k segment. The pointer `s' to the buffer must be in a format that
+; all bytes can be accessed by manipulating the offset part, only.
+; This means:
+; + no huge pointers
+; + char buffer size < 64 kByte
+;
+; - Since the buffer size argument `n' is of type `size_t' (= unsigned short)
+; for this routine, the char buffer size is limited to less than 64 kByte,
+; anyway. So, the assumption above should be easily fulfilled.
+;
+;==============================================================================
+;
+; Do NOT assemble this source if external crc32 routine from zlib gets used,
+; or only the precomputed CRC_32_Table is needed.
+;
+ifndef USE_ZLIB
+ifndef CRC_TABLE_ONLY
+;
+; Setup of amount of assemble time informational messages:
+;
+ifdef DEBUG
+ VERBOSE_INFO EQU 1
+else
+ ifdef _AS_MSG_
+ VERBOSE_INFO EQU 1
+ else
+ VERBOSE_INFO EQU 0
+ endif
+endif
+;
+; Selection of memory model, and initialization of memory model
+; related macros:
+;
+ifndef __SMALL__
+ ifndef __COMPACT__
+ ifndef __MEDIUM__
+ ifndef __LARGE__
+ ifndef __HUGE__
+; __SMALL__ EQU 1
+ endif
+ endif
+ endif
+ endif
+endif
+
+ifdef __HUGE__
+; .MODEL Huge
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
+ Save_DS EQU 1
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Huge memory model
+ endif
+ endif
+else
+ ifdef __LARGE__
+; .MODEL Large
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Large memory model
+ endif
+ endif
+ else
+ ifdef __COMPACT__
+; .MODEL Compact
+ ifndef @CodeSize
+ @CodeSize EQU 0
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Compact memory model
+ endif
+ endif
+ else
+ ifdef __MEDIUM__
+; .MODEL Medium
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 0
+ endif
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Medium memory model
+ endif
+ endif
+ else
+; .MODEL Small
+ ifndef @CodeSize
+ @CodeSize EQU 0
+ endif
+ ifndef @DataSize
+ @DataSize EQU 0
+ endif
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Small memory model
+ endif
+ endif
+ endif
+ endif
+ endif
+endif
+
+if @CodeSize
+ LCOD_OFS EQU 2
+else
+ LCOD_OFS EQU 0
+endif
+
+IF @DataSize
+ LDAT_OFS EQU 2
+else
+ LDAT_OFS EQU 0
+endif
+
+ifdef Save_DS
+; (di,si,ds)+(size, return address)
+ SAVE_REGS EQU 6+(4+LCOD_OFS)
+else
+; (di,si)+(size, return address)
+ SAVE_REGS EQU 4+(4+LCOD_OFS)
+endif
+
+;
+; Selection of the supported CPU instruction set and initialization
+; of CPU type related macros:
+;
+ifdef __686
+ Use_286_code EQU 1
+ Align_Size EQU 4 ; dword alignment on Pentium II/III/IV
+ Alig_PARA EQU 1 ; paragraph aligned code segment
+else
+ifdef __586
+ Use_286_code EQU 1
+ Align_Size EQU 4 ; dword alignment on Pentium
+ Alig_PARA EQU 1 ; paragraph aligned code segment
+else
+ifdef __486
+ Use_286_code EQU 1
+ Align_Size EQU 4 ; dword alignment on 32 bit processors
+ Alig_PARA EQU 1 ; paragraph aligned code segment
+else
+ifdef __386
+ Use_286_code EQU 1
+ Align_Size EQU 4 ; dword alignment on 32 bit processors
+ Alig_PARA EQU 1 ; paragraph aligned code segment
+else
+ifdef __286
+ Use_286_code EQU 1
+ Align_Size EQU 2 ; word alignment on 16 bit processors
+ Alig_PARA EQU 0 ; word aligned code segment
+else
+ifdef __186
+ Use_186_code EQU 1
+ Align_Size EQU 2 ; word alignment on 16 bit processors
+ Alig_PARA EQU 0 ; word aligned code segment
+else
+ Align_Size EQU 2 ; word alignment on 16 bit processors
+ Alig_PARA EQU 0 ; word aligned code segment
+endif ;?__186
+endif ;?__286
+endif ;?__386
+endif ;?__486
+endif ;?__586
+endif ;?__686
+
+ifdef Use_286_code
+ .286
+ Have_80x86 EQU 1
+else
+ifdef Use_186_code
+ .186
+ Have_80x86 EQU 1
+else
+ .8086
+ Have_80x86 EQU 0
+endif ;?Use_186_code
+endif ;?Use_286_code
+
+;
+; Declare the segments used in this module:
+;
+if @CodeSize
+if Alig_PARA
+CRC32_TEXT SEGMENT PARA PUBLIC 'CODE'
+else
+CRC32_TEXT SEGMENT WORD PUBLIC 'CODE'
+endif
+CRC32_TEXT ENDS
+else ;!@CodeSize
+if Alig_PARA
+_TEXT SEGMENT PARA PUBLIC 'CODE'
+else
+_TEXT SEGMENT WORD PUBLIC 'CODE'
+endif
+_TEXT ENDS
+endif ;?@CodeSize
+_DATA SEGMENT WORD PUBLIC 'DATA'
+_DATA ENDS
+_BSS SEGMENT WORD PUBLIC 'BSS'
+_BSS ENDS
+DGROUP GROUP _BSS, _DATA
+if @DataSize
+ ASSUME DS: nothing, SS: DGROUP
+else
+ ASSUME DS: DGROUP, SS: DGROUP
+endif
+
+if @CodeSize
+EXTRN _get_crc_table:FAR
+else
+EXTRN _get_crc_table:NEAR
+endif
+
+
+Do_CRC MACRO
+ mov bl,al
+ sub bh,bh
+if Have_80x86
+ shl bx,2
+else
+ shl bx,1
+ shl bx,1
+endif
+ mov al,ah
+ mov ah,dl
+ mov dl,dh
+ sub dh,dh
+ xor ax,WORD PTR [bx][si]
+ xor dx,WORD PTR [bx+2][si]
+ ENDM
+;
+Do_1 MACRO
+if @DataSize
+ xor al,BYTE PTR es:[di]
+else
+ xor al,BYTE PTR [di]
+endif
+ inc di
+ Do_CRC
+ ENDM
+;
+Do_2 MACRO
+ifndef NO_16_BIT_LOADS
+if @DataSize
+ xor ax,WORD PTR es:[di]
+else
+ xor ax,WORD PTR [di]
+endif
+ add di,2
+ Do_CRC
+ Do_CRC
+else
+ Do_1
+ Do_1
+endif
+ ENDM
+;
+Do_4 MACRO
+ Do_2
+ Do_2
+ ENDM
+;
+
+IF @CodeSize
+CRC32_TEXT SEGMENT
+ ASSUME CS: CRC32_TEXT
+else
+_TEXT SEGMENT
+ ASSUME CS: _TEXT
+endif
+; Line 37
+
+;
+;ulg crc32(ulg crc,
+; ZCONST uch *buf,
+; extent len)
+;
+ PUBLIC _crc32
+if @CodeSize
+_crc32 PROC FAR
+else
+_crc32 PROC NEAR
+endif
+if Have_80x86
+ enter WORD PTR 0,0
+else
+ push bp
+ mov bp,sp
+endif
+ push di
+ push si
+if @DataSize
+; crc = 4+LCOD_OFS DWORD (unsigned long)
+; buf = 8+LCOD_OFS DWORD PTR BYTE (uch *)
+; len = 12+LCOD_OFS WORD (unsigned int)
+else
+; crc = 4+LCOD_OFS DWORD (unsigned long)
+; buf = 8+LCOD_OFS WORD PTR BYTE (uch *)
+; len = 10+LCOD_OFS WORD (unsigned int)
+endif
+;
+if @DataSize
+ mov ax,WORD PTR [bp+8+LCOD_OFS] ; buf
+ or ax,WORD PTR [bp+10+LCOD_OFS] ; == NULL ?
+else
+ cmp WORD PTR [bp+8+LCOD_OFS],0 ; buf == NULL ?
+endif
+ jne crc_update
+ sub ax,ax ; crc = 0
+ cwd
+ifndef NO_UNROLLED_LOOPS
+ jmp fine
+else
+ jmp SHORT fine
+endif
+;
+crc_update:
+ call _get_crc_table
+; When used with compilers that conform to the Microsoft/Borland standard
+; C calling convention, model-dependent handling is not needed, because
+; _get_crc_table returns NEAR pointer.
+; But Watcom C is different and does not allow one to assume DS pointing to
+; DGROUP. So, we load DS with DGROUP, to be safe.
+;if @DataSize
+; push ds
+; mov ds,dx
+; ASSUME DS: nothing
+;endif
+ mov si,ax ;crc_table
+if @DataSize
+ push ds
+ mov ax,SEG DGROUP
+ mov ds,ax
+ ASSUME DS: DGROUP
+endif
+;
+ mov ax,WORD PTR [bp+4+LCOD_OFS] ;crc
+ mov dx,WORD PTR [bp+6+LCOD_OFS]
+ not ax
+ not dx
+if @DataSize
+ les di,DWORD PTR [bp+8+LCOD_OFS] ;buf
+ mov cx,WORD PTR [bp+12+LCOD_OFS] ;len
+else
+ mov di,WORD PTR [bp+8+LCOD_OFS] ;buf
+ mov cx,WORD PTR [bp+10+LCOD_OFS] ;len
+endif
+;
+ifndef NO_UNROLLED_LOOPS
+ifndef NO_16_BIT_LOADS
+ test cx,cx
+ jnz start
+ jmp done
+start: test di,1
+ jz is_wordaligned
+ dec cx
+ Do_1
+ mov WORD PTR [bp+10+LDAT_OFS+LCOD_OFS],cx
+is_wordaligned:
+endif ; !NO_16_BIT_LOADS
+if Have_80x86
+ shr cx,2
+else
+ shr cx,1
+ shr cx,1
+endif
+ jz No_Fours
+;
+ align Align_Size ; align destination of branch
+Next_Four:
+ Do_4
+ifndef OPTIMIZE_286_88
+ dec cx ; on 286, "loop Next_Four" needs 11
+ jnz Next_Four ; clocks, one less than this code
+else
+ loop Next_Four
+endif
+;
+No_Fours:
+if @DataSize
+ mov cx,WORD PTR [bp+12+LCOD_OFS] ;len
+else
+ mov cx,WORD PTR [bp+10+LCOD_OFS] ;len
+endif
+ and cx,00003H
+endif ; !NO_UNROLLED_LOOPS
+ jz done
+;
+ align Align_Size ; align destination of branch
+Next_Byte:
+ Do_1
+ifndef OPTIMIZE_286_88
+ dec cx ; on 286, "loop Next_Four" needs 11
+ jnz Next_Byte ; clocks, one less than this code
+else
+ loop Next_Four
+endif
+;
+done:
+if @DataSize
+ pop ds
+; ASSUME DS: DGROUP
+ ASSUME DS: nothing
+endif
+ not ax
+ not dx
+;
+fine:
+ pop si
+ pop di
+if Have_80x86
+ leave
+else
+ mov sp,bp
+ pop bp
+endif
+ ret
+
+_crc32 ENDP
+
+if @CodeSize
+CRC32_TEXT ENDS
+else
+_TEXT ENDS
+endif
+;
+endif ;!CRC_TABLE_ONLY
+endif ;!USE_ZLIB
+;
+END
diff --git a/msdos/makebz2.dj2 b/msdos/makebz2.dj2
new file mode 100644
index 0000000..161f1e3
--- /dev/null
+++ b/msdos/makebz2.dj2
@@ -0,0 +1,148 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# djgpp 2.x
+#
+# This simple modified version of makefile.dj2 adds bzip2 support
+# to Zip for djgpp 2.x and was donated by Robert Riebisch.
+#
+# Given standard djgpp 2.x and bzip2 installations, this should create a
+# version of Zip 3.0 with bzip2 support. Additional information is in
+# bzip2/install.txt.
+#
+# 27 June 2008
+
+VPATH=.;msdos
+# ------------- djgpp -------------
+CPPFLAGS=-I. -DDOS -DASM_CRC -DBZIP2_SUPPORT $(LOCAL_ZIP)
+ASFLAGS=$(CPPFLAGS)
+CFLAGS=-Wall -O2 $(CPPFLAGS)
+UTILFLAGS=-c -DUTIL $(CFLAGS) -o
+CC=gcc
+LD=gcc
+LDFLAGS=-s
+
+# ------------- file packer --------
+# Laszlo Molnar who wrote DJ Packer and Markus F. X. J. Oberhumer who wrote
+# the compression library used by the DJ Packer have collaborated on the
+# Ultimate Packer for eXecutables, which has recently been released. Look
+# for upx???d.zip at http://upx.sourceforge.net
+# As an alternative, look for "djp.exe", now two years old, in the archive
+# mlp107[b,s].zip, found in the same location as csdpmi?[b,s].zip (see below).
+# If you have got an executable packer in your PATH, you may reduce the
+# size of the disk image of the zip*.exe's by uncommenting the lines
+# containing $(DJP) below where the exe's are built.
+#DJP=djp -q
+DJP=upx -qq --best
+
+# variables
+
+#set CRC32 to crc_gcc.o or nothing, depending on whether ASM_CRC is defined:
+CRCA_O = crc_gcc.o
+
+OBJZ = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \
+ crc32.o $(CRCA_O) globals.o
+OBJI = deflate.o trees.o match.o msdos.o
+OBJU = zipfile_.o fileio_.o util_.o globals.o msdos_.o
+OBJN = zipnote.o $(OBJU)
+OBJC = zipcloak.o crc32_.o crypt_.o ttyio.o $(OBJU)
+OBJS = zipsplit.o $(OBJU)
+LIBS = -lbz2
+
+ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h
+
+# rules
+
+.SUFFIXES: # Delete make's default suffix list
+.SUFFIXES: .exe .out .a .ln .o .c .cc .C .p .f .F .y .l .s .S .h
+
+.c.o:
+ $(CC) -c $(CFLAGS) $< -o $@
+
+zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+
+zipfile.o: zipfile.c $(ZIP_H) crc32.h
+
+zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h
+
+fileio.o: fileio.c $(ZIP_H) crc32.h
+
+util.o: util.c $(ZIP_H)
+
+globals.o: globals.c $(ZIP_H)
+
+deflate.o: deflate.c $(ZIP_H)
+
+trees.o: trees.c $(ZIP_H)
+
+crc_gcc.o: crc_i386.S
+ $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S
+
+crc32.o: crc32.c $(ZIP_H) crc32.h
+
+crypt.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+
+ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h
+
+msdos.o: msdos/msdos.c $(ZIP_H)
+
+zipcloak.o: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+
+zipnote.o: zipnote.c $(ZIP_H) revision.h
+
+zipsplit.o: zipsplit.c $(ZIP_H) revision.h
+
+zipfile_.o: zipfile.c $(ZIP_H) crc32.h
+ $(CC) $(UTILFLAGS) $@ zipfile.c
+
+fileio_.o: fileio.c $(ZIP_H) crc32.h
+ $(CC) $(UTILFLAGS) $@ fileio.c
+
+util_.o: util.c $(ZIP_H)
+ $(CC) $(UTILFLAGS) $@ util.c
+
+crc32_.o: crc32.c $(ZIP_H) crc32.h
+ $(CC) $(UTILFLAGS) $@ crc32.c
+
+crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) $(UTILFLAGS) $@ crypt.c
+
+msdos_.o: msdos/msdos.c $(ZIP_H)
+ $(CC) $(UTILFLAGS) $@ msdos/msdos.c
+
+
+match.o: match.S
+ $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S
+
+zip.exe: $(OBJZ) $(OBJI)
+ echo $(OBJZ) > zip.rsp
+ echo $(OBJI) >> zip.rsp
+ echo $(LIBS) >> zip.rsp
+ $(LD) $(LDFLAGS) -o $@ @zip.rsp
+ del zip.rsp
+# stubedit $@ dpmi=cwsdpmi.exe
+# $(DJP) $@
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) $(OBJC) -o $@
+# stubedit $@ dpmi=cwsdpmi.exe
+# $(DJP) $@
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) $(OBJN) -o $@
+# stubedit $@ dpmi=cwsdpmi.exe
+# $(DJP) $@
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS) -o $@
+# stubedit $@ dpmi=cwsdpmi.exe
+# $(DJP) $@
+
+# These stand alone executables require dpmi services to run. When
+# running in a DOS window under windows 3.1 or later, the dpmi server
+# is automatically present. Under DOS, if a dpmi server is not installed,
+# by default the program will look for "cwsdpmi.exe." If found, it will
+# be loaded for the duration of the program.
+# cwsdpmi is a "free" dpmi server written by Charles W. Sandmann
+# (sandman@clio.rice.edu). It may be found, among other sites, on SimTel
+# and its mirrors in the .../vendors/djgpp/v2misc directory.
diff --git a/msdos/makefile.bor b/msdos/makefile.bor
new file mode 100644
index 0000000..88ecde4
--- /dev/null
+++ b/msdos/makefile.bor
@@ -0,0 +1,197 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# Borland (Turbo) C++ 1.0 or 2.0.
+# Warning: this file is not suitable for Turbo C 2.0. Use makefile.tc instead.
+
+# To use, do "make -fmakefile.bor"
+
+# WARNING: the small model is not supported.
+# Add -DSMALL_MEM or -DMEDIUM_MEM to the LOC macro if you wish to reduce
+# the memory requirements.
+# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if
+# you do not have tasm.
+
+# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM)
+# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added
+# to the declaration of LOC here:
+LOC = -DDOS -DNO_SECURE_TESTS $(LOCAL_ZIP)
+
+# Zip requires compact or large memory model.
+# with 2.1, compact model exceeds 64k code segment; use large model
+ZIPMODEL=l # large model for Zip and ZipUtils
+
+# name of Flag to select memory model for assembler compiles, supported
+# values are __SMALL__ , __MEDIUM__ , __COMPACT__ , __LARGE__ :
+ASMODEL=__LARGE__ # keep in sync with ZIPMODEL definition !!
+
+# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+CRCA_O = crc_i86.obj
+ASMOBJS = match.obj $(CRCA_O)
+
+ASCPUFLAG = __$(CPU_TYP)86
+!if $(CPU_TYP) != 0
+CC_CPUFLG = -$(CPU_TYP)
+!endif
+
+VPATH=.;msdos
+# ------------- Turbo C++, Borland C++ -------------
+!if $(CC_REV) == 1
+CC = tcc
+!else
+! if !$(CC_REV)
+CC_REV = 3
+! endif
+CC = bcc
+!endif
+
+MODEL=-m$(ZIPMODEL)
+!if $(CC_REV) == 1
+CFLAGS=-w -w-eff -w-def -w-sig -w-cln -a -d -G -O -Z $(CC_CPUFLG) $(MODEL) $(LOC)
+!else
+CFLAGS=-w -w-cln -O2 -Z $(CC_CPUFLG) $(MODEL) $(LOC)
+!endif
+UTILFLAGS=-DUTIL $(CFLAGS) -o
+# for Turbo C++ 1.0, replace bcc with tcc and use the upper version of CFLAGS
+
+AS=tasm
+ASFLAGS=-ml -t -m2 -DDYN_ALLOC -DSS_NEQ_DS -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC)
+
+LD=$(CC)
+LDFLAGS=$(MODEL)
+
+# ------------- Common declarations:
+STRIP=@rem
+# If you don't have UPX, LZEXE, or PKLITE, get one of them. Then define:
+# (NOTE: upx needs a 386 or higher system to run the exe compressor)
+#STRIP=upx --8086 --best
+# or
+#STRIP=lzexe
+# or (if you've registered PKLITE)
+#STRIP=pklite
+# This makes a big difference in .exe size (and possibly load time)
+
+# ------------- Used by install rule
+# set BIN to the directory you want to install the executables to
+BIN = c:\util
+
+# variables
+OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj globals.obj
+
+OBJI = deflate.obj trees.obj $(ASMOBJS) msdos.obj
+
+OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj msdos_.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.obj crc32_.obj crypt_.obj ttyio.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h
+
+ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zips: $(ZIPS)
+
+zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+util.obj: util.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+globals.obj: globals.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+msdos.obj: msdos/msdos.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) msdos/$*.c
+
+zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipnote.obj: zipnote.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$* zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$* fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$* util.c
+
+crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) crc32.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c $(UTILFLAGS)$* crypt.c
+
+msdos_.obj: msdos/msdos.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$* msdos/msdos.c
+
+crc_i86.obj: msdos/crc_i86.asm
+ $(AS) $(ASFLAGS) msdos\crc_i86.asm ;
+
+match.obj: msdos/match.asm
+ $(AS) $(ASFLAGS) msdos\match.asm ;
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+zip.exe: $(OBJZ) $(OBJI)
+ echo $(OBJZ) > zip.rsp
+ echo $(OBJI) >> zip.rsp
+ $(LD) $(LDFLAGS) @zip.rsp
+ del zip.rsp
+ $(STRIP) zip.exe
+
+zipcloak.exe: $(OBJC)
+ echo $(OBJC) > zipc.rsp
+ $(LD) $(LDFLAGS) @zipc.rsp
+ del zipc.rsp
+ $(STRIP) zipcloak.exe
+
+zipnote.exe: $(OBJN)
+ echo $(OBJN) > zipn.rsp
+ $(LD) $(LDFLAGS) @zipn.rsp
+ del zipn.rsp
+ $(STRIP) zipnote.exe
+
+zipsplit.exe: $(OBJS)
+ echo $(OBJS) > zips.rsp
+ $(LD) $(LDFLAGS) @zips.rsp
+ del zips.rsp
+ $(STRIP) zipsplit.exe
+
+install: $(ZIPS)
+ copy /b *.exe $(BIN)
+
+clean:
+ del *.obj
+ del *.exe
diff --git a/msdos/makefile.dj1 b/msdos/makefile.dj1
new file mode 100644
index 0000000..05137cc
--- /dev/null
+++ b/msdos/makefile.dj1
@@ -0,0 +1,126 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# djgpp 1.x
+VPATH=.;msdos
+# ------------- djgpp -------------
+CPPFLAGS=-I. -DDOS -DASM_CRC $(LOCAL_ZIP)
+ASFLAGS=$(CPPFLAGS)
+CFLAGS=-Wall -O2 -m486 $(CPPFLAGS)
+UTILFLAGS=-c -DUTIL $(CFLAGS) -o
+CC=gcc
+LD=gcc
+LDFLAGS=-s
+
+STRIP=strip
+
+# Change the STUBIFY definition to the upper version if you want to create
+# executables which can be used without any external extender file.
+# >>> NOTE: Either copy the go32 extender into your build directory, or
+# >>> edit the STUBIFY macro and add the correct path to "go32.exe".
+#STUBIFY=coff2exe -s go32.exe
+STUBIFY=coff2exe
+
+# variables
+
+#set CRCA_O to crc_gcc.o or nothing, depending on whether ASM_CRC is defined:
+CRCA_O = crc_gcc.o
+
+OBJZ = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \
+ crc32.o $(CRCA_O) globals.o
+OBJI = deflate.o trees.o match.o msdos.o
+OBJU = zipfile_.o fileio_.o util_.o globals.o msdos_.o
+OBJN = zipnote.o $(OBJU)
+OBJC = zipcloak.o crc32_.o crypt_.o ttyio.o $(OBJU)
+OBJS = zipsplit.o $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h
+
+# rules
+
+.SUFFIXES: # Delete make's default suffix list
+.SUFFIXES: .exe .out .a .ln .o .c .cc .C .p .f .F .y .l .s .S .h
+
+.c.o:
+ $(CC) -c $(CFLAGS) $< -o $@
+
+zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+
+zipfile.o: zipfile.c $(ZIP_H) crc32.h
+
+zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h
+
+fileio.o: fileio.c $(ZIP_H)
+
+util.o: util.c $(ZIP_H)
+
+globals.o: globals.c $(ZIP_H)
+
+deflate.o: deflate.c $(ZIP_H)
+
+trees.o: trees.c $(ZIP_H)
+
+crc_gcc.o: crc_i386.S
+ $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S
+
+crc32.o: crc32.c $(ZIP_H) crc32.h
+
+crypt.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+
+ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h
+
+msdos.o: msdos/msdos.c $(ZIP_H)
+
+zipcloak.o: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+
+zipnote.o: zipnote.c $(ZIP_H) revision.h
+
+zipsplit.o: zipsplit.c $(ZIP_H) revision.h
+
+zipfile_.o: zipfile.c $(ZIP_H) crc32.h
+ $(CC) $(UTILFLAGS) $@ zipfile.c
+
+fileio_.o: fileio.c $(ZIP_H) crc32.h
+ $(CC) $(UTILFLAGS) $@ fileio.c
+
+util_.o: util.c $(ZIP_H)
+ $(CC) $(UTILFLAGS) $@ util.c
+
+crc32_.o: crc32.c $(ZIP_H) crc32.h
+ $(CC) $(UTILFLAGS) $@ crc32.c
+
+crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) $(UTILFLAGS) $@ crypt.c
+
+msdos_.o: msdos/msdos.c $(ZIP_H)
+ $(CC) $(UTILFLAGS) $@ msdos/msdos.c
+
+match.o: match.S
+ $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S
+
+zip.exe: $(OBJZ) $(OBJI)
+ echo $(OBJZ) > zip.rsp
+ echo $(OBJI) >> zip.rsp
+ $(LD) $(LDFLAGS) -o zip @zip.rsp
+ del zip.rsp
+ $(STRIP) zip
+ $(STUBIFY) zip
+ del zip
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) $(OBJC) -o zipcloak
+ $(STRIP) zipcloak
+ $(STUBIFY) zipcloak
+ del zipcloak
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) $(OBJN) -o zipnote
+ $(STRIP) zipnote
+ $(STUBIFY) zipnote
+ del zipnote
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS) -o zipsplit
+ $(STRIP) zipsplit
+ $(STUBIFY) zipsplit
+ del zipsplit
diff --git a/msdos/makefile.dj2 b/msdos/makefile.dj2
new file mode 100644
index 0000000..39192ee
--- /dev/null
+++ b/msdos/makefile.dj2
@@ -0,0 +1,136 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# djgpp 2.x
+VPATH=.;msdos
+# ------------- djgpp -------------
+CPPFLAGS=-I. -DDOS -DASM_CRC $(LOCAL_ZIP)
+ASFLAGS=$(CPPFLAGS)
+CFLAGS=-Wall -O2 $(CPPFLAGS)
+UTILFLAGS=-c -DUTIL $(CFLAGS) -o
+CC=gcc
+LD=gcc
+LDFLAGS=-s
+
+# ------------- file packer --------
+# Laszlo Molnar who wrote DJ Packer and Markus F. X. J. Oberhumer who wrote
+# the compression library used by the DJ Packer have collaborated on the
+# Ultimate Packer for eXecutables, which has recently been released. Look
+# for upx???d.zip at http://upx.sourceforge.net
+# As an alternative, look for "djp.exe", now two years old, in the archive
+# mlp107[b,s].zip, found in the same location as csdpmi?[b,s].zip (see below).
+# If you have got an executable packer in your PATH, you may reduce the
+# size of the disk image of the zip*.exe's by uncommenting the lines
+# containing $(DJP) below where the exe's are built.
+#DJP=djp -q
+DJP=upx -qq --best
+
+# variables
+
+#set CRC32 to crc_gcc.o or nothing, depending on whether ASM_CRC is defined:
+CRCA_O = crc_gcc.o
+
+OBJZ = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \
+ crc32.o $(CRCA_O) globals.o
+OBJI = deflate.o trees.o match.o msdos.o
+OBJU = zipfile_.o fileio_.o util_.o globals.o msdos_.o
+OBJN = zipnote.o $(OBJU)
+OBJC = zipcloak.o crc32_.o crypt_.o ttyio.o $(OBJU)
+OBJS = zipsplit.o $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h
+
+# rules
+
+.SUFFIXES: # Delete make's default suffix list
+.SUFFIXES: .exe .out .a .ln .o .c .cc .C .p .f .F .y .l .s .S .h
+
+.c.o:
+ $(CC) -c $(CFLAGS) $< -o $@
+
+zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+
+zipfile.o: zipfile.c $(ZIP_H) crc32.h
+
+zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h
+
+fileio.o: fileio.c $(ZIP_H) crc32.h
+
+util.o: util.c $(ZIP_H)
+
+globals.o: globals.c $(ZIP_H)
+
+deflate.o: deflate.c $(ZIP_H)
+
+trees.o: trees.c $(ZIP_H)
+
+crc_gcc.o: crc_i386.S
+ $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S
+
+crc32.o: crc32.c $(ZIP_H) crc32.h
+
+crypt.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+
+ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h
+
+msdos.o: msdos/msdos.c $(ZIP_H)
+
+zipcloak.o: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+
+zipnote.o: zipnote.c $(ZIP_H) revision.h
+
+zipsplit.o: zipsplit.c $(ZIP_H) revision.h
+
+zipfile_.o: zipfile.c $(ZIP_H) crc32.h
+ $(CC) $(UTILFLAGS) $@ zipfile.c
+
+fileio_.o: fileio.c $(ZIP_H) crc32.h
+ $(CC) $(UTILFLAGS) $@ fileio.c
+
+util_.o: util.c $(ZIP_H)
+ $(CC) $(UTILFLAGS) $@ util.c
+
+crc32_.o: crc32.c $(ZIP_H) crc32.h
+ $(CC) $(UTILFLAGS) $@ crc32.c
+
+crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) $(UTILFLAGS) $@ crypt.c
+
+msdos_.o: msdos/msdos.c $(ZIP_H)
+ $(CC) $(UTILFLAGS) $@ msdos/msdos.c
+
+
+match.o: match.S
+ $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S
+
+zip.exe: $(OBJZ) $(OBJI)
+ echo $(OBJZ) > zip.rsp
+ echo $(OBJI) >> zip.rsp
+ $(LD) $(LDFLAGS) -o $@ @zip.rsp
+ del zip.rsp
+# stubedit $@ dpmi=cwsdpmi.exe
+# $(DJP) $@
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) $(OBJC) -o $@
+# stubedit $@ dpmi=cwsdpmi.exe
+# $(DJP) $@
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) $(OBJN) -o $@
+# stubedit $@ dpmi=cwsdpmi.exe
+# $(DJP) $@
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS) -o $@
+# stubedit $@ dpmi=cwsdpmi.exe
+# $(DJP) $@
+
+# These stand alone executables require dpmi services to run. When
+# running in a DOS window under windows 3.1 or later, the dpmi server
+# is automatically present. Under DOS, if a dpmi server is not installed,
+# by default the program will look for "cwsdpmi.exe." If found, it will
+# be loaded for the duration of the program.
+# cwsdpmi is a "free" dpmi server written by Charles W. Sandmann
+# (sandman@clio.rice.edu). It may be found, among other sites, on SimTel
+# and its mirrors in the .../vendors/djgpp/v2misc directory.
diff --git a/msdos/makefile.emx b/msdos/makefile.emx
new file mode 100644
index 0000000..3a50b5b
--- /dev/null
+++ b/msdos/makefile.emx
@@ -0,0 +1,169 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit
+# using emx 0.9c for DOS.
+# By Kai-Uwe Rommel, Chr. Spieler, E-Yen Tan (and others).
+# Last updated 7th January 2007.
+#
+# This Makefile is a stripped down version of win32/Makefile.emx that
+# builds executables applying the default MSDOS emx setup. For variant
+# targets (using zlib), and cross-compilation for WIN32 or OS/2, take a
+# look into "win32/makefile.emx" resp. "os2/makefile.os2".
+#
+# Supported Make utilities:
+# - Microsoft/IBM nmake (e.g. from MSC 6.0 or newer)
+# - dmake 3.8 or higher
+# - GNU make, at least version 3.68 (GNUish 16-bit port, RSXNT Make 3.75 in a
+# Win95/WinNT DOS box, DJGPP v1.12 Make 3.71, some versions of DJGPP v2.x
+# 32-bit Make; current DJGPP v2.01 Make 3.76.1 does NOT work)
+# - NOT watcom make
+# The "smart" Make utilities mentioned below are Christian Spieler's
+# enhanced version of GNUish 16-bit Make (3.74) and his adaption of these
+# GNU Make sources to EMX (32-bit).
+
+# Supported 32-bit C Compilers for MSDOS:
+# - GNU gcc (emx kit 0.9c or newer, 32-bit)
+
+# Supported Assemblers:
+# - GNU as with GNU gcc
+
+
+# To use, enter "make/nmake/dmake -f msdos/makefile.emx"
+# (this makefile depends on its name being "msdos/makefile.emx").
+
+# emx 0.9c, gcc, a.out format, for MS-DOS
+CC=gcc -O2 -m486 -Wall
+CFLAGS=-DDOS -DMSDOS -DASM_CRC
+AS=gcc
+ASFLAGS=-Di386
+LDFLAGS=-o ./
+LDFLAGS2=-s -Zsmall-conv
+OUT=-o
+OBJ=.o
+CRCA_O=crc_gcc.o
+OBJA=matchgcc.o
+OBJZS=msdos.o
+OBJUS=msdos_.o
+OSDEP_H=msdos/osdep.h
+ZIPUP_H=msdos/zipup.h
+
+#default settings for target dependent macros:
+DIRSEP = /
+AS_DIRSEP = /
+RM = del
+LOCAL_OPTS = $(LOCAL_ZIP)
+CCFLAGS = $(CFLAGS) $(LOCAL_OPTS)
+
+
+OBJZ1 = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \
+ crc32$(OBJ) $(CRCA_O)
+OBJZ2 = globals$(OBJ) deflate$(OBJ) trees$(OBJ) crypt$(OBJ) \
+ ttyio$(OBJ)
+OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS) $(OBJA)
+
+OBJU1 = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) globals$(OBJ)
+OBJU = $(OBJU1) $(OBJUS)
+
+OBJN = zipnote$(OBJ) $(OBJU)
+OBJS = zipsplit$(OBJ) $(OBJU)
+OBJC1 = zipcloak$(OBJ) crc32_$(OBJ) crypt_$(OBJ) ttyio$(OBJ)
+OBJC = $(OBJC1) $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
+
+# rules
+
+.SUFFIXES: .c $(OBJ)
+
+.c$(OBJ):
+ $(CC) -c -I. $(CCFLAGS) $(OUT)$@ $<
+
+# targets
+
+all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zip$(OBJ): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+zipfile$(OBJ): zipfile.c $(ZIP_H) crc32.h
+zipup$(OBJ): zipup.c $(ZIP_H) revision.h crc32.h crypt.h $(ZIPUP_H)
+fileio$(OBJ): fileio.c $(ZIP_H) crc32.h
+util$(OBJ): util.c $(ZIP_H)
+globals$(OBJ): globals.c $(ZIP_H)
+deflate$(OBJ): deflate.c $(ZIP_H)
+trees$(OBJ): trees.c $(ZIP_H)
+crc32$(OBJ): crc32.c $(ZIP_H) crc32.h
+crypt$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ttyio$(OBJ): ttyio.c $(ZIP_H) crypt.h ttyio.h
+
+msdos$(OBJ): msdos/msdos.c $(ZIP_H)
+ $(CC) -c -I. $(CCFLAGS) msdos$(DIRSEP)msdos.c
+
+win32zip$(OBJ): win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32zip.c
+
+win32$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32.c
+
+nt$(OBJ): win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)nt.c
+
+crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS
+ $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S
+
+matchgcc$(OBJ): match.S
+ $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S
+
+zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+zipnote$(OBJ): zipnote.c $(ZIP_H) revision.h
+zipsplit$(OBJ): zipsplit.c $(ZIP_H) revision.h
+
+zipfile_$(OBJ): zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c
+
+fileio_$(OBJ): fileio.c $(ZIP_H) crc32.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ fileio.c
+
+util_$(OBJ): util.c $(ZIP_H)
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ util.c
+
+crc32_$(OBJ): crc32.c $(ZIP_H) crc32.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crc32.c
+
+crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crypt.c
+
+msdos_$(OBJ): msdos/msdos.c $(ZIP_H)
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ msdos$(DIRSEP)msdos.c
+
+win32_$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ win32$(DIRSEP)win32.c
+
+# This next bit is nasty, but is needed to overcome the MS-DOS command
+# line limit as response files for emx's gcc seem to only work if each
+# file is on a different line. DJGPP doesn't do this (if you are at all
+# interested).
+
+zip.exe: $(OBJZ)
+# for DUMB make utilities, uncomment the following commands:
+ -@$(RM) zip.rsp
+ @for %%f in ($(OBJZ1)) do echo %%f >> zip.rsp
+ @for %%f in ($(OBJZ2)) do echo %%f >> zip.rsp
+ @for %%f in ($(OBJZS) $(OBJA)) do echo %%f >> zip.rsp
+ $(CC) $(LDFLAGS)$@ @zip.rsp $(LDFLAGS2)
+ @$(RM) zip.rsp
+# smart make utilities (like well done ports of GNU Make) can use this:
+# $(CC) $(LDFLAGS)$@ $(OBJZ) $(LDFLAGS2)
+
+zipcloak.exe: $(OBJC)
+# for DUMB make utilities, uncomment the following commands:
+ -@$(RM) zipcloak.rsp
+ @for %%f in ($(OBJC1)) do echo %%f >> zipcloak.rsp
+ @for %%f in ($(OBJU1)) do echo %%f >> zipcloak.rsp
+ @for %%f in ($(OBJUS)) do echo %%f >> zipcloak.rsp
+ $(CC) $(LDFLAGS)$@ @zipcloak.rsp $(LDFLAGS2)
+ @$(RM) zipcloak.rsp
+# smart make utilities (like well done ports of GNU Make) can use this:
+# $(CC) $(LDFLAGS)$@ $(OBJC) $(LDFLAGS2)
+
+zipnote.exe: $(OBJN)
+ $(CC) $(LDFLAGS)$@ $(OBJN) $(LDFLAGS2)
+
+zipsplit.exe: $(OBJS)
+ $(CC) $(LDFLAGS)$@ $(OBJS) $(LDFLAGS2)
diff --git a/msdos/makefile.msc b/msdos/makefile.msc
new file mode 100644
index 0000000..a7ec9c9
--- /dev/null
+++ b/msdos/makefile.msc
@@ -0,0 +1,209 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# Microsoft C 5.1 and above.
+
+# To use, do "make makefile.msc"
+
+# Add -DSMALL_MEM or -DMEDIUM_MEM to the LOC macro if you wish to reduce
+# the memory requirements.
+# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if
+# you do not have masm.
+#
+# If you want link Zip against zlib to replace the built-in deflate routines,
+# the following changes are required:
+# - in the definition of "LOC", add "-DUSE_ZLIB" and remove "-DNO_SECURE_TESTS"
+# - comment out the "ASMOBJS" symbol definition
+# - modify the linking command blocks for zip and zipcloak according to
+# the following scheme:
+# add a command line "echo ,,,zlib_$(ZIPMODEL); >> zip[c].rsp" just
+# before the "$(LD)..." line; and remove the semicolon character from the
+# "echo ..." line immediately preceding the just inserted command
+
+
+# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM)
+# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added
+# to the declaration of LOC here:
+LOC = -DDOS -DDYN_ALLOC -DNO_SECURE_TESTS $(LOCAL_ZIP)
+
+# Zip requires compact or large memory model.
+# with 2.1, compact model exceeds 64k code segment; use large model
+ZIPMODEL=L # large model for Zip and ZipUtils
+
+# name of Flag to select memory model for assembler compiles, supported
+# values are __SMALL__ , __MEDIUM__ , __COMPACT__ , __LARGE__ :
+ASMODEL=__LARGE__ # keep in sync with ZIPMODEL definition !!
+
+# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+ASMOBJS = match.obj crc_i86.obj
+
+ASCPUFLAG = __$(CPU_TYP)86
+
+# ------------- Microsoft C 5.1, 6.0, 7.0 and VC++ Pro 1.0 -------------
+CC=cl
+MODEL=-A$(ZIPMODEL)
+FP=
+# With the feature additions of Zip 3, the default data segment gets occupied
+# with too much initialized data to fit into 64k. As a workaround, for some
+# source files with large amount of message strings, -Gt<num> is used to
+# force data items of size <num> or larger into their own data segments.
+COMMON_CFLAGS=-nologo -I. $(MODEL) $(FP) -DMSC $(LOC) -W3 -G$(CPU_TYP)
+CFLAGS=$(COMMON_CFLAGS) -Ox
+SPECFLAGS=$(COMMON_CFLAGS) -Oaict -Gs
+# For MSC/C++ 7.0 and VC++ no special flags are needed:
+# SPECFLAGS=$(CFLAGS)
+UTILFLAGS=-DUTIL $(CFLAGS) -Fo
+
+AS=masm
+ASFLAGS=-ml -t -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC)
+# For MSC 6.0, use:
+#AS=ml
+#ASFLAGS=-c -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC)
+# Supress -DDYN_ALLOC in ASFLAGS if you have suppressed it in CFLAGS
+
+LD=link
+LDFLAGS=/noi/farcall/packcode/e/st:0x1400/m
+# If you use an exe packer as recommended below, remove /e from LDFLAGS
+
+# ------------- Common declarations:
+STRIP=rem
+# If you don't have UPX, LZEXE, or PKLITE, get one of them. Then define:
+# (NOTE: upx needs a 386 or higher system to run the exe compressor)
+#STRIP=upx --8086 --best
+# or
+#STRIP=lzexe
+# or (if you've registered PKLITE)
+#STRIP=pklite
+# and remove /e from LDFLAGS.
+# This makes a big difference in .exe size (and possibly load time)
+
+# ------------- Used by install rule
+# set BIN to the directory you want to install the executables to
+BIN = c:\util
+
+# variables
+OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj globals.obj
+
+OBJI = deflate.obj trees.obj $(ASMOBJS) msdos.obj
+
+OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj msdos_.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.obj crc32_.obj crypt_.obj ttyio.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h
+
+ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zips: $(ZIPS)
+
+zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) -Gt65 $*.c
+
+# MSC 5.1 generates bad code on zipfile with -Ox
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(SPECFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+util.obj: util.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+globals.obj: globals.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+msdos.obj: msdos/msdos.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) msdos/$*.c
+
+zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipnote.obj: zipnote.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) $*.c
+
+# MSC 5.1 dies on zipsplit with -Ox
+zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+ $(CC) -c $(SPECFLAGS) $*.c
+
+# MSC 5.1 generates bad code on zipfile with -Ox
+zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(SPECFLAGS) -DUTIL -Fo$@ zipfile.c
+
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$@ fileio.c
+
+util_.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$@ util.c
+
+crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$@ crc32.c
+
+crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c $(UTILFLAGS)$@ crypt.c
+
+msdos_.obj: msdos/msdos.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$@ msdos/msdos.c
+
+crc_i86.obj: msdos/crc_i86.asm
+ $(AS) $(ASFLAGS) msdos\crc_i86.asm ;
+
+match.obj: msdos/match.asm
+ $(AS) $(ASFLAGS) msdos\match.asm ;
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+zip.exe: $(OBJZ) $(OBJI)
+ echo $(OBJZ)+ > zip.rsp
+ echo $(OBJI); >> zip.rsp
+ $(LD) $(LDFLAGS) @zip.rsp
+ del zip.rsp
+ $(STRIP) zip.exe
+
+zipcloak.exe: $(OBJC)
+ echo $(OBJC); > zipc.rsp
+ $(LD) $(LDFLAGS) @zipc.rsp
+ del zipc.rsp
+ $(STRIP) zipcloak.exe
+
+zipnote.exe: $(OBJN)
+ echo $(OBJN); > zipn.rsp
+ $(LD) $(LDFLAGS) @zipn.rsp
+ del zipn.rsp
+ $(STRIP) zipnote.exe
+
+zipsplit.exe: $(OBJS)
+ echo $(OBJS); > zips.rsp
+ $(LD) $(LDFLAGS) @zips.rsp
+ del zips.rsp
+ $(STRIP) zipsplit.exe
+
+# No `install' and `clean' target possible as long as MSC's old MAKE utility
+# is supported (MSC 5.1 Make always tries to update ALL targets. The result
+# is that install and clean are always executed, unless an error occured.)
+#install: $(ZIPS)
+# copy /b *.exe $(BIN)
+#
+#clean:
+# del *.obj
+# del *.exe
diff --git a/msdos/makefile.tc b/msdos/makefile.tc
new file mode 100644
index 0000000..9ce3e32
--- /dev/null
+++ b/msdos/makefile.tc
@@ -0,0 +1,177 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# Turbo C 2.0. (Thanks to Andrew Cadach <kadach@isi.itfs.nsk.su>)
+
+# To use, do "make -fmakefile.tc"
+
+# WARNING: the small model is not supported. You must use the large model.
+# Add -DSMALL_MEM or -DMEDIUM_MEM to the LOC macro if you wish to reduce
+# the memory requirements.
+# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if
+# you do not have tasm.
+
+# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM)
+# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added
+# to the declaration of LOC here:
+LOC = -DDOS -DNO_SECURE_TESTS $(LOCAL_ZIP)
+
+# Zip requires compact or large memory model.
+# with 2.1, compact model exceeds 64k code segment; use large model
+ZIPMODEL=l # large model for Zip and ZipUtils
+
+# name of Flag to select memory model for assembler compiles, supported
+# values are __SMALL__ , __MEDIUM__ , __COMPACT__ , __LARGE__ :
+ASMODEL=__LARGE__ # keep in sync with ZIPMODEL definition !!
+
+# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+ASMOBJS = match.obj crc_i86.obj
+
+ASCPUFLAG = __$(CPU_TYP)86
+
+# ------------- Turbo C 2.0 -------------
+MODEL=-m$(ZIPMODEL)
+CFLAGS=-w -w-eff -w-def -w-sig -w-cln -a -d -G -O -Z $(MODEL) $(LOC)
+UTILFLAGS=-DUTIL $(CFLAGS) -o
+CC=tcc
+
+# Old versions of tasm (prior to 2.01) may not like the "-m2" option...
+AS=tasm
+ASFLAGS=-ml -t -m2 -DDYN_ALLOC -DSS_NEQ_DS -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC)
+
+LD=tcc
+LDFLAGS=$(MODEL)
+
+# ------------- Common declarations:
+STRIP=rem
+# If you don't have UPX, LZEXE, or PKLITE, get one of them. Then define:
+# (NOTE: upx needs a 386 or higher system to run the exe compressor)
+#STRIP=upx --8086 --best
+# or
+#STRIP=lzexe
+# or (if you've registered PKLITE)
+#STRIP=pklite
+# This makes a big difference in .exe size (and possibly load time)
+
+# ------------- Used by install rule
+# set BIN to the directory you want to install the executables to
+BIN = c:\util
+
+# variables
+OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj globals.obj
+
+OBJI = deflate.obj trees.obj $(ASMOBJS) msdos.obj
+
+OBJU = _zipfile.obj _fileio.obj _util.obj globals.obj _msdos.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.obj _crc32.obj _crypt.obj ttyio.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h
+
+ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
+
+zips: $(ZIPS)
+
+zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
+
+fileio.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+util.obj: util.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+globals.obj: globals.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) $*.c
+
+crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
+
+msdos.obj: msdos/msdos.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) msdos/$*.c
+
+zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) -o$* $*.c
+
+zipnote.obj: zipnote.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) -o$* $*.c
+
+zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+ $(CC) -c $(CFLAGS) -o$* $*.c
+
+_zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$* zipfile.c
+
+_fileio.obj: fileio.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$* fileio.c
+
+_util.obj: util.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$* util.c
+
+_crc32.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$* crc32.c
+
+_crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c $(UTILFLAGS)$* crypt.c
+
+_msdos.obj: msdos/msdos.c $(ZIP_H)
+ $(CC) -c $(UTILFLAGS)$* msdos/msdos.c
+
+crc_i86.obj: msdos/crc_i86.asm
+ $(AS) $(ASFLAGS) msdos\crc_i86.asm ;
+
+match.obj: msdos/match.asm
+ $(AS) $(ASFLAGS) msdos\match.asm ;
+
+# make sure the command line fits in the MS/DOS 128 byte limit:
+zip.exe: $(OBJZ) $(OBJI)
+ rem ignore any warnings in the following renaming commands:
+ ren _*.obj _*.ob
+ ren zipcloak.obj *.ob
+ ren zipnote.obj *.ob
+ ren zipsplit.obj *.ob
+ $(LD) $(LDFLAGS) -ezip.exe *.obj
+ ren _*.ob _*.obj
+ ren zip???*.ob *.obj
+ $(STRIP) zip.exe
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) -ezipcloak.exe $(OBJC)
+ $(STRIP) zipcloak.exe
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) -ezipnote.exe $(OBJN)
+ $(STRIP) zipnote.exe
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) -ezipsplit.exe $(OBJS)
+ $(STRIP) zipsplit.exe
+
+install: $(ZIPS)
+ copy /b *.exe $(BIN)
+
+clean:
+ del *.obj
+ del *.exe
diff --git a/msdos/makefile.wat b/msdos/makefile.wat
new file mode 100644
index 0000000..dd4d8cd
--- /dev/null
+++ b/msdos/makefile.wat
@@ -0,0 +1,256 @@
+# WMAKE makefile for 16 bit MSDOS or 32 bit DOS extender (PMODE/W or DOS/4GW)
+# using Watcom C/C++ v11.0+, by Paul Kienitz, last revised 07 Aug 2005.
+# Makes Zip.exe, ZipNote.exe, ZipCloak.exe, and ZipSplit.exe.
+#
+# Invoke from Zip source dir with "WMAKE -F MSDOS\MAKEFILE.WAT [targets]"
+# To build with debug info use "WMAKE DEBUG=1 ..."
+# To build with no assembly modules use "WMAKE NOASM=1 ..."
+# To make the PMODE/W version use "WMAKE PM=1 ..."
+# To make the DOS/4GW version use "WMAKE GW=1 ..." (overrides PM=1)
+# Note: specifying PM or GW without NOASM requires that the win32 source
+# directory be present, so it can access the 32 bit assembly sources.
+# PMODE/W is recommended over DOS/4GW for best performance.
+# To create a low memory usage version of Zip, use "WMAKE WSIZE=8192 ..."
+# (or whatever power of two less than 32768 you wish) -- this also causes
+# SMALL_MEM to be defined. Compression performance will be reduced.
+# This currently is not supported with PM=1 or GW=1.
+#
+# Other options to be fed to the compiler and assembler can be specified in
+# an environment variable called LOCAL_ZIP.
+
+variation = $(%LOCAL_ZIP)
+
+# Stifle annoying "Delete this file?" questions when errors occur:
+.ERASE
+
+.EXTENSIONS:
+.EXTENSIONS: .exe .obj .c .h .asm
+
+# We maintain multiple sets of object files in different directories so that
+# we can compile msdos, dos/4gw or pmode/w, and win32 versions of Zip without
+# their object files interacting. The following var must be a directory name
+# ending with a backslash. All object file names must include this macro
+# at the beginning, for example "$(O)foo.obj".
+
+!ifdef GW
+PM = 1 # both protected mode formats use the same object files
+!endif
+
+!ifdef DEBUG
+! ifdef PM
+OBDIR = od32d
+! else
+! ifdef WSIZE
+OBDIR = od16l
+size = -DWSIZE=$(WSIZE) -DSMALL_MEM
+! else
+OBDIR = od16d
+size = -DMEDIUM_MEM
+! endif
+! endif
+!else
+! ifdef PM
+OBDIR = ob32d
+! else
+! ifdef WSIZE
+OBDIR = ob16l
+size = -DWSIZE=$(WSIZE) -DSMALL_MEM
+! else
+OBDIR = ob16d
+size = -DMEDIUM_MEM
+! endif
+! endif
+!endif
+O = $(OBDIR)\ # comment here so backslash won't continue the line
+
+# The assembly hot-spot code in crc_i[3]86.asm and match[32].asm is
+# optional. This section controls its usage.
+
+!ifdef NOASM
+ # C source
+asmob =
+cvars = $+$(cvars)$- -DDYN_ALLOC -DNO_ASM # or ASM_CRC might default on!
+# "$+$(foo)$-" means expand foo as it has been defined up to now; normally,
+# this make defers inner expansion until the outer macro is expanded.
+!else # !NOASM
+asmob = $(O)crc.obj $(O)match.obj
+! ifdef PM
+cvars = $+$(cvars)$- -DASM_CRC -DASMV # no DYN_ALLOC with match32.asm
+crc_s = win32\crc_i386.asm # requires that the win32 directory be present
+mat_s = win32\match32.asm # ditto
+! else
+cvars = $+$(cvars)$- -DDYN_ALLOC -DASM_CRC -DASMV
+avars = $+$(avars)$- -DDYN_ALLOC
+crc_s = msdos\crc_i86.asm
+mat_s = msdos\match.asm
+! endif
+!endif
+
+# Now we have to pick out the proper compiler and options for it. This gets
+# pretty complicated with the PM, GW, DEBUG, and NOASM options...
+
+link = wlink
+asm = wasm
+
+!ifdef PM
+cc = wcc386
+# Use Pentium Pro timings, register args, static strings in code:
+cflags = -bt=DOS -mf -6r -zt -zq
+aflags = -bt=DOS -mf -3 -zq
+cvars = $+$(cvars)$- -DDOS $(variation)
+avars = $+$(avars)$- -DWATCOM_DSEG $(variation)
+
+! ifdef GW
+lflags = sys DOS4G
+! else
+# THIS REQUIRES THAT PMODEW.EXE BE FINDABLE IN THE COMMAND PATH.
+# It does NOT require you to add a pmodew entry to wlink.lnk or wlsystem.lnk.
+defaultlibs = libpath %WATCOM%\lib386 libpath %WATCOM%\lib386\dos
+lflags = format os2 le op osname='PMODE/W' op stub=pmodew.exe $(defaultlibs)
+! endif
+
+!else # plain 16-bit DOS:
+
+cc = wcc
+# Use plain 8086 instructions, large memory model, static strings in code:
+cflags = -bt=DOS -ml -0 -zt -zq
+aflags = -bt=DOS -ml -0 -zq
+cvars = $+$(cvars)$- -DDOS $(size) $(variation)
+avars = $+$(avars)$- $(size) $(variation)
+lflags = sys DOS
+!endif # !PM
+
+# Specify optimizations, or a nonoptimized debugging version:
+
+!ifdef DEBUG
+cdebug = -od -d2
+ldebug = d w all op symf
+!else
+! ifdef PM
+cdebug = -s -obhikl+rt -oe=100 -zp8
+# -oa helps slightly but might be dangerous.
+! else
+cdebug = -s -oehiklrt
+! endif
+ldebug = op el
+!endif
+
+# How to compile most sources:
+.c.obj:
+ $(cc) $(cdebug) $(cflags) $(cvars) $[@ -fo=$@
+
+# Our object files. OBJZ is for Zip, OBJC is for ZipCloak, OBJN is for
+# ZipNote, and OBJS is for ZipSplit:
+
+OBJZ2 = $(O)zip.obj $(O)crypt.obj $(O)ttyio.obj $(O)zipfile.obj $(O)zipup.obj
+OBJZA = $(OBJZ2) $(O)util.obj $(O)fileio.obj $(O)deflate.obj
+OBJZB = $(O)trees.obj $(O)globals.obj $(O)crc32.obj $(asmob) $(O)msdos.obj
+
+OBJU2 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)globals.obj
+OBJ_U = $(OBJU2) $(O)msdos_.obj
+
+OBJC = $(O)zipcloak.obj $(O)crc32_.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U)
+
+OBJN = $(O)zipnote.obj $(OBJ_U)
+
+OBJS = $(O)zipsplit.obj $(OBJ_U)
+
+# Common header files included by all C sources:
+
+ZIP_H = zip.h ziperr.h tailor.h msdos\osdep.h
+
+
+# HERE WE GO! By default, make all targets:
+all: Zip.exe ZipNote.exe ZipCloak.exe ZipSplit.exe
+
+# Convenient shorthand options for single targets:
+z: Zip.exe .SYMBOLIC
+n: ZipNote.exe .SYMBOLIC
+c: ZipCloak.exe .SYMBOLIC
+s: ZipSplit.exe .SYMBOLIC
+
+Zip.exe: $(OBDIR) $(OBJZA) $(OBJZB) $(OBJV)
+ set WLK_VA=file {$(OBJZA)}
+ set WLK_VB=file {$(OBJZB) $(OBJV)}
+ $(link) $(lflags) $(ldebug) name $@ @WLK_VA @WLK_VB
+ set WLK_VA=
+ set WLK_VB=
+# We use WLK_VA and WLK_VB to keep the size of each command under 256 chars.
+
+ZipNote.exe: $(OBDIR) $(OBJN)
+ set WLK_VAR=file {$(OBJN)}
+ $(link) $(lflags) $(ldebug) name $@ @WLK_VAR
+ set WLK_VAR=
+
+ZipCloak.exe: $(OBDIR) $(OBJC)
+ set WLK_VAR=file {$(OBJC)}
+ $(link) $(lflags) $(ldebug) name $@ @WLK_VAR
+ set WLK_VAR=
+
+ZipSplit.exe: $(OBDIR) $(OBJS)
+ set WLK_VAR=file {$(OBJS)}
+ $(link) $(lflags) $(ldebug) name $@ @WLK_VAR
+ set WLK_VAR=
+
+# Source dependencies:
+
+$(O)crc32.obj: crc32.c $(ZIP_H) crc32.h
+$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+$(O)deflate.obj: deflate.c $(ZIP_H)
+$(O)fileio.obj: fileio.c $(ZIP_H) crc32.h
+$(O)globals.obj: globals.c $(ZIP_H)
+$(O)trees.obj: trees.c $(ZIP_H)
+$(O)ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
+$(O)util.obj: util.c $(ZIP_H)
+$(O)zip.obj: zip.c $(ZIP_H) crc32.h crypt.h revision.h ttyio.h
+$(O)zipfile.obj: zipfile.c $(ZIP_H) crc32.h
+$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos\zipup.h
+$(O)zipnote.obj: zipnote.c $(ZIP_H) revision.h
+$(O)zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+$(O)zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
+
+# Special case object files:
+
+$(O)msdos.obj: msdos\msdos.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) msdos\msdos.c -fo=$@
+
+$(O)match.obj: $(mat_s)
+ $(asm) $(aflags) $(avars) $(mat_s) -fo=$@
+
+$(O)crc.obj: $(crc_s)
+ $(asm) $(aflags) $(avars) $(crc_s) -fo=$@
+
+# Variant object files for ZipNote, ZipCloak, and ZipSplit:
+
+$(O)zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@
+
+$(O)fileio_.obj: fileio.c $(ZIP_H) crc32.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL fileio.c -fo=$@
+
+$(O)util_.obj: util.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL util.c -fo=$@
+
+$(O)crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crc32.c -fo=$@
+
+$(O)crypt_.obj: crypt.c $(ZIP_H) crc32.h crypt.h ttyio.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crypt.c -fo=$@
+
+$(O)msdos_.obj: msdos\msdos.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL msdos\msdos.c -fo=$@
+
+# Creation of subdirectory for intermediate files
+$(OBDIR):
+ -mkdir $@
+
+# Unwanted file removal:
+
+clean: .SYMBOLIC
+ del $(O)*.obj
+
+cleaner: clean .SYMBOLIC
+ del Zip.exe
+ del ZipNote.exe
+ del ZipCloak.exe
+ del ZipSplit.exe
diff --git a/msdos/match.asm b/msdos/match.asm
new file mode 100644
index 0000000..998881e
--- /dev/null
+++ b/msdos/match.asm
@@ -0,0 +1,477 @@
+;===========================================================================
+; Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2007-Mar-04 or later
+; (the contents of which are also included in zip.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
+;===========================================================================
+;
+; match.asm by Jean-loup Gailly.
+
+; match.asm, optimized version of longest_match() in deflate.c
+; Must be assembled with masm -ml. To be used only with C compact model
+; or large model. (For large model, assemble with -D__LARGE__).
+; This file is only optional. If you don't have masm or tasm, use the
+; C version (add -DNO_ASM to CFLAGS in makefile.msc and remove match.obj
+; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is
+; assembled with an equivalent -DWSIZE=<whatever>.
+;
+; The code has been prepared for two different C compiler calling conventions
+; and contains some support for dynamically allocated working space.
+; The different environments are selected by two conditional flags:
+; DYN_ALLOC : select support for malloc'ed working space
+; SS_NEQ_DS : relaxes assumption that stack and default data segments
+; are identical
+; When SS_NEQ_DS is defined, the code segment is used to store some
+; local variables. This (bad) coding practice is very likely to break any
+; `segment protection scheme', it will most probably only work for real
+; mode programs.
+;
+; Turbo C 2.0 does not support static allocation of more than 64K bytes per
+; file, and does not have SS == DS. So TC and BC++ users must use:
+; tasm -ml -DDYN_ALLOC -DSS_NEQ_DS match;
+;
+; To simplify the code, the option -DDYN_ALLOC is supported for OS/2
+; only if the arrays are guaranteed to have zero offset (allocated by
+; halloc). We also require SS==DS. This is satisfied for MSC but not Turbo C.
+;
+; Per default, test code is included to check if the above requirements are
+; fulfilled. This test code can be disabled by defining the compile time
+; option flag NO_SECURE_TESTS when compiling for a production executable.
+; This shortens the code size (but the performance gain is neglectable).
+; The security tests should remain enabled, when a new C compiler
+; and/or a new set of compilation options is tried.
+
+ name match
+
+; Do NOT assemble this source if external crc32 routine from zlib gets used.
+;
+ifndef USE_ZLIB
+
+ifdef DEBUG
+ VERBOSE_INFO EQU 1
+else
+ ifdef _AS_MSG_
+ VERBOSE_INFO EQU 1
+ else
+ VERBOSE_INFO EQU 0
+ endif
+endif
+
+ifndef __SMALL__
+ ifndef __COMPACT__
+ ifndef __MEDIUM__
+ ifndef __LARGE__
+ ifndef __HUGE__
+; __SMALL__ EQU 1
+ endif
+ endif
+ endif
+ endif
+endif
+
+ifdef __HUGE__
+; .MODEL Huge
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
+ Save_DS EQU 1
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Huge memory model
+ endif
+ endif
+else
+ ifdef __LARGE__
+; .MODEL Large
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Large memory model
+ endif
+ endif
+ else
+ ifdef __COMPACT__
+; .MODEL Compact
+ ifndef @CodeSize
+ @CodeSize EQU 0
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Compact memory model
+ endif
+ endif
+ else
+ ifdef __MEDIUM__
+; .MODEL Medium
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 0
+ endif
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Medium memory model
+ endif
+ endif
+ else
+; .MODEL Small
+ ifndef @CodeSize
+ @CodeSize EQU 0
+ endif
+ ifndef @DataSize
+ @DataSize EQU 0
+ endif
+ if VERBOSE_INFO
+ if1
+ %out Assembling for C, Small memory model
+ endif
+ endif
+ endif
+ endif
+ endif
+endif
+
+if @CodeSize
+ LCOD_OFS EQU 2
+else
+ LCOD_OFS EQU 0
+endif
+
+IF @DataSize
+ LDAT_OFS EQU 2
+else
+ LDAT_OFS EQU 0
+endif
+
+ifdef Save_DS
+; (di,si,ds)+(size, return address)
+ SAVE_REGS EQU 6+(4+LCOD_OFS)
+else
+; (di,si)+(size, return address)
+ SAVE_REGS EQU 4+(4+LCOD_OFS)
+endif
+
+;
+; Selection of the supported CPU instruction set and initialization
+; of CPU type related macros:
+;
+ifdef __586
+ Use_286_code EQU 1
+ Align_Size EQU 16 ; paragraph alignment on Pentium
+ Alig_PARA EQU 1 ; paragraph aligned code segment
+else
+ifdef __486
+ Use_286_code EQU 1
+ Align_Size EQU 4 ; dword alignment on 32 bit processors
+ Alig_PARA EQU 1 ; paragraph aligned code segment
+else
+ifdef __386
+ Use_286_code EQU 1
+ Align_Size EQU 4 ; dword alignment on 32 bit processors
+ Alig_PARA EQU 1 ; paragraph aligned code segment
+else
+ifdef __286
+ Use_286_code EQU 1
+ Align_Size EQU 2 ; word alignment on 16 bit processors
+ Alig_PARA EQU 0 ; word aligned code segment
+else
+ifdef __186
+ Use_186_code EQU 1
+ Align_Size EQU 2 ; word alignment on 16 bit processors
+ Alig_PARA EQU 0 ; word aligned code segment
+else
+ Align_Size EQU 2 ; word alignment on 16 bit processors
+ Alig_PARA EQU 0 ; word aligned code segment
+endif ;?__186
+endif ;?__286
+endif ;?__386
+endif ;?__486
+endif ;?__586
+
+ifdef Use_286_code
+ .286
+ Have_80x86 EQU 1
+else
+ifdef Use_186_code
+ .186
+ Have_80x86 EQU 1
+else
+ .8086
+ Have_80x86 EQU 0
+endif ;?Use_186_code
+endif ;?Use_286_code
+
+ifndef DYN_ALLOC
+ extrn _prev : word
+ extrn _window : byte
+ prev equ _prev ; offset part
+ window equ _window
+endif
+
+_DATA segment word public 'DATA'
+ extrn _nice_match : word
+ extrn _match_start : word
+ extrn _prev_length : word
+ extrn _good_match : word
+ extrn _strstart : word
+ extrn _max_chain_length : word
+ifdef DYN_ALLOC
+ extrn _prev : word
+ extrn _window : word
+ prev equ 0 ; offset forced to zero
+ window equ 0
+ window_seg equ _window[2]
+ window_off equ 0
+else
+ wseg dw seg _window
+ window_seg equ wseg
+ window_off equ offset _window
+endif
+_DATA ends
+
+DGROUP group _DATA
+
+if @CodeSize
+if Alig_PARA
+MATCH_TEXT SEGMENT PARA PUBLIC 'CODE'
+else
+MATCH_TEXT SEGMENT WORD PUBLIC 'CODE'
+endif
+ assume cs: MATCH_TEXT, ds: DGROUP
+else ;!@CodeSize
+if Alig_PARA
+_TEXT segment para public 'CODE'
+else
+_TEXT segment word public 'CODE'
+endif
+ assume cs: _TEXT, ds: DGROUP
+endif ;?@CodeSize
+
+ public _match_init
+ public _longest_match
+
+ifndef WSIZE
+ WSIZE equ 32768 ; keep in sync with zip.h !
+endif
+ MIN_MATCH equ 3
+ MAX_MATCH equ 258
+ MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
+ MAX_DIST equ (WSIZE-MIN_LOOKAHEAD)
+
+ifdef DYN_ALLOC
+ ifdef SS_NEQ_DS
+ prev_ptr dw seg _prev ; pointer to the prev array
+ endif
+else
+ prev_ptr dw seg _prev ; pointer to the prev array
+endif
+ifdef SS_NEQ_DS
+ match_start dw 0 ; copy of _match_start if SS != DS
+ nice_match dw 0 ; copy of _nice_match if SS != DS
+endif
+
+; initialize or check the variables used in match.asm.
+
+if @CodeSize
+_match_init proc far ; 'proc far' for large model
+else
+_match_init proc near ; 'proc near' for compact model
+endif
+ifdef SS_NEQ_DS
+ ma_start equ cs:match_start ; does not work on OS/2
+ nice equ cs:nice_match
+else
+ assume ss: DGROUP
+ ma_start equ ss:_match_start
+ nice equ ss:_nice_match
+ ifndef NO_SECURE_TESTS
+ mov ax,ds
+ mov bx,ss
+ cmp ax,bx ; SS == DS?
+ jne fatal_err
+ endif
+endif
+ifdef DYN_ALLOC
+ ifndef NO_SECURE_TESTS
+ cmp _prev[0],0 ; verify zero offset
+ jne fatal_err
+ cmp _window[0],0
+ jne fatal_err
+ endif
+ ifdef SS_NEQ_DS
+ mov ax,_prev[2] ; segment value
+ mov cs:prev_ptr,ax ; ugly write to code, crash on OS/2
+ prev_seg equ cs:prev_ptr
+ else
+ prev_seg equ ss:_prev[2] ; works on OS/2 if SS == DS
+ endif
+else
+ prev_seg equ cs:prev_ptr
+endif
+ ret
+ifndef NO_SECURE_TESTS
+if @CodeSize
+ extrn _exit : far ; 'far' for large model
+else
+ extrn _exit : near ; 'near' for compact model
+endif
+fatal_err: ; (quiet) emergency stop:
+ call _exit ; incompatible "global vars interface"
+endif
+
+_match_init endp
+
+; -----------------------------------------------------------------------
+; Set match_start to the longest match starting at the given string and
+; return its length. Matches shorter or equal to prev_length are discarded,
+; in which case the result is equal to prev_length and match_start is
+; garbage.
+; IN assertions: cur_match is the head of the hash chain for the current
+; string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+
+; int longest_match(cur_match)
+
+ align Align_Size
+
+if @CodeSize
+_longest_match proc far ; 'proc far' for large model
+else
+_longest_match proc near ; 'proc near' for compact model
+endif
+ push bp
+ mov bp,sp
+ push di
+ push si
+ push ds
+
+if @CodeSize
+ cur_match equ word ptr [bp+6] ; [bp+6] for large model
+else
+ cur_match equ word ptr [bp+4] ; [bp+4] for compact model
+endif
+
+; window equ es:window (es:0 for DYN_ALLOC)
+; prev equ ds:prev
+; match equ es:si
+; scan equ es:di
+; chain_length equ bp
+; best_len equ bx
+; limit equ dx
+
+ mov si,cur_match ; use bp before it is destroyed
+ifdef SS_NEQ_DS
+ mov ax,_nice_match
+ mov nice,ax ; ugly write to code, crash on OS/2
+endif
+ mov dx,_strstart
+ mov bp,_max_chain_length ; chain_length = max_chain_length
+ mov di,dx
+ sub dx,MAX_DIST ; limit = strstart-MAX_DIST
+ cld ; string ops increment si and di
+ jae limit_ok
+ sub dx,dx ; limit = NIL
+limit_ok:
+ add di,2+window_off ; di = offset(window + strstart + 2)
+ mov bx,_prev_length ; best_len = prev_length
+ mov es,window_seg
+ mov ax,es:[bx+di-3] ; ax = scan[best_len-1..best_len]
+ mov cx,es:[di-2] ; cx = scan[0..1]
+ cmp bx,_good_match ; do we have a good match already?
+ mov ds,prev_seg ; (does not destroy the flags)
+ assume ds: nothing
+ jb do_scan ; good match?
+if Have_80x86
+ shr bp,2 ; chain_length >>= 2
+else
+ shr bp,1 ; chain_length >>= 2
+ shr bp,1
+endif
+ jmp short do_scan
+
+ align Align_Size ; align destination of branch
+long_loop:
+; at this point, ds:di == scan+2, ds:si == cur_match
+ mov ax,[bx+di-3] ; ax = scan[best_len-1..best_len]
+ mov cx,[di-2] ; cx = scan[0..1]
+ mov ds,prev_seg ; reset ds to address the prev array
+short_loop:
+; at this point, di == scan+2, si = cur_match,
+; ax = scan[best_len-1..best_len] and cx = scan[0..1]
+if (WSIZE-32768)
+ and si,WSIZE-1 ; not needed if WSIZE=32768
+endif
+ shl si,1 ; cur_match as word index
+ dec bp ; --chain_length
+ mov si,prev[si] ; cur_match = prev[cur_match]
+ jz the_end
+ cmp si,dx ; cur_match <= limit ?
+ jbe the_end
+do_scan:
+ cmp ax,word ptr es:window[bx+si-1] ; check match at best_len-1
+ jne short_loop
+ cmp cx,word ptr es:window[si] ; check min_match_length match
+ jne short_loop
+
+ mov cx,es
+ add si,2+window_off ; si = match
+ mov ds,cx ; ds = es = window
+ mov cx,(MAX_MATCH-2)/2 ; scan for at most MAX_MATCH bytes
+ mov ax,di ; ax = scan+2
+ repe cmpsw ; loop until mismatch
+ je maxmatch ; match of length MAX_MATCH?
+mismatch:
+ mov cl,[di-2] ; mismatch on first or second byte?
+ xchg ax,di ; di = scan+2, ax = end of scan
+ sub cl,[si-2] ; cl = 0 if first bytes equal
+ sub ax,di ; ax = len
+ sub si,2+window_off ; si = cur_match + len
+ sub si,ax ; si = cur_match
+ sub cl,1 ; set carry if cl == 0 (can't use DEC)
+ adc ax,0 ; ax = carry ? len+1 : len
+ cmp ax,bx ; len > best_len ?
+ jle long_loop
+ mov ma_start,si ; match_start = cur_match
+ mov bx,ax ; bx = best_len = len
+ cmp ax,nice ; len >= nice_match ?
+ jl long_loop
+the_end:
+ pop ds
+ assume ds: DGROUP
+ifdef SS_NEQ_DS
+ mov ax,ma_start ; garbage if no match found
+ mov ds:_match_start,ax
+endif
+ pop si
+ pop di
+ pop bp
+ mov ax,bx ; result = ax = best_len
+ ret
+maxmatch: ; come here if maximum match
+ cmpsb ; increment si and di
+ jmp mismatch ; force match_length = MAX_LENGTH
+
+_longest_match endp
+
+if @CodeSize
+MATCH_TEXT ENDS
+else
+_TEXT ENDS
+endif
+;
+endif ;!USE_ZLIB
+;
+end
diff --git a/msdos/msdos.c b/msdos/msdos.c
new file mode 100644
index 0000000..4f71397
--- /dev/null
+++ b/msdos/msdos.c
@@ -0,0 +1,1126 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2005-Feb-10 or later
+ (the contents of which are also included in zip.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
+*/
+#include "zip.h"
+
+#ifndef UTIL /* little or no material in this file is used by UTIL */
+
+#include <dos.h>
+#include <time.h>
+
+
+#if defined(__GO32__) || defined(__TURBOC__)
+# include <dir.h> /* prototypes of find*() */
+ typedef struct ffblk ff_dir;
+# define FATTR (hidden_files ? FA_HIDDEN+FA_SYSTEM+FA_DIREC : FA_DIREC)
+# define FFIRST(n,d,a) findfirst(n,(struct ffblk *)d,a)
+# define FNEXT(d) findnext((struct ffblk *)d)
+# if (defined(__TURBOC__) || (defined(__DJGPP__) && (__DJGPP__ >=2)))
+# if (defined(__DJGPP__) && (__DJGPP__ == 2) && (__DJGPP_MINOR__ == 0))
+# include <libc/dosio.h>
+# endif
+# define GetFileMode(name) _chmod(name, 0)
+# define SetFileMode(name, attr) _chmod(name, 1, attr)
+# else /* DJGPP v1.x */
+# define GetFileMode(name) bdosptr(0x43, (name), 0)
+# endif
+#endif /* __GO32__ || __TURBOC__ */
+
+#if defined(MSC) || defined(__WATCOMC__)
+ typedef struct find_t ff_dir;
+# define FATTR (hidden_files ? _A_HIDDEN+_A_SYSTEM+_A_SUBDIR : _A_SUBDIR)
+# ifndef FA_LABEL
+# define FA_LABEL _A_VOLID
+# endif
+# define FFIRST(n,d,a) _dos_findfirst(n,a,(struct find_t *)d)
+# define FNEXT(d) _dos_findnext((struct find_t *)d)
+# define ff_name name
+# define ff_fdate wr_date
+# define ff_ftime wr_time
+# define ff_attrib attrib
+#endif /* MSC || __WATCOMC__ */
+
+#ifdef __EMX__
+# ifdef EMX_OBSOLETE /* emx 0.9b or earlier */
+# define size_t xxx_size_t
+# define wchar_t xxx_wchar_t
+# define tm xxx_tm
+# include <sys/emx.h>
+# undef size_t
+# undef wchar_t
+# undef tm
+# else /* !EMX_OBSOLETE */ /* emx 0.9c or newer */
+# include <emx/syscalls.h>
+# endif /* ?EMX_OBSOLETE */
+ typedef struct _find ff_dir;
+# define FATTR (hidden_files ? _A_HIDDEN+_A_SYSTEM+_A_SUBDIR : _A_SUBDIR)
+# define FA_LABEL _A_VOLID
+# define FFIRST(n,d,a) __findfirst(n,a,d)
+# define FNEXT(d) __findnext(d)
+# define ff_name name
+# define ff_fdate date
+# define ff_ftime time
+# define ff_attrib attr
+# define GetFileMode(name) __chmod(name, 0, 0)
+# define SetFileMode(name, attr) __chmod(name, 1, attr)
+#endif /* __EMX__ */
+
+#ifndef SetFileMode
+# define SetFileMode(name, attr) _dos_setfileattr(name, attr)
+#endif
+
+
+#define PAD 0
+#define PATH_END '/'
+
+/* Library functions not in (most) header files */
+int rmdir OF((const char *));
+int utime OF((char *, ztimbuf *));
+
+/* Local functions */
+#ifndef GetFileMode
+int GetFileMode OF((char *name));
+#endif /* !GetFileMode */
+
+local int initDirSearch OF((char *name, ff_dir *ff_context_p));
+local char *getVolumeLabel OF((int, ulg *, ulg *, time_t *));
+local int wild_recurse OF((char *, char *));
+local int procname_dos OF((char *n, int caseflag, unsigned attribs));
+local int is_running_on_windows OF((void));
+
+#define MSDOS_INVALID_ATTR 0xFF
+#define getDirEntryAttr(d) ((d)->ff_attrib)
+
+/* Module level variables */
+extern char *label;
+local ulg label_time = 0;
+local ulg label_mode = 0;
+local time_t label_utim = 0;
+
+/* Module level constants */
+local ZCONST char wild_match_all[] = "*.*";
+
+
+#ifndef GetFileMode
+int GetFileMode(char *name)
+{
+ unsigned int attr = 0;
+ return (_dos_getfileattr(name, &attr) ? -1 : attr);
+}
+#endif /* !GetFileMode */
+
+local int initDirSearch(name, ff_context_p)
+ char *name; /* name of directory to scan */
+ ff_dir *ff_context_p; /* pointer to FFIRST/FNEXT context structure */
+{
+ int r; /* FFIRST return value */
+ char *p, *q; /* temporary copy of name, and aux pointer */
+
+ if ((p = malloc(strlen(name) + (2 + sizeof(wild_match_all)))) == NULL)
+ return ZE_MEM;
+
+ strcpy(p, name);
+ q = p + strlen(p);
+ if (q[-1] == ':')
+ *q++ = '.';
+ if ((q - p) > 0 && *(q - 1) != '/')
+ *q++ = '/';
+ strcpy(q, wild_match_all);
+ r = FFIRST(p, ff_context_p, FATTR);
+ free((zvoid *)p);
+
+ return (r ? ZE_MISS : ZE_OK);
+}
+
+local char *getVolumeLabel(drive, vtime, vmode, vutim)
+ int drive; /* drive name: 'A' .. 'Z' or '\0' for current drive */
+ ulg *vtime; /* volume label creation time (DOS format) */
+ ulg *vmode; /* volume label file mode */
+ time_t *vutim;/* volume label creation time (UNIX format) */
+
+/* If a volume label exists for the given drive, return its name and
+ set its time and mode. The returned name must be static data. */
+{
+ static char vol[14];
+ ff_dir d;
+ char *p;
+
+ if (drive) {
+ vol[0] = (char)drive;
+ strcpy(vol+1, ":/");
+ } else {
+ strcpy(vol, "/");
+ }
+ strcat(vol, wild_match_all);
+ if (FFIRST(vol, &d, FA_LABEL) == 0) {
+ strncpy(vol, d.ff_name, sizeof(vol)-1);
+ vol[sizeof(vol)-1] = '\0'; /* just in case */
+ if ((p = strchr(vol, '.')) != NULL) /* remove dot, though PKZIP doesn't */
+ strcpy(p, p + 1);
+ *vtime = ((ulg)d.ff_fdate << 16) | ((ulg)d.ff_ftime & 0xffff);
+ *vmode = (ulg)d.ff_attrib;
+ *vutim = dos2unixtime(*vtime);
+ return vol;
+ }
+ return NULL;
+}
+
+
+#ifdef MSDOS16
+#define ONENAMELEN 12 /* no 16-bit compilers supports LFN */
+#else
+#define ONENAMELEN 255
+#endif
+
+/* whole is a pathname with wildcards, wildtail points somewhere in the */
+/* middle of it. All wildcards to be expanded must come AFTER wildtail. */
+
+local int wild_recurse(whole, wildtail)
+char *whole;
+char *wildtail;
+{
+ ff_dir dir;
+ char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2;
+ ush newlen, amatch = 0;
+ int e = ZE_MISS;
+
+ if (!isshexp(wildtail)) {
+ struct stat s; /* dummy buffer for stat() */
+
+ if (!LSSTAT(whole, &s)) /* file exists ? */
+ return procname(whole, 0);
+ else
+ return ZE_MISS; /* woops, no wildcards! */
+ }
+
+ /* back up thru path components till existing dir found */
+ do {
+ name = wildtail + strlen(wildtail) - 1;
+ for (;;)
+ if (name-- <= wildtail || *name == PATH_END) {
+ subwild = name + 1;
+ plug2 = *subwild;
+ *subwild = 0;
+ break;
+ }
+ if (glue)
+ *glue = plug;
+ glue = subwild;
+ plug = plug2;
+ e = initDirSearch(whole, &dir);
+ } while (e == ZE_MISS && subwild > wildtail);
+ wildtail = subwild; /* skip past non-wild components */
+ if (e != ZE_OK) {
+ if (glue)
+ *glue = plug;
+ goto ohforgetit;
+ }
+ subwild = strchr(wildtail + 1, PATH_END);
+ /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */
+ if (subwild != NULL) {
+ *(subwild++) = 0; /* wildtail = one component pattern */
+ newlen = strlen(whole) + strlen(subwild) + (ONENAMELEN + 2);
+ } else
+ newlen = strlen(whole) + (ONENAMELEN + 1);
+ if ((newwhole = malloc(newlen)) == NULL) {
+ if (glue)
+ *glue = plug;
+ e = ZE_MEM;
+ goto ohforgetit;
+ }
+ strcpy(newwhole, whole);
+ newlen = strlen(newwhole);
+ if (glue)
+ *glue = plug; /* repair damage to whole */
+ if (!isshexp(wildtail)) {
+ e = ZE_MISS; /* non-wild name not found */
+ goto ohforgetit;
+ }
+
+ do {
+ if (strcmp(dir.ff_name, ".") && strcmp(dir.ff_name, "..")
+ && MATCH(wildtail, dir.ff_name, 0)) {
+ strcpy(newwhole + newlen, dir.ff_name);
+ if (subwild) {
+ name = newwhole + strlen(newwhole);
+ *(name++) = PATH_END;
+ strcpy(name, subwild);
+ e = wild_recurse(newwhole, name);
+ } else
+ e = procname_dos(newwhole, 0, getDirEntryAttr(&dir));
+ newwhole[newlen] = 0;
+ if (e == ZE_OK)
+ amatch = 1;
+ else if (e != ZE_MISS)
+ break;
+ }
+ } while (FNEXT(&dir) == 0);
+
+ ohforgetit:
+ if (subwild)
+ *--subwild = PATH_END;
+ if (newwhole)
+ free(newwhole);
+ if (e == ZE_MISS && amatch)
+ e = ZE_OK;
+ return e;
+}
+
+int wild(w)
+char *w; /* path/pattern to match */
+/* If not in exclude mode, expand the pattern based on the contents of the
+ file system. Return an error code in the ZE_ class. */
+{
+ char *p; /* path */
+ char *q; /* diskless path */
+ int e; /* result */
+
+ if (volume_label == 1) {
+ volume_label = 2;
+ label = getVolumeLabel((w != NULL && w[1] == ':') ? to_up(w[0]) : '\0',
+ &label_time, &label_mode, &label_utim);
+ if (label != NULL)
+ (void)newname(label, 0, 0);
+ if (w == NULL || (w[1] == ':' && w[2] == '\0')) return ZE_OK;
+ /* "zip -$ foo a:" can be used to force drive name */
+ }
+ /* special handling of stdin request */
+ if (strcmp(w, "-") == 0) /* if compressing stdin */
+ return newname(w, 0, 0);
+
+ /* Allocate and copy pattern, leaving room to add "." if needed */
+ if ((p = malloc(strlen(w) + 2)) == NULL)
+ return ZE_MEM;
+ strcpy(p, w);
+
+ /* Normalize path delimiter as '/' */
+ for (q = p; *q; q++) /* use / consistently */
+ if (*q == '\\')
+ *q = '/';
+
+ /* Separate the disk part of the path */
+ q = strchr(p, ':');
+ if (q != NULL) {
+ if (strchr(++q, ':')) /* sanity check for safety of wild_recurse */
+ return ZE_MISS;
+ } else
+ q = p;
+
+ /* Normalize bare disk names */
+ if (q > p && !*q)
+ strcpy(q, ".");
+
+ /* Here we go */
+ e = wild_recurse(p, q);
+ free((zvoid *)p);
+ return e;
+}
+
+local int procname_dos(n, caseflag, attribs)
+char *n; /* name to process */
+int caseflag; /* true to force case-sensitive match */
+unsigned attribs; /* file attributes, if available */
+/* Process a name or sh expression to operate on (or exclude). Return
+ an error code in the ZE_ class. */
+{
+ char *a; /* path and name for recursion */
+ ff_dir *d; /* control structure for FFIRST/FNEXT */
+ char *e; /* pointer to name from readd() */
+ int m; /* matched flag */
+ int ff_status; /* return value of FFIRST/FNEXT */
+ char *p; /* path for recursion */
+ struct stat s; /* result of stat() */
+ struct zlist far *z; /* steps through zfiles list */
+
+ if (n == NULL) /* volume_label request in freshen|delete mode ?? */
+ return ZE_OK;
+
+ if (strcmp(n, "-") == 0) /* if compressing stdin */
+ return newname(n, 0, caseflag);
+ else if (*n == '\0') return ZE_MISS;
+ else if (attribs != MSDOS_INVALID_ATTR)
+ {
+ /* Avoid calling stat() for performance reasons when it is already known
+ (from a previous directory scan) that the passed name corresponds to
+ a "real existing" file. The only information needed further down in
+ this function is the distinction between directory entries and other
+ (typically normal file) entries. This distinction can be derived from
+ the file's attributes that the directory lookup has already provided
+ "for free".
+ */
+ s.st_mode = ((attribs & MSDOS_DIR_ATTR) ? S_IFDIR : S_IFREG);
+ }
+ else if (LSSTAT(n, &s)
+#ifdef __TURBOC__
+ /* For this compiler, stat() succeeds on wild card names! */
+ || isshexp(n)
+#endif
+ )
+ {
+ /* Not a file or directory--search for shell expression in zip file */
+ if (caseflag) {
+ p = malloc(strlen(n) + 1);
+ if (p != NULL)
+ strcpy(p, n);
+ } else
+ p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */
+ m = 1;
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (MATCH(p, z->iname, caseflag))
+ {
+ z->mark = pcount ? filter(z->zname, caseflag) : 1;
+ if (z->mark) z->dosflag = 1; /* force DOS attribs for incl. names */
+ if (verbose)
+ fprintf(mesg, "zip diagnostic: %scluding %s\n",
+ z->mark ? "in" : "ex", z->name);
+ m = 0;
+ }
+ }
+ free((zvoid *)p);
+ return m ? ZE_MISS : ZE_OK;
+ }
+
+ /* Live name--use if file, recurse if directory */
+ for (p = n; *p; p++) /* use / consistently */
+ if (*p == '\\')
+ *p = '/';
+ if ((s.st_mode & S_IFDIR) == 0)
+ {
+ /* add or remove name of file */
+ if ((m = newname(n, 0, caseflag)) != ZE_OK)
+ return m;
+ } else {
+ /* Add trailing / to the directory name */
+ if ((p = malloc(strlen(n)+2)) == NULL)
+ return ZE_MEM;
+ if (strcmp(n, ".") == 0 || strcmp(n, "/.") == 0) {
+ *p = '\0'; /* avoid "./" prefix and do not create zip entry */
+ } else {
+ strcpy(p, n);
+ a = p + strlen(p);
+ if (a[-1] != '/')
+ strcpy(a, "/");
+ if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) {
+ free((zvoid *)p);
+ return m;
+ }
+ }
+ /* recurse into directory */
+ if (recurse)
+ {
+ if ((d = malloc(sizeof(ff_dir))) == NULL ||
+ (m = initDirSearch(n, d)) == ZE_MEM)
+ {
+ if (d != NULL)
+ free((zvoid *)d);
+ free((zvoid *)p);
+ return ZE_MEM;
+ }
+ for (e = d->ff_name, ff_status = m;
+ ff_status == 0;
+ ff_status = FNEXT(d))
+ {
+ if (strcmp(e, ".") && strcmp(e, ".."))
+ {
+ if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
+ {
+ free((zvoid *)d);
+ free((zvoid *)p);
+ return ZE_MEM;
+ }
+ strcat(strcpy(a, p), e);
+ if ((m = procname_dos(a, caseflag, getDirEntryAttr(d)))
+ != ZE_OK) /* recurse on name */
+ {
+ if (m == ZE_MISS)
+ zipwarn("name not matched: ", a);
+ else
+ ziperr(m, a);
+ }
+ free((zvoid *)a);
+ }
+ }
+ free((zvoid *)d);
+ }
+ free((zvoid *)p);
+ } /* (s.st_mode & S_IFDIR) == 0) */
+ return ZE_OK;
+}
+
+int procname(n, caseflag)
+char *n; /* name to process */
+int caseflag; /* true to force case-sensitive match */
+{
+ return procname_dos(n, caseflag, MSDOS_INVALID_ATTR);
+}
+
+char *ex2in(x, isdir, pdosflag)
+char *x; /* external file name */
+int isdir; /* input: x is a directory */
+int *pdosflag; /* output: force MSDOS file attributes? */
+/* Convert the external file name to a zip file name, returning the malloc'ed
+ string or NULL if not enough memory. */
+{
+ char *n; /* internal file name (malloc'ed) */
+ char *t; /* shortened name */
+ int dosflag;
+
+ dosflag = 1;
+
+ /* Find starting point in name before doing malloc */
+ /* Strip drive specification */
+ t = *x && *(x + 1) == ':' ? x + 2 : x;
+ /* Strip "//host/share/" part of a UNC name */
+ if ((!strncmp(x,"//",2) || !strncmp(x,"\\\\",2)) &&
+ (x[2] != '\0' && x[2] != '/' && x[2] != '\\')) {
+ n = x + 2;
+ while (*n != '\0' && *n != '/' && *n != '\\')
+ n++; /* strip host name */
+ if (*n != '\0') {
+ n++;
+ while (*n != '\0' && *n != '/' && *n != '\\')
+ n++; /* strip `share' name */
+ }
+ if (*n != '\0')
+ t = n + 1;
+ }
+ /* Strip leading "/" to convert an absolute path into a relative path */
+ while (*t == '/' || *t == '\\')
+ t++;
+ /* Skip leading "./" as well */
+ while (*t == '.' && (t[1] == '/' || t[1] == '\\'))
+ t += 2;
+
+ /* Make changes, if any, to the copied name (leave original intact) */
+ for (n = t; *n; n++)
+ if (*n == '\\')
+ *n = '/';
+
+ if (!pathput)
+ t = last(t, PATH_END);
+
+ /* Malloc space for internal name and copy it */
+ if ((n = malloc(strlen(t) + 1)) == NULL)
+ return NULL;
+ strcpy(n, t);
+
+ if (isdir == 42) return n; /* avoid warning on unused variable */
+
+ if (dosify)
+ msname(n);
+ else
+#if defined(__DJGPP__) && __DJGPP__ >= 2
+ if (_USE_LFN == 0)
+#endif
+ strlwr(n);
+ if (pdosflag)
+ *pdosflag = dosflag;
+ return n;
+}
+
+char *in2ex(n)
+char *n; /* internal file name */
+/* Convert the zip file name to an external file name, returning the malloc'ed
+ string or NULL if not enough memory. */
+{
+ char *x; /* external file name */
+
+ if ((x = malloc(strlen(n) + 1 + PAD)) == NULL)
+ return NULL;
+ strcpy(x, n);
+
+ return x;
+}
+
+void stamp(f, d)
+char *f; /* name of file to change */
+ulg d; /* dos-style time to change it to */
+/* Set last updated and accessed time of file f to the DOS time d. */
+{
+#if defined(__TURBOC__) || defined(__GO32__)
+ int h; /* file handle */
+
+ if ((h = open(f, 0)) != -1)
+ {
+ setftime(h, (struct ftime *)(void *)&d);
+ close(h);
+ }
+#else /* !__TURBOC__ && !__GO32__ */
+ ztimbuf u; /* argument for utime() */
+
+ /* Convert DOS time to time_t format in u.actime and u.modtime */
+ u.actime = u.modtime = dos2unixtime(d);
+
+ /* Set updated and accessed times of f */
+ utime(f, &u);
+#endif /* ?(__TURBOC__ || __GO32__) */
+}
+
+ulg filetime(f, a, n, t)
+char *f; /* name of file to get info on */
+ulg *a; /* return value: file attributes */
+long *n; /* return value: file size */
+iztimes *t; /* return value: access, modific. and creation times */
+/* If file *f does not exist, return 0. Else, return the file's last
+ modified date and time as an MSDOS date and time. The date and
+ time is returned in a long with the date most significant to allow
+ unsigned integer comparison of absolute times. Also, if a is not
+ a NULL pointer, store the file attributes there, with the high two
+ bytes being the Unix attributes, and the low byte being a mapping
+ of that to DOS attributes. If n is not NULL, store the file size
+ there. If t is not NULL, the file's access, modification and creation
+ times are stored there as UNIX time_t values.
+ If f is "-", use standard input as the file. If f is a device, return
+ a file size of -1 */
+{
+ struct stat s; /* results of stat() */
+ /* convert FNMAX to malloc - 11/8/04 EG */
+ char *name;
+ int len = strlen(f);
+ int isstdin = !strcmp(f, "-");
+
+ if (f == label) {
+ if (a != NULL)
+ *a = label_mode;
+ if (n != NULL)
+ *n = -2L; /* convention for a label name */
+ if (t != NULL)
+ t->atime = t->mtime = t->ctime = label_utim;
+ return label_time;
+ }
+ if ((name = malloc(len + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "filetime");
+ }
+ strcpy(name, f);
+ if (name[len - 1] == '/')
+ name[len - 1] = '\0';
+ /* not all systems allow stat'ing a file with / appended */
+
+ if (isstdin) {
+ if (fstat(fileno(stdin), &s) != 0) {
+ free(name);
+ error("fstat(stdin)");
+ }
+ time((time_t *)&s.st_mtime); /* some fstat()s return time zero */
+ } else if (LSSTAT(name, &s) != 0) {
+ /* Accept about any file kind including directories
+ * (stored with trailing / with -r option)
+ */
+ free(name);
+ return 0;
+ }
+
+ if (a != NULL) {
+ *a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileMode(name));
+#if (S_IFREG != 0x8000)
+ /* kludge to work around non-standard S_IFREG flag used in DJGPP V2.x */
+ if ((s.st_mode & S_IFMT) == S_IFREG) *a |= 0x80000000L;
+#endif
+ }
+ free(name);
+ if (n != NULL)
+ *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L;
+ if (t != NULL) {
+ t->atime = s.st_atime;
+ t->mtime = s.st_mtime;
+ t->ctime = s.st_ctime;
+ }
+
+ return unix2dostime((time_t *)&s.st_mtime);
+}
+
+int deletedir(d)
+char *d; /* directory to delete */
+/* Delete the directory *d if it is empty, do nothing otherwise.
+ Return the result of rmdir(), delete(), or system().
+ */
+{
+ return rmdir(d);
+}
+
+int set_extra_field(z, z_utim)
+ struct zlist far *z;
+ iztimes *z_utim;
+ /* create extra field and change z->att if desired */
+{
+#ifdef USE_EF_UT_TIME
+#ifdef IZ_CHECK_TZ
+ if (!zp_tz_is_valid) return ZE_OK; /* skip silently if no valid TZ info */
+#endif
+
+ if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL)
+ return ZE_MEM;
+
+ z->extra[0] = 'U';
+ z->extra[1] = 'T';
+ z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */
+ z->extra[3] = 0;
+ z->extra[4] = EB_UT_FL_MTIME;
+ z->extra[5] = (char)(z_utim->mtime);
+ z->extra[6] = (char)(z_utim->mtime >> 8);
+ z->extra[7] = (char)(z_utim->mtime >> 16);
+ z->extra[8] = (char)(z_utim->mtime >> 24);
+
+ z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1));
+ z->cextra = z->extra;
+
+ return ZE_OK;
+#else /* !USE_EF_UT_TIME */
+ return (int)(z-z);
+#endif /* ?USE_EF_UT_TIME */
+}
+
+
+#ifdef MY_ZCALLOC /* Special zcalloc function for MEMORY16 (MSDOS/OS2) */
+
+#if defined(__TURBOC__) && !defined(OS2)
+/* Small and medium model are for now limited to near allocation with
+ * reduced MAX_WBITS and MAX_MEM_LEVEL
+ */
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ zvoid far *org_ptr;
+ zvoid far *new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+zvoid far *zcalloc (unsigned items, unsigned size)
+{
+ zvoid far *buf;
+ ulg bsize = (ulg)items*size;
+
+ if (bsize < (65536L-16L)) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-NULL) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+zvoid zcfree (zvoid far *ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = next_ptr - 1; n >= 0; n--) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ziperr(ZE_MEM, "zcfree: ptr not found");
+}
+#endif /* __TURBOC__ */
+
+#if defined(MSC) || defined(__WATCOMC__)
+#if (!defined(_MSC_VER) || (_MSC_VER < 700))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+zvoid far *zcalloc (unsigned items, unsigned size)
+{
+ return (zvoid far *)_halloc((long)items, size);
+}
+
+zvoid zcfree (zvoid far *ptr)
+{
+ _hfree((void huge *)ptr);
+}
+#endif /* MSC || __WATCOMC__ */
+
+#endif /* MY_ZCALLOC */
+
+#if (defined(__WATCOMC__) && defined(ASMV) && !defined(__386__))
+/* This is a hack to connect "call _exit" in match.asm to exit() */
+#pragma aux xit "_exit" parm caller []
+void xit(void)
+{
+ exit(20);
+}
+#endif
+
+local int is_running_on_windows(void)
+{
+ char * var = getenv("OS");
+
+ /* if the OS env.var says 'Windows_NT' then */
+ /* we're likely running on a variant of WinNT */
+
+ if ((NULL != var) && (0 == strcmp("Windows_NT", var)))
+ {
+ return 1;
+ }
+
+ /* if the windir env.var is non-null then */
+ /* we're likely running on a variant of Win9x */
+ /* DOS mode of Win9x doesn't define windir, only winbootdir */
+ /* NT's command.com can't see lowercase env. vars */
+
+ var = getenv("windir");
+ if ((NULL != var) && (0 != var[0]))
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+void check_for_windows(char *app)
+{
+ /* Print a warning for users running under Windows */
+ /* to reduce bug reports due to running DOS version */
+ /* under Windows, when Windows version usually works correctly */
+
+ /* This is only called from the DOS version */
+
+ if (is_running_on_windows())
+ {
+ printf("\nzip warning: You are running MSDOS %s on Windows.\n"
+ "Try the Windows version before reporting any problems.\n",
+ app);
+ }
+}
+
+#endif /* !UTIL */
+
+
+#ifndef WINDLL
+/******************************/
+/* Function version_local() */
+/******************************/
+
+static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s.\n\n";
+ /* At module level to keep Turbo C++ 1.0 happy !! */
+
+void version_local()
+{
+#if defined(__DJGPP__) || defined(__WATCOMC__) || \
+ (defined(_MSC_VER) && (_MSC_VER != 800))
+ char buf[80];
+#endif
+
+/* Define the compiler name and version strings */
+#if defined(__GNUC__)
+# if defined(__DJGPP__)
+ sprintf(buf, "djgpp v%d.%02d / gcc ", __DJGPP__, __DJGPP_MINOR__);
+# define COMPILER_NAME1 buf
+# elif defined(__GO32__) /* __GO32__ is defined as "1" only (sigh) */
+# define COMPILER_NAME1 "djgpp v1.x / gcc "
+# elif defined(__EMX__) /* ...so is __EMX__ (double sigh) */
+# define COMPILER_NAME1 "emx+gcc "
+# else
+# define COMPILER_NAME1 "gcc "
+# endif
+# define COMPILER_NAME2 __VERSION__
+#elif defined(__WATCOMC__)
+# if (__WATCOMC__ % 10 > 0)
+/* We do this silly test because __WATCOMC__ gives two digits for the */
+/* minor version, but Watcom packaging prefers to show only one digit. */
+ sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100,
+ __WATCOMC__ % 100);
+# else
+ sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100,
+ (__WATCOMC__ % 100) / 10);
+# endif
+# define COMPILER_NAME1 buf
+# define COMPILER_NAME2 ""
+#elif defined(__TURBOC__)
+# ifdef __BORLANDC__
+# define COMPILER_NAME1 "Borland C++"
+# if (__BORLANDC__ < 0x0200)
+# define COMPILER_NAME2 " 1.0"
+# elif (__BORLANDC__ == 0x0200) /* James: __TURBOC__ = 0x0297 */
+# define COMPILER_NAME2 " 2.0"
+# elif (__BORLANDC__ == 0x0400)
+# define COMPILER_NAME2 " 3.0"
+# elif (__BORLANDC__ == 0x0410) /* __BCPLUSPLUS__ = 0x0310 */
+# define COMPILER_NAME2 " 3.1"
+# elif (__BORLANDC__ == 0x0452) /* __BCPLUSPLUS__ = 0x0320 */
+# define COMPILER_NAME2 " 4.0 or 4.02"
+# elif (__BORLANDC__ == 0x0460) /* __BCPLUSPLUS__ = 0x0340 */
+# define COMPILER_NAME2 " 4.5"
+# elif (__BORLANDC__ == 0x0500) /* __TURBOC__ = 0x0500 */
+# define COMPILER_NAME2 " 5.0"
+# else
+# define COMPILER_NAME2 " later than 5.0"
+# endif
+# else
+# define COMPILER_NAME1 "Turbo C"
+# if (__TURBOC__ > 0x0401)
+# define COMPILER_NAME2 "++ later than 3.0"
+# elif (__TURBOC__ == 0x0401) /* Kevin: 3.0 -> 0x0401 */
+# define COMPILER_NAME2 "++ 3.0"
+# elif (__TURBOC__ == 0x0296) /* [662] checked by SPC */
+# define COMPILER_NAME2 "++ 1.01"
+# elif (__TURBOC__ == 0x0295) /* [661] vfy'd by Kevin */
+# define COMPILER_NAME2 "++ 1.0"
+# elif (__TURBOC__ == 0x0201) /* Brian: 2.01 -> 0x0201 */
+# define COMPILER_NAME2 " 2.01"
+# elif ((__TURBOC__ >= 0x018d) && (__TURBOC__ <= 0x0200)) /* James: 0x0200 */
+# define COMPILER_NAME2 " 2.0"
+# elif (__TURBOC__ > 0x0100)
+# define COMPILER_NAME2 " 1.5" /* James: 0x0105? */
+# else
+# define COMPILER_NAME2 " 1.0" /* James: 0x0100 */
+# endif
+# endif
+#elif defined(MSC)
+# if defined(_QC) && !defined(_MSC_VER)
+# define COMPILER_NAME1 "Microsoft Quick C"
+# define COMPILER_NAME2 "" /* _QC is defined as 1 */
+# else
+# define COMPILER_NAME1 "Microsoft C "
+# ifdef _MSC_VER
+# if (_MSC_VER == 800)
+# define COMPILER_NAME2 "8.0/8.0c (Visual C++ 1.0/1.5)"
+# else
+# define COMPILER_NAME2 \
+ (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf)
+# endif
+# else
+# define COMPILER_NAME2 "5.1 or earlier"
+# endif
+# endif
+#else
+# define COMPILER_NAME1 "unknown compiler"
+# define COMPILER_NAME2 ""
+#endif
+
+/* Define the OS name and memory environment strings */
+#if defined(__WATCOMC__) || defined(__TURBOC__) || defined(MSC) || \
+ defined(__GNUC__)
+# define OS_NAME1 "\nMS-DOS"
+#else
+# define OS_NAME1 "MS-DOS"
+#endif
+
+#if (defined(__GNUC__) || (defined(__WATCOMC__) && defined(__386__)))
+# define OS_NAME2 " (32-bit)"
+#elif defined(M_I86HM) || defined(__HUGE__)
+# define OS_NAME2 " (16-bit, huge)"
+#elif defined(M_I86LM) || defined(__LARGE__)
+# define OS_NAME2 " (16-bit, large)"
+#elif defined(M_I86MM) || defined(__MEDIUM__)
+# define OS_NAME2 " (16-bit, medium)"
+#elif defined(M_I86CM) || defined(__COMPACT__)
+# define OS_NAME2 " (16-bit, compact)"
+#elif defined(M_I86SM) || defined(__SMALL__)
+# define OS_NAME2 " (16-bit, small)"
+#elif defined(M_I86TM) || defined(__TINY__)
+# define OS_NAME2 " (16-bit, tiny)"
+#else
+# define OS_NAME2 " (16-bit)"
+#endif
+
+/* Define the compile date string */
+#ifdef __DATE__
+# define COMPILE_DATE " on " __DATE__
+#else
+# define COMPILE_DATE ""
+#endif
+
+ printf(CompiledWith, COMPILER_NAME1, COMPILER_NAME2,
+ OS_NAME1, OS_NAME2, COMPILE_DATE);
+
+} /* end function version_local() */
+#endif /* !WINDLL */
+
+
+#if 0 /* inserted here for future use (clearing of archive bits) */
+#if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
+
+#include <errno.h>
+int volatile _doserrno;
+
+unsigned _dos_setfileattr(char *name, unsigned attr)
+{
+#if 0 /* stripping of trailing '/' is not needed for zip-internal use */
+ unsigned namlen = strlen(name);
+ char *i_name = alloca(namlen + 1);
+
+ strcpy(i_name, name);
+ if (namlen > 1 && i_name[namlen-1] == '/' && i_name[namlen-2] != ':')
+ i_name[namlen-1] = '\0';
+ asm("movl %0, %%edx": : "g" (i_name));
+#else
+ asm("movl %0, %%edx": : "g" (name));
+#endif
+ asm("movl %0, %%ecx": : "g" (attr));
+ asm("movl $0x4301, %eax");
+ asm("int $0x21": : : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi");
+ _doserrno = 0;
+ asm("jnc 1f");
+ asm("movl %%eax, %0": "=m" (_doserrno));
+ switch (_doserrno) {
+ case 2:
+ case 3:
+ errno = ENOENT;
+ break;
+ case 5:
+ errno = EACCES;
+ break;
+ }
+ asm("1:");
+ return (unsigned)_doserrno;
+}
+
+#endif /* DJGPP v1.x */
+#endif /* never (not yet used) */
+
+
+#if (defined(__DJGPP__) && (__DJGPP__ >= 2))
+
+/* Disable determination of "x" bit in st_mode field for [f]stat() calls. */
+int _is_executable (const char *path, int fhandle, const char *ext)
+{
+ return 0;
+}
+
+/* Prevent globbing of filenames. This gives the same functionality as
+ * "stubedit <program> globbing=no" did with DJGPP v1.
+ */
+#ifndef USE_DJGPP_GLOB
+char **__crt0_glob_function(char *_arg)
+{
+ return NULL;
+}
+#endif
+
+/* Reduce the size of the executable and remove the functionality to read
+ * the program's environment from whatever $DJGPP points to.
+ */
+#if !defined(USE_DJGPP_ENV) || defined(UTIL)
+void __crt0_load_environment_file(char *_app_name)
+{
+}
+#endif
+
+#endif /* __DJGPP__ >= 2 */
+
+
+#if defined(_MSC_VER) && _MSC_VER == 700
+
+/*
+ * ARGH. MSC 7.0 libraries think times are based on 1899 Dec 31 00:00, not
+ * 1970 Jan 1 00:00. So we have to diddle time_t's appropriately: add
+ * 70 years' worth of seconds for localtime() wrapper function;
+ * (70*365 regular days + 17 leap days + 1 1899 day) * 86400 ==
+ * (25550 + 17 + 1) * 86400 == 2209075200 seconds.
+ * Let time() and stat() return seconds since 1970 by using our own
+ * _dtoxtime() which is the routine that is called by these two functions.
+ */
+
+
+#ifdef UTIL
+# include <time.h>
+#endif
+
+#ifndef UTIL
+#undef localtime
+struct tm *localtime(const time_t *);
+
+struct tm *msc7_localtime(const time_t *clock)
+{
+ time_t t = *clock;
+
+ t += 2209075200L;
+ return localtime(&t);
+}
+#endif /* !UTIL */
+
+
+void __tzset(void);
+int _isindst(struct tm *);
+
+extern int _days[];
+
+/* 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)
+
+time_t _dtoxtime(year, month, mday, hour, min, sec)
+int year, month, mday, year, hour, min, sec;
+{
+ struct tm tm;
+ time_t t;
+ int days;
+
+ days = _days[month - 1] + mday;
+ year += 1980;
+ if (leap(year) && month > 2)
+ ++days;
+ tm.tm_yday = days;
+ tm.tm_mon = month - 1;
+ tm.tm_year = year - 1900;
+ tm.tm_hour = hour;
+ __tzset();
+ days += 365 * (year - 1970) + nleap (year);
+ t = 86400L * days + 3600L * hour + 60 * min + sec + _timezone;
+ if (_daylight && _isindst(&tm))
+ t -= 3600;
+ return t;
+}
+
+#endif /* _MSC_VER && _MSC_VER == 700 */
+
+
+#ifdef __WATCOMC__
+
+/* This papers over a bug in Watcom 10.6's standard library... sigh */
+/* Apparently it applies to both the DOS and Win32 stat()s. */
+
+int stat_bandaid(const char *path, struct stat *buf)
+{
+ char newname[4];
+ if (!stat(path, buf))
+ return 0;
+ else if (!strcmp(path, ".") || (path[0] && !strcmp(path + 1, ":."))) {
+ strcpy(newname, path);
+ newname[strlen(path) - 1] = '\\'; /* stat(".") fails for root! */
+ return stat(newname, buf);
+ } else
+ return -1;
+}
+
+#endif
diff --git a/msdos/osdep.h b/msdos/osdep.h
new file mode 100644
index 0000000..0e0f23f
--- /dev/null
+++ b/msdos/osdep.h
@@ -0,0 +1,218 @@
+/*
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2007-Mar-4 or later
+ (the contents of which are also included in zip.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
+*/
+/* The symbol DOS is used throughout the Zip source to identify code portions
+ * specific to the MSDOS port.
+ * Just to make sure, we check that it is set.
+ * (Currently, this should should not be neccessary, since currently it has
+ * to be set on the compiler command line to get this file read in.)
+ */
+#ifndef DOS
+# define DOS
+#endif
+
+/* The symbol MSDOS is consistently used in the generic source files
+ * to identify code to support for MSDOS (and MSDOS related) stuff.
+ * e.g: FAT or (FAT like) file systems,
+ * '\\' as directory separator in paths,
+ * "\r\n" as record (line) terminator in text files, ...
+ *
+ * IMPORTANT Note:
+ * This symbol is not unique for the MSDOS port !!!!!!
+ * It is also defined by ports to some other OS which are (to some extend)
+ * considered DOS compatible.
+ * Examples are: OS/2 (OS2), Windows NT and Windows 95 (WIN32).
+ *
+ */
+#ifndef MSDOS
+# define MSDOS
+#endif
+
+/* Power C is similar to Turbo C */
+#ifdef __POWERC
+# define __TURBOC__
+#endif /* __POWERC */
+
+/* Automatic setting of the common Microsoft C idenfifier MSC.
+ * NOTE: Watcom also defines M_I*86 !
+ */
+#if defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__))
+# ifndef MSC
+# define MSC /* This should work for older MSC, too! */
+# endif
+#endif
+
+#if !defined(__GO32__) && !defined(__EMX__)
+# define NO_UNISTD_H
+#endif
+
+#if defined(__WATCOMC__) && defined(__386__)
+# define WATCOMC_386
+#endif
+
+#ifdef WINDLL
+# define MSWIN
+# define MEMORY16
+#endif
+
+
+#if !defined(__EMX__) && !defined(__GO32__) && !defined(WATCOMC_386)
+#if !defined(WINDLL)
+# define MSDOS16 /* 16 bit MSDOS only */
+# define MEMORY16
+#endif
+#endif
+
+#if !defined(NO_ASM) && !defined(ASMV)
+# define ASMV
+#endif
+
+/* enable creation of UTC time fields unless explicitely suppressed */
+#if !defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)
+# define USE_EF_UT_TIME
+#endif
+
+/* check that TZ environment variable is defined before using UTC times */
+#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ))
+# define IZ_CHECK_TZ
+#endif
+
+#ifdef MEMORY16
+# ifndef NO_ASM
+# define ASM_CRC 1
+# endif /* ?NO_ASM */
+# ifdef __TURBOC__
+# include <alloc.h>
+# if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
+# if defined(DYNAMIC_CRC_TABLE) && defined(DYNALLOC_CRCTAB)
+ error: No dynamic CRC table allocation with Borland C far data models.
+# endif /* DYNAMIC_CRC_TABLE */
+# endif /* Turbo/Borland C far data memory models */
+# define nearmalloc malloc
+# define nearfree free
+# define DYN_ALLOC
+# else /* !__TURBOC__ */
+# include <malloc.h>
+# define nearmalloc _nmalloc
+# define nearfree _nfree
+# define farmalloc _fmalloc
+# define farfree _ffree
+# endif /* ?__TURBOC__ */
+# define MY_ZCALLOC 1
+# ifdef SMALL_MEM
+# define CBSZ 2048
+# define ZBSZ 2048
+# endif
+# ifdef MEDIUM_MEM
+# define CBSZ 4096
+# define ZBSZ 4096
+# endif
+# ifndef CBSZ
+# define CBSZ 8192
+# define ZBSZ 8192
+# endif
+#endif /* MEMORY16 */
+
+
+/* Symbolic links are not supported, but some compilers may define S_IFLNK. */
+#ifndef NO_SYMLINKS
+# define NO_SYMLINKS
+#endif
+
+#ifdef MATCH
+# undef MATCH
+#endif
+#define MATCH dosmatch /* use DOS style wildcard matching */
+
+#define USE_CASE_MAP
+
+#define ROUNDED_TIME(time) (((time) + 1) & (~1))
+#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \
+ procname(n, 1))
+
+#define FOPR "rb"
+#define FOPM "r+b"
+#define FOPW "wb"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <io.h>
+
+#ifdef ZCRYPT_INTERNAL
+# ifdef WINDLL
+# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */
+# else
+# ifndef __GO32__
+# include <process.h> /* getpid() declaration for srand seed */
+# endif
+# endif
+#endif
+
+/*
+ * djgpp 1.x did not declare these
+ */
+#if defined(__GO32__) && !defined(__DJGPP__)
+char *strlwr(char *);
+int setmode(int, int);
+#endif
+
+#ifdef __WATCOMC__
+# define NO_MKTEMP
+# define HAS_OPENDIR
+# define SSTAT stat_bandaid
+ int stat_bandaid(const char *path, struct stat *buf);
+
+/* Get asm routines to link properly without using "__cdecl": */
+# ifdef __386__
+# ifdef ASMV
+# pragma aux match_init "_*" parm caller [] modify []
+# pragma aux longest_match "_*" parm caller [] value [eax] \
+ modify [eax ecx edx]
+# endif
+# 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 */
+# else /* !__386__ */
+# ifdef ASMV
+# pragma aux match_init "_*" parm caller [] loadds modify [ax bx]
+# pragma aux longest_match "_*" parm caller [] loadds value [ax] \
+ modify [ax bx cx dx es]
+# endif /* ASMV */
+# ifndef USE_ZLIB
+# pragma aux crc32 "_*" parm caller [] value [ax dx] \
+ modify [ax bx cx dx es]
+# pragma aux get_crc_table "_*" parm caller [] value [ax] \
+ modify [ax bx cx dx]
+# endif /* !USE_ZLIB */
+# endif /* ?__386__ */
+#endif /* __WATCOMC__ */
+
+/*
+ * Wrapper function to get around the MSC7 00:00:00 31 Dec 1899 time base,
+ * see msdos.c for more info
+ */
+
+#if defined(_MSC_VER) && _MSC_VER == 700
+# define localtime(t) msc7_localtime(t)
+#endif
+
+#ifdef __TURBOC__
+# ifdef __FILEIO_C
+# include <dir.h> /* supplies mktemp() prototype */
+# endif
+#endif
+
+#if (defined(__TURBOC__) && !defined(__BORLANDC__) && __TURBOC__ <= 0x0201)
+# ifndef NO_MKTIME
+# define NO_MKTIME /* TC 2.01 and earlier do not supply mktime() */
+# endif
+#endif
+
+void check_for_windows(char *app);
diff --git a/msdos/zipup.h b/msdos/zipup.h
new file mode 100644
index 0000000..78b428a
--- /dev/null
+++ b/msdos/zipup.h
@@ -0,0 +1,16 @@
+/*
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 1999-Oct-05 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+*/
+#define fhow (O_RDONLY|O_BINARY)
+#define fbad (-1)
+typedef int ftype;
+#define zopen(n,p) open(n,p)
+#define zread(f,b,n) read(f,b,n)
+#define zclose(f) close(f)
+#define zerr(f) (k == (extent)(-1L))
+#define zstdin 0