diff --git a/tests/unzip2/actions.py b/tests/unzip2/actions.py
new file mode 100644
index 00000000..ed12a90d
--- /dev/null
+++ b/tests/unzip2/actions.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2005, TUBITAK/UEKAE
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# Please read the COPYING file.
+#
+
+from pisi.actionsapi import autotools
+from pisi.actionsapi import get
+from pisi.actionsapi import pisitools
+
+def setup():
+ pisitools.dosed("unix/Makefile", "-O3", get.CFLAGS())
+ pisitools.dosed("unix/Makefile", "CC=gcc LD=gcc", "CC=${CC:-gcc} LD=${CC:-gcc}")
+ pisitools.dosed("unix/Makefile", "-O ", get.CFLAGS())
+ pass
+
+def build():
+ autotools.make("-f unix/Makefile linux")
+
+def install():
+ pisitools.insinto("/usr/bin/", "unzip")
+ pisitools.insinto("/usr/bin/", "funzip")
+ pisitools.insinto("/usr/bin/", "unzipsfx")
+ pisitools.insinto("/usr/bin/", "unix/zipgrep")
+
+ pisitools.dosym("/usr/bin/unzip", "/usr/bin/zipinfo")
+ pisitools.doman("man/*.1")
+ pisitools.dodoc("BUGS", "History*", "README", "ToDo", "WHERE")
diff --git a/tests/unzip2/files/unzip-5.50-dotdot.patch b/tests/unzip2/files/unzip-5.50-dotdot.patch
new file mode 100644
index 00000000..73441f7b
--- /dev/null
+++ b/tests/unzip2/files/unzip-5.50-dotdot.patch
@@ -0,0 +1,85 @@
+Only in unzip-5.50-lhh/: cscope.files
+Only in unzip-5.50-lhh/: cscope.out
+diff -ur unzip-5.50/unix/unix.c unzip-5.50-lhh/unix/unix.c
+--- unzip-5.50/unix/unix.c 2002-01-21 17:54:42.000000000 -0500
++++ unzip-5.50-lhh/unix/unix.c 2003-06-11 18:35:38.000000000 -0400
+@@ -421,7 +421,8 @@
+ */
+ {
+ char pathcomp[FILNAMSIZ]; /* path-component buffer */
+- char *pp, *cp=(char *)NULL; /* character pointers */
++ char *pp, *cp=(char *)NULL, /* character pointers */
++ *dp=(char *)NULL;
+ char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */
+ #ifdef ACORN_FTYPE_NFS
+ char *lastcomma=(char *)NULL; /* pointer to last comma in pathcomp */
+@@ -429,6 +430,7 @@
+ #endif
+ int quote = FALSE; /* flags */
+ int killed_ddot = FALSE; /* is set when skipping "../" pathcomp */
++ int snarf_ddot = FALSE; /* Is set while scanning for "../" */
+ int error = MPN_OK;
+ register unsigned workch; /* hold the character being tested */
+
+@@ -467,6 +469,9 @@
+ while ((workch = (uch)*cp++) != 0) {
+
+ if (quote) { /* if character quoted, */
++ if ((pp == pathcomp) && (workch == '.'))
++ /* Oh no you don't... */
++ goto ddot_hack;
+ *pp++ = (char)workch; /* include it literally */
+ quote = FALSE;
+ } else
+@@ -481,15 +486,44 @@
+ break;
+
+ case '.':
+- if (pp == pathcomp) { /* nothing appended yet... */
++ if (pp == pathcomp) {
++ddot_hack:
++ /* nothing appended yet... */
+ if (*cp == '/') { /* don't bother appending "./" to */
+ ++cp; /* the path: skip behind the '/' */
+ break;
+- } else if (!uO.ddotflag && *cp == '.' && cp[1] == '/') {
+- /* "../" dir traversal detected */
+- cp += 2; /* skip over behind the '/' */
+- killed_ddot = TRUE; /* set "show message" flag */
+- break;
++ } else if (!uO.ddotflag) {
++
++ /*
++ * SECURITY: Skip past control characters if the user
++ * didn't OK use of absolute pathnames. lhh - this is
++ * a very quick, ugly, inefficient fix.
++ */
++ dp = cp;
++ do {
++ workch = (uch)(*dp);
++ if (workch == '/' && snarf_ddot) {
++ /* "../" dir traversal detected */
++ cp = dp + 1; /* skip past the '/' */
++ killed_ddot = TRUE; /* set "show msg" flag */
++ break;
++ } else if (workch == '.' && !snarf_ddot) {
++ snarf_ddot = TRUE;
++ } else if (isprint(workch) ||
++ ((workch > 127) && (workch <= 254))) {
++ /*
++ * Since we found a printable, non-ctrl char,
++ * we can stop looking for '../', the amount
++ * in ../!
++ */
++ break;
++ }
++
++ dp++;
++ } while (*dp != 0);
++
++ if (killed_ddot)
++ break;
+ }
+ }
+ *pp++ = '.';
+Only in unzip-5.50-lhh/unix: .unix.c.swp
diff --git a/tests/unzip2/pspec.xml b/tests/unzip2/pspec.xml
new file mode 100644
index 00000000..8ff86f0f
--- /dev/null
+++ b/tests/unzip2/pspec.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+ unzip
+ ftp://ftp.info-zip.org/pub/infozip/UnZip.html
+
+ A. Murat Eren
+ meren@uludag.org.tr
+
+ Info-ZIP
+ category
+ component
+ Unzipper for pkzip-compressed files
+ Unzipper for pkzip-compressed files
+ ftp://ftp.linux.org.tr/pub/mirrors/gentoo/distfiles/unzip550.tar.gz
+
+ unzip-5.50-dotdot.patch
+
+
+ libc
+ sed
+ patch
+
+
+
+ 2005-07-15
+ 5.50
+ 1
+
+
+
+
+
+ unzip
+
+
+
+
+ /usr/bin
+ /usr/share/doc
+ /usr/share/man
+
+
+
+
+
diff --git a/tests/zip2/actions.py b/tests/zip2/actions.py
new file mode 100644
index 00000000..730924b4
--- /dev/null
+++ b/tests/zip2/actions.py
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2005, TUBITAK/UEKAE
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# Please read the COPYING file.
+#
+
+from pisi.actionsapi import autotools
+from pisi.actionsapi import get
+from pisi.actionsapi import pisitools
+
+def setup():
+ pisitools.dosed("unix/Makefile", "-O2", get.CFLAGS())
+
+def build():
+ autotools.make("-f unix/Makefile CC=%s CPP=%s generic" % (get.CC(), get.CXX()))
+
+def install():
+ pisitools.dobin("zip")
+ pisitools.dobin("zipcloak")
+ pisitools.dobin("zipnote")
+ pisitools.dobin("zipsplit")
+
+ pisitools.doman("man/*.1")
+ pisitools.dodoc("BUGS", "CHANGES", "MANUAL", "README", "TODO", "WHATSNEW", "WHERE")
+
diff --git a/tests/zip2/files/zcrypt.patch b/tests/zip2/files/zcrypt.patch
new file mode 100644
index 00000000..6b696af5
--- /dev/null
+++ b/tests/zip2/files/zcrypt.patch
@@ -0,0 +1,752 @@
+diff -ur zip-2.3.orig/crypt.c zip-2.3/crypt.c
+--- zip-2.3.orig/crypt.c 1999-10-09 23:09:26.000000000 +0300
++++ zip-2.3/crypt.c 2005-07-15 16:19:00.000000000 +0300
+@@ -1,20 +1,577 @@
+ /*
+- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
++ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+- See the accompanying file LICENSE, version 1999-Oct-05 or later
++ 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, both of these files are missing, the Info-ZIP license
+- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
++ 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
+ */
+ /*
+- crypt.c (dummy version) by Info-ZIP. Last revised: 15 Aug 98
++ crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
+
+- This is a non-functional version of Info-ZIP's crypt.c encryption/
+- decryption code for Zip, ZipCloak, UnZip and fUnZip. This file is
+- not copyrighted and may be distributed freely. :-) See the "WHERE"
+- file for sites from which to obtain the full encryption/decryption
+- sources (zcrypt28.zip or later).
++ The encryption/decryption parts of this source code (as opposed to the
++ non-echoing password parts) were originally written in Europe. The
++ whole source package can be freely distributed, including from the USA.
++ (Prior to January 2000, re-export from the US was a violation of US law.)
+ */
+
++/*
++ This encryption code is a direct transcription of the algorithm from
++ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
++ file (appnote.txt) is distributed with the PKZIP program (even in the
++ version without encryption capabilities).
++ */
++
++#define ZCRYPT_INTERNAL
++#include "zip.h"
++#include "crypt.h"
++#include "ttyio.h"
++
++#if CRYPT
++
++#ifndef FALSE
++# define FALSE 0
++#endif
++
++#ifdef ZIP
++ /* For the encoding task used in Zip (and ZipCloak), we want to initialize
++ the crypt algorithm with some reasonably unpredictable bytes, see
++ the crypthead() function. The standard rand() library function is
++ used to supply these `random' bytes, which in turn is initialized by
++ a srand() call. The srand() function takes an "unsigned" (at least 16bit)
++ seed value as argument to determine the starting point of the rand()
++ pseudo-random number generator.
++ This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
++ Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
++ as some (hopefully) nondeterministic bitmask. On many (most) systems,
++ we use some "process specific" number, as the PID or something similar,
++ but when nothing unpredictable is available, a fixed number may be
++ sufficient.
++ NOTE:
++ 1.) This implementation requires the availability of the following
++ standard UNIX C runtime library functions: time(), rand(), srand().
++ On systems where some of them are missing, the environment that
++ incorporates the crypt routines must supply suitable replacement
++ functions.
++ 2.) It is a very bad idea to use a second call to time() to set the
++ "Seed2" number! In this case, both "Seed1" and "Seed2" would be
++ (almost) identical, resulting in a (mostly) "zero" constant seed
++ number passed to srand().
++
++ The implementation environment defined in the "zip.h" header should
++ supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
++ most implementations of rand() and srand(), only the lower 16 bits are
++ significant!). An example that works on many systems would be
++ "#define ZCR_SEED2 (unsigned)getpid()".
++ The default definition for ZCR_SEED2 supplied below should be regarded
++ as a fallback to allow successful compilation in "beta state"
++ environments.
++ */
++# include /* time() function supplies first part of crypt seed */
++ /* "last resort" source for second part of crypt seed pattern */
++# ifndef ZCR_SEED2
++# define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */
++# endif
++# ifdef GLOBAL /* used in Amiga system headers, maybe others too */
++# undef GLOBAL
++# endif
++# define GLOBAL(g) g
++#else /* !ZIP */
++# define GLOBAL(g) G.g
++#endif /* ?ZIP */
++
++
++#ifdef UNZIP
++ /* char *key = (char *)NULL; moved to globals.h */
++# ifndef FUNZIP
++ local int testp OF((__GPRO__ ZCONST uch *h));
++ local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
++# endif
++#endif /* UNZIP */
++
++#ifndef UNZIP /* moved to globals.h for UnZip */
++ local ulg keys[3]; /* keys defining the pseudo-random sequence */
++#endif /* !UNZIP */
++
++#ifndef Trace
++# ifdef CRYPT_DEBUG
++# define Trace(x) fprintf x
++# else
++# define Trace(x)
++# endif
++#endif
++
++#ifndef CRC_32_TAB
++# define CRC_32_TAB crc_32_tab
++#endif
++
++#define CRC32(c, b) (CRC_32_TAB[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
++
++/***********************************************************************
++ * Return the next byte in the pseudo-random sequence
++ */
++int decrypt_byte(__G)
++ __GDEF
++{
++ unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
++ * unpredictable manner on 16-bit systems; not a problem
++ * with any known compiler so far, though */
++
++ temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
++ return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
++}
++
++/***********************************************************************
++ * Update the encryption keys with the next byte of plain text
++ */
++int update_keys(__G__ c)
++ __GDEF
++ int c; /* byte of plain text */
++{
++ GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c);
++ GLOBAL(keys[1]) += GLOBAL(keys[0]) & 0xff;
++ GLOBAL(keys[1]) = GLOBAL(keys[1]) * 134775813L + 1;
++ {
++ register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
++ GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift);
++ }
++ return c;
++}
++
++
++/***********************************************************************
++ * Initialize the encryption keys and the random header according to
++ * the given password.
++ */
++void init_keys(__G__ passwd)
++ __GDEF
++ ZCONST char *passwd; /* password string with which to modify keys */
++{
++ GLOBAL(keys[0]) = 305419896L;
++ GLOBAL(keys[1]) = 591751049L;
++ GLOBAL(keys[2]) = 878082192L;
++ while (*passwd != '\0') {
++ update_keys(__G__ (int)*passwd);
++ passwd++;
++ }
++}
++
++
++#ifdef ZIP
++
++/***********************************************************************
++ * Write encryption header to file zfile using the password passwd
++ * and the cyclic redundancy check crc.
++ */
++void crypthead(passwd, crc, zfile)
++ ZCONST char *passwd; /* password string */
++ ulg crc; /* crc of file being encrypted */
++ FILE *zfile; /* where to write header */
++{
++ int n; /* index in random header */
++ int t; /* temporary */
++ int c; /* random byte */
++ int ztemp; /* temporary for zencoded value */
++ uch header[RAND_HEAD_LEN-2]; /* random header */
++ static unsigned calls = 0; /* ensure different random header each time */
++
++ /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
++ * output of rand() to get less predictability, since rand() is
++ * often poorly implemented.
++ */
++ if (++calls == 1) {
++ srand((unsigned)time(NULL) ^ ZCR_SEED2);
++ }
++ init_keys(passwd);
++ for (n = 0; n < RAND_HEAD_LEN-2; n++) {
++ c = (rand() >> 7) & 0xff;
++ header[n] = (uch)zencode(c, t);
++ }
++ /* Encrypt random header (last two bytes is high word of crc) */
++ init_keys(passwd);
++ for (n = 0; n < RAND_HEAD_LEN-2; n++) {
++ ztemp = zencode(header[n], t);
++ putc(ztemp, zfile);
++ }
++ ztemp = zencode((int)(crc >> 16) & 0xff, t);
++ putc(ztemp, zfile);
++ ztemp = zencode((int)(crc >> 24) & 0xff, t);
++ putc(ztemp, zfile);
++}
++
++
++#ifdef UTIL
++
++/***********************************************************************
++ * Encrypt the zip entry described by z from file source to file dest
++ * using the password passwd. Return an error code in the ZE_ class.
++ */
++int zipcloak(z, source, dest, passwd)
++ struct zlist far *z; /* zip entry to encrypt */
++ FILE *source, *dest; /* source and destination files */
++ ZCONST char *passwd; /* password string */
++{
++ int c; /* input byte */
++ int res; /* result code */
++ ulg n; /* holds offset and counts size */
++ ush flag; /* previous flags */
++ int t; /* temporary */
++ int ztemp; /* temporary storage for zencode value */
++
++ /* Set encrypted bit, clear extended local header bit and write local
++ header to output file */
++ if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
++ z->off = n;
++ flag = z->flg;
++ z->flg |= 1, z->flg &= ~8;
++ z->lflg |= 1, z->lflg &= ~8;
++ z->siz += RAND_HEAD_LEN;
++ if ((res = putlocal(z, dest)) != ZE_OK) return res;
++
++ /* Initialize keys with password and write random header */
++ crypthead(passwd, z->crc, dest);
++
++ /* Skip local header in input file */
++ if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
++ SEEK_CUR)) {
++ return ferror(source) ? ZE_READ : ZE_EOF;
++ }
++
++ /* Encrypt data */
++ for (n = z->siz - RAND_HEAD_LEN; n; n--) {
++ if ((c = getc(source)) == EOF) {
++ return ferror(source) ? ZE_READ : ZE_EOF;
++ }
++ ztemp = zencode(c, t);
++ putc(ztemp, dest);
++ }
++ /* Skip extended local header in input file if there is one */
++ if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
++ return ferror(source) ? ZE_READ : ZE_EOF;
++ }
++ if (fflush(dest) == EOF) return ZE_TEMP;
++ return ZE_OK;
++}
++
++/***********************************************************************
++ * Decrypt the zip entry described by z from file source to file dest
++ * using the password passwd. Return an error code in the ZE_ class.
++ */
++int zipbare(z, source, dest, passwd)
++ struct zlist far *z; /* zip entry to encrypt */
++ FILE *source, *dest; /* source and destination files */
++ ZCONST char *passwd; /* password string */
++{
++ int c0, c1; /* last two input bytes */
++ ulg offset; /* used for file offsets */
++ ulg size; /* size of input data */
++ int r; /* size of encryption header */
++ int res; /* return code */
++ ush flag; /* previous flags */
++
++ /* Save position and skip local header in input file */
++ if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
++ fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
++ SEEK_CUR)) {
++ return ferror(source) ? ZE_READ : ZE_EOF;
++ }
++ /* Initialize keys with password */
++ init_keys(passwd);
++
++ /* Decrypt encryption header, save last two bytes */
++ c1 = 0;
++ for (r = RAND_HEAD_LEN; r; r--) {
++ c0 = c1;
++ if ((c1 = getc(source)) == EOF) {
++ return ferror(source) ? ZE_READ : ZE_EOF;
++ }
++ Trace((stdout, " (%02x)", c1));
++ zdecode(c1);
++ Trace((stdout, " %02x", c1));
++ }
++ Trace((stdout, "\n"));
++
++ /* If last two bytes of header don't match crc (or file time in the
++ * case of an extended local header), back up and just copy. For
++ * pkzip 2.0, the check has been reduced to one byte only.
++ */
++#ifdef ZIP10
++ if ((ush)(c0 | (c1<<8)) !=
++ (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
++#else
++ c0++; /* avoid warning on unused variable */
++ if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
++#endif
++ if (fseek(source, offset, SEEK_SET)) {
++ return ferror(source) ? ZE_READ : ZE_EOF;
++ }
++ if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
++ return ZE_MISS;
++ }
++
++ /* Clear encrypted bit and local header bit, and write local header to
++ output file */
++ if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
++ z->off = offset;
++ flag = z->flg;
++ z->flg &= ~9;
++ z->lflg &= ~9;
++ z->siz -= RAND_HEAD_LEN;
++ if ((res = putlocal(z, dest)) != ZE_OK) return res;
++
++ /* Decrypt data */
++ for (size = z->siz; size; size--) {
++ if ((c1 = getc(source)) == EOF) {
++ return ferror(source) ? ZE_READ : ZE_EOF;
++ }
++ zdecode(c1);
++ putc(c1, dest);
++ }
++ /* Skip extended local header in input file if there is one */
++ if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
++ return ferror(source) ? ZE_READ : ZE_EOF;
++ }
++ if (fflush(dest) == EOF) return ZE_TEMP;
++
++ return ZE_OK;
++}
++
++
++#else /* !UTIL */
++
++/***********************************************************************
++ * If requested, encrypt the data in buf, and in any case call fwrite()
++ * with the arguments to zfwrite(). Return what fwrite() returns.
++ */
++unsigned zfwrite(buf, item_size, nb, f)
++ zvoid *buf; /* data buffer */
++ extent item_size; /* size of each item in bytes */
++ extent nb; /* number of items */
++ FILE *f; /* file to write to */
++{
++ int t; /* temporary */
++
++ if (key != (char *)NULL) { /* key is the global password pointer */
++ ulg size; /* buffer size */
++ char *p = (char*)buf; /* steps through buffer */
++
++ /* Encrypt data in buffer */
++ for (size = item_size*(ulg)nb; size != 0; p++, size--) {
++ *p = (char)zencode(*p, t);
++ }
++ }
++ /* Write the buffer out */
++ return fwrite(buf, item_size, nb, f);
++}
++
++#endif /* ?UTIL */
++#endif /* ZIP */
++
++
++#if (defined(UNZIP) && !defined(FUNZIP))
++
++/***********************************************************************
++ * Get the password and set up keys for current zipfile member.
++ * Return PK_ class error.
++ */
++int decrypt(__G__ passwrd)
++ __GDEF
++ ZCONST char *passwrd;
++{
++ ush b;
++ int n, r;
++ uch h[RAND_HEAD_LEN];
++
++ Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
++
++ /* get header once (turn off "encrypted" flag temporarily so we don't
++ * try to decrypt the same data twice) */
++ GLOBAL(pInfo->encrypted) = FALSE;
++ defer_leftover_input(__G);
++ for (n = 0; n < RAND_HEAD_LEN; n++) {
++ b = NEXTBYTE;
++ h[n] = (uch)b;
++ Trace((stdout, " (%02x)", h[n]));
++ }
++ undefer_input(__G);
++ GLOBAL(pInfo->encrypted) = TRUE;
++
++ if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
++ GLOBAL(newzip) = FALSE;
++ if (passwrd != (char *)NULL) { /* user gave password on command line */
++ if (!GLOBAL(key)) {
++ if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
++ (char *)NULL)
++ return PK_MEM2;
++ strcpy(GLOBAL(key), passwrd);
++ GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */
++ }
++ } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
++ free(GLOBAL(key));
++ GLOBAL(key) = (char *)NULL;
++ }
++ }
++
++ /* if have key already, test it; else allocate memory for it */
++ if (GLOBAL(key)) {
++ if (!testp(__G__ h))
++ return PK_COOL; /* existing password OK (else prompt for new) */
++ else if (GLOBAL(nopwd))
++ return PK_WARN; /* user indicated no more prompting */
++ } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
++ return PK_MEM2;
++
++ /* try a few keys */
++ n = 0;
++ do {
++ r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
++ GLOBAL(zipfn), GLOBAL(filename));
++ if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */
++ free (GLOBAL(key));
++ GLOBAL(key) = NULL;
++ return PK_MEM2;
++ }
++ if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */
++ *GLOBAL(key) = '\0'; /* We try the NIL password, ... */
++ n = 0; /* and cancel fetch for this item. */
++ }
++ if (!testp(__G__ h))
++ return PK_COOL;
++ if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */
++ GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */
++ } while (n > 0);
++
++ return PK_WARN;
++
++} /* end function decrypt() */
++
++
++
++/***********************************************************************
++ * Test the password. Return -1 if bad, 0 if OK.
++ */
++local int testp(__G__ h)
++ __GDEF
++ ZCONST uch *h;
++{
++ int r;
++ char *key_translated;
++
++ /* On systems with "obscure" native character coding (e.g., EBCDIC),
++ * the first test translates the password to the "main standard"
++ * character coding. */
++
++#ifdef STR_TO_CP1
++ /* allocate buffer for translated password */
++ if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
++ return -1;
++ /* first try, test password translated "standard" charset */
++ r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
++#else /* !STR_TO_CP1 */
++ /* first try, test password as supplied on the extractor's host */
++ r = testkey(__G__ h, GLOBAL(key));
++#endif /* ?STR_TO_CP1 */
++
++#ifdef STR_TO_CP2
++ if (r != 0) {
++#ifndef STR_TO_CP1
++ /* now prepare for second (and maybe third) test with translated pwd */
++ if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
++ return -1;
++#endif
++ /* second try, password translated to alternate ("standard") charset */
++ r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
++#ifdef STR_TO_CP3
++ if (r != 0)
++ /* third try, password translated to another "standard" charset */
++ r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
++#endif
++#ifndef STR_TO_CP1
++ free(key_translated);
++#endif
++ }
++#endif /* STR_TO_CP2 */
++
++#ifdef STR_TO_CP1
++ free(key_translated);
++ if (r != 0) {
++ /* last resort, test password as supplied on the extractor's host */
++ r = testkey(__G__ h, GLOBAL(key));
++ }
++#endif /* STR_TO_CP1 */
++
++ return r;
++
++} /* end function testp() */
++
++
++local int testkey(__G__ h, key)
++ __GDEF
++ ZCONST uch *h; /* decrypted header */
++ ZCONST char *key; /* decryption password to test */
++{
++ ush b;
++#ifdef ZIP10
++ ush c;
++#endif
++ int n;
++ uch *p;
++ uch hh[RAND_HEAD_LEN]; /* decrypted header */
++
++ /* set keys and save the encrypted header */
++ init_keys(__G__ key);
++ memcpy(hh, h, RAND_HEAD_LEN);
++
++ /* check password */
++ for (n = 0; n < RAND_HEAD_LEN; n++) {
++ zdecode(hh[n]);
++ Trace((stdout, " %02x", hh[n]));
++ }
++
++ Trace((stdout,
++ "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n",
++ GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
++ GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
++ Trace((stdout, " incnt = %d unzip offset into zipfile = %ld\n",
++ GLOBAL(incnt),
++ GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
++
++ /* same test as in zipbare(): */
++
++#ifdef ZIP10 /* check two bytes */
++ c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
++ Trace((stdout,
++ " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
++ (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
++ ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
++ if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
++ ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
++ (ush)(GLOBAL(lrec.crc32) >> 16)))
++ return -1; /* bad */
++#else
++ b = hh[RAND_HEAD_LEN-1];
++ Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n",
++ b, (ush)(GLOBAL(lrec.crc32) >> 24),
++ ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
++ if (b != (GLOBAL(pInfo->ExtLocHdr) ?
++ ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
++ (ush)(GLOBAL(lrec.crc32) >> 24)))
++ return -1; /* bad */
++#endif
++ /* password OK: decrypt current buffer contents before leaving */
++ for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
++ (int)GLOBAL(csize) : GLOBAL(incnt),
++ p = GLOBAL(inptr); n--; p++)
++ zdecode(*p);
++ return 0; /* OK */
++
++} /* end function testkey() */
++
++#endif /* UNZIP && !FUNZIP */
++
++#else /* !CRYPT */
++
+ /* something "externally visible" to shut up compiler/linker warnings */
+ int zcr_dummy;
++
++#endif /* ?CRYPT */
+diff -ur zip-2.3.orig/crypt.h zip-2.3/crypt.h
+--- zip-2.3.orig/crypt.h 1999-10-09 23:10:00.000000000 +0300
++++ zip-2.3/crypt.h 2005-07-15 16:19:00.000000000 +0300
+@@ -1,19 +1,13 @@
+ /*
+- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
++ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+- See the accompanying file LICENSE, version 1999-Oct-05 or later
++ 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, both of these files are missing, the Info-ZIP license
+- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
++ 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
+ */
+ /*
+- crypt.h (dummy version) by Info-ZIP. Last revised: 15 Aug 98
+-
+- This is a non-functional version of Info-ZIP's crypt.h encryption/
+- decryption header file for Zip, ZipCloak, UnZip and fUnZip. This
+- file is not copyrighted and may be distributed without restriction.
+- See the "WHERE" file for sites from which to obtain the full crypt
+- sources (zcrypt28.zip or later).
++ crypt.h (full version) by Info-ZIP. Last revised: [see CR_VERSION_DATE]
+ */
+
+ #ifndef __crypt_h /* don't include more than once */
+@@ -22,11 +16,131 @@
+ #ifdef CRYPT
+ # undef CRYPT
+ #endif
+-#define CRYPT 0 /* dummy version */
++
++#if !defined(NO_CRYPT)
++# define CRYPT 1 /* full version */
++#else
++# define CRYPT 0 /* dummy version */
++#endif
++
++#if CRYPT
++/* full version */
++
++#ifdef CR_BETA
++# undef CR_BETA /* this is not a beta release */
++#endif
++
++#define CR_MAJORVER 2
++#define CR_MINORVER 9
++#ifdef CR_BETA
++# define CR_BETA_VER "a BETA"
++# define CR_VERSION_DATE "9 April 2000" /* last real code change */
++#else
++# define CR_BETA_VER ""
++# define CR_VERSION_DATE "22 April 2000" /* last public release date */
++# define CR_RELEASE
++#endif
++
++#ifndef __G /* UnZip only, for now (DLL stuff) */
++# define __G
++# define __G__
++# define __GDEF
++# define __GPRO void
++# define __GPRO__
++#endif
++
++#if defined(MSDOS) || defined(OS2) || defined(WIN32)
++# ifndef DOS_OS2_W32
++# define DOS_OS2_W32
++# endif
++#endif
++
++#if defined(DOS_OS2_W32) || defined(__human68k__)
++# ifndef DOS_H68_OS2_W32
++# define DOS_H68_OS2_W32
++# endif
++#endif
++
++#if defined(VM_CMS) || defined(MVS)
++# ifndef CMS_MVS
++# define CMS_MVS
++# endif
++#endif
++
++/* To allow combining of Zip and UnZip static libraries in a single binary,
++ * the Zip and UnZip versions of the crypt core functions have to be named
++ * differently.
++ */
++#ifdef ZIP
++# ifdef REALLY_SHORT_SYMS
++# define decrypt_byte zdcrby
++# else
++# define decrypt_byte zp_decrypt_byte
++# endif
++# define update_keys zp_update_keys
++# define init_keys zp_init_keys
++#else /* !ZIP */
++# ifdef REALLY_SHORT_SYMS
++# define decrypt_byte dcrbyt
++# endif
++#endif /* ?ZIP */
++
++#define IZ_PWLEN 80 /* input buffer size for reading encryption key */
++#ifndef PWLEN /* for compatibility with previous zcrypt release... */
++# define PWLEN IZ_PWLEN
++#endif
++#define RAND_HEAD_LEN 12 /* length of encryption random header */
++
++/* the crc_32_tab array has to be provided externally for the crypt calculus */
++#ifndef CRC_32_TAB /* UnZip provides this in globals.h */
++# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
++ extern ZCONST ulg near *crc_32_tab;
++# else
++ extern ZCONST ulg Far *crc_32_tab;
++# endif
++#endif /* !CRC_32_TAB */
++
++/* encode byte c, using temp t. Warning: c must not have side effects. */
++#define zencode(c,t) (t=decrypt_byte(__G), update_keys(c), t^(c))
++
++/* decode byte c in place */
++#define zdecode(c) update_keys(__G__ c ^= decrypt_byte(__G))
++
++int decrypt_byte OF((__GPRO));
++int update_keys OF((__GPRO__ int c));
++void init_keys OF((__GPRO__ ZCONST char *passwd));
++
++#ifdef ZIP
++ void crypthead OF((ZCONST char *, ulg, FILE *));
++# ifdef UTIL
++ int zipcloak OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
++ int zipbare OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
++# else
++ unsigned zfwrite OF((zvoid *, extent, extent, FILE *));
++ extern char *key;
++# endif
++#endif /* ZIP */
++
++#if (defined(UNZIP) && !defined(FUNZIP))
++ int decrypt OF((__GPRO__ ZCONST char *passwrd));
++#endif
++
++#ifdef FUNZIP
++ extern int encrypted;
++# ifdef NEXTBYTE
++# undef NEXTBYTE
++# endif
++# define NEXTBYTE \
++ (encrypted? update_keys(__G__ getc(G.in)^decrypt_byte(__G)) : getc(G.in))
++#endif /* FUNZIP */
++
++#else /* !CRYPT */
++/* dummy version */
+
+ #define zencode
+ #define zdecode
+
+ #define zfwrite fwrite
+
++#endif /* ?CRYPT */
+ #endif /* !__crypt_h */
diff --git a/tests/zip2/files/zip-2.3-unix_configure-pic.patch b/tests/zip2/files/zip-2.3-unix_configure-pic.patch
new file mode 100644
index 00000000..45b137b0
--- /dev/null
+++ b/tests/zip2/files/zip-2.3-unix_configure-pic.patch
@@ -0,0 +1,12 @@
+--- unix/configure.orig 2004-09-28 06:45:33.000000000 +0000
++++ unix/configure 2004-09-28 06:54:53.000000000 +0000
+@@ -29,6 +29,9 @@
+
+ echo Check if we can use asm code
+ OBJA=""
++piclib="$(echo | $CPP -dM $CFLAGS - | grep -i __pic__)"
++echo "Checking if compiler wants to create pic code"
++[ "$piclib" == "" ] && \
+ if eval "$CPP match.S > _match.s 2>/dev/null"; then
+ if test ! -s _match.s || grep error < _match.s > /dev/null; then
+ :
diff --git a/tests/zip2/files/zip-CAN-2004-1010.patch b/tests/zip2/files/zip-CAN-2004-1010.patch
new file mode 100644
index 00000000..150d6407
--- /dev/null
+++ b/tests/zip2/files/zip-CAN-2004-1010.patch
@@ -0,0 +1,25 @@
+--- zip-2.3/unix/unix.c.orig 2004-11-05 15:44:41.000000000 -0500
++++ zip-2.3/unix/unix.c 2004-11-05 15:50:28.000000000 -0500
+@@ -319,8 +319,8 @@ iztimes *t; /* return value:
+ a file size of -1 */
+ {
+ struct stat s; /* results of stat() */
+- char name[FNMAX];
+- int len = strlen(f);
++ char *name;
++ size_t len = strlen(f);
+
+ if (f == label) {
+ if (a != NULL)
+@@ -331,6 +331,11 @@ iztimes *t; /* return value:
+ t->atime = t->mtime = t->ctime = label_utim;
+ return label_time;
+ }
++
++ name = malloc(len+1);
++ if (!name)
++ return 0;
++
+ strcpy(name, f);
+ if (name[len - 1] == '/')
+ name[len - 1] = '\0';
diff --git a/tests/zip2/pspec.xml b/tests/zip2/pspec.xml
new file mode 100644
index 00000000..e64035a5
--- /dev/null
+++ b/tests/zip2/pspec.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+ zip
+ ftp://ftp.freesoftware.com/pub/infozip/Zip.html
+
+ PACKAGER
+ PACKAGER_EMAIL
+
+ Info-ZIP
+ category
+ component
+ Info ZIP (encryption support)
+ Info ZIP (encryption support)
+ ftp://ftp.linux.org.tr/pub/mirrors/gentoo/distfiles/zip23.tar.gz
+
+ zip-2.3-unix_configure-pic.patch
+ zip-CAN-2004-1010.patch
+ zcrypt.patch
+
+
+ unzip
+ patch
+
+
+
+ 2005-07-15
+ 2.3
+ 1
+
+
+
+
+
+ zip
+
+ unzip
+
+
+ /usr/bin
+ /usr/share/doc
+ /usr/share/man
+
+
+
+
+