pstodulk pushed to unzip (pstodulk_segment). "added rewritten alpha-upstream-patch for support of segmented archives"
notifications at fedoraproject.org
notifications at fedoraproject.org
Wed Mar 25 11:45:27 UTC 2015
>From 53b4bd8b698f28aaf185c2d2d51ffae90f7723ba Mon Sep 17 00:00:00 2001
From: Petr Stodulka <pstodulk at redhat.com>
Date: Wed, 25 Mar 2015 12:44:32 +0100
Subject: added rewritten alpha-upstream-patch for support of segmented
archives
diff --git a/unzip-sgmnt-rfe.patch b/unzip-sgmnt-rfe.patch
new file mode 100644
index 0000000..8dbfdc7
--- /dev/null
+++ b/unzip-sgmnt-rfe.patch
@@ -0,0 +1,1341 @@
+diff --git a/cmsmvs/vmmvs.c b/cmsmvs/vmmvs.c
+index 8416ce8..13d410d 100644
+--- a/cmsmvs/vmmvs.c
++++ b/cmsmvs/vmmvs.c
+@@ -35,17 +35,23 @@
+ /* Function vmmvs_open_infile() */
+ /********************************/
+
+-FILE *vmmvs_open_infile(__G)
++FILE *vmmvs_open_infile(__G fn)
+ __GDEF
++ char *fn;
+ {
+ FILE *fzip;
+
+- G.tempfn = NULL;
+
+- fzip = fopen(G.zipfn, FOPR);
++ fzip = fopen(.fn, FOPR);
++#ifdef CMS_MVS_INFILE_TMP
+
+-#if 0
+ /* Let's try it without the convert for a while -- RG Hartwig */
++ /* 2015-03-17 SMS.
++ * If ever re-enabled, this code will need changes to accommodate the
++ * additional archive segment file(s) (variable file name).
++ */
++
++ G.tempfn = NULL;
+
+ if ((fzip = fopen(G.zipfn,"rb,recfm=fb")) == NULL) {
+ size_t cnt;
+@@ -82,7 +88,7 @@ FILE *vmmvs_open_infile(__G)
+ G.ziplen = ftell(fzip);
+ }
+
+-#endif
++#endif /* def CMS_MVS_INFILE_TMP */
+
+ return fzip;
+ }
+@@ -177,15 +183,21 @@ void close_outfile(__G)
+ /* Function close_infile() */
+ /***************************/
+
+-void close_infile(__G)
++void close_infile(__G__ pfd)
+ __GDEF
++ zipfd_t *pfd;
+ {
+- fclose(G.zipfd);
++ int sts;
++ sts = fclose( *pfd);
++ *pfd = NULL;
+
+- /* If we're working from a temp file, erase it now */
+- if (G.tempfn)
+- remove(G.tempfn);
++#ifdef CMS_MVS_INFILE_TMP
++ /* If we're working from a temp file, erase it now */
++ if (G.tempfn)
++ remove(G.tempfn);
++#endif /* def CMS_MVS_INFILE_TMP */
+
++ return sts;
+ } /* end function close_infile() */
+
+
+diff --git a/consts.h b/consts.h
+index 5dfc0a0..dee57b1 100644
+--- a/consts.h
++++ b/consts.h
+@@ -33,7 +33,7 @@ ZCONST char Far VersionDate[] = UZ_VERSION_DATE; /* now defined in unzvers.h */
+ ZCONST char Far CentSigMsg[] =
+ "error: expected central file header signature not found (file #%lu).\n";
+ ZCONST char Far SeekMsg[] =
+- "error [%s]: attempt to seek before beginning of zipfile\n%s";
++ "error [%s]: attempt to seek before beginning of zipfile (%d)\n%s";
+ ZCONST char Far FilenameNotMatched[] = "caution: filename not matched: %s\n";
+ ZCONST char Far ExclFilenameNotMatched[] =
+ "caution: excluded filename not matched: %s\n";
+diff --git a/extract.c b/extract.c
+index 7134bfe..e41803f 100644
+--- a/extract.c
++++ b/extract.c
+@@ -19,6 +19,7 @@
+ find_compr_idx()
+ extract_or_test_entrylist()
+ extract_or_test_member()
++ close_segment()
+ TestExtraField()
+ test_compr_eb()
+ memextract()
+@@ -323,8 +324,20 @@ static ZCONST char Far BadExtraFieldCRC[] =
+ "error [%s]: bad extra-field CRC %08lx (should be %08lx)\n";
+
+
++/*******************************/
++/* Function close_segment(). */
++/*******************************/
++static void close_segment(__G)
++ __GDEF
++{
++ if (G.zipfn_sgmnt != NULL)
++ {
++ izu_free(G.zipfn_sgmnt);
++ G.zipfn_sgmnt = NULL;
++ }
++ CLOSE_INFILE( &G.zipfd_sgmnt);
+
+-
++} /* close_segment(). */
+
+ /**************************************/
+ /* Function extract_or_test_files() */
+@@ -351,6 +364,8 @@ int extract_or_test_files(__G) /* return PK-type error code */
+ unsigned num_dirs=0;
+ direntry *dirlist=(direntry *)NULL, **sorted_dirlist=(direntry **)NULL;
+ #endif
++ zuvl_t sgmnt_nr;
++ zipfd_t zipfd;
+
+ /*
+ * First, two general initializations are applied. These have been moved
+@@ -578,6 +593,12 @@ int extract_or_test_files(__G) /* return PK-type error code */
+ cd_inptr = G.inptr;
+ cd_incnt = G.incnt;
+
++ /* Save the file descr/pointer and segment number, which are subject
++ * to change when the archive is segmented.
++ */
++ zipfd = G.zipfd;
++ sgmnt_nr = G.sgmnt_nr;
++
+ /*-----------------------------------------------------------------------
+ Second loop: process files in current block, extracting or testing
+ each one.
+@@ -606,7 +627,8 @@ int extract_or_test_files(__G) /* return PK-type error code */
+ * Jump back to where we were in the central directory, then go and do
+ * the next batch of files.
+ */
+-
++ G.zipfd = zipfd;
++ G.sgmnt_nr = sgmnt_nr;
+ #ifdef USE_STRM_INPUT
+ zfseeko(G.zipfd, cd_bufstart, SEEK_SET);
+ G.cur_zipfile_bufstart = zftello(G.zipfd);
+@@ -1060,8 +1082,51 @@ static int extract_or_test_entrylist(__G__ numchunk,
+ * (either haven't yet read far enough, or (maybe) skipping back-
+ * ward), skip to the target position and reset readbuf(). */
+
++ if(G.ecrec.number_this_disk > 0)
++ {
++ /* Open file (when it is segmented) even if it is a duplicate
++ * of the same fd, due to possible unwanted changes of G.zipfd
++ * and G.sgmnt_nr which were saved in extract_or_test_files().
++ */
++ if (!fd_is_valid(G.zipfd_sgmnt) || G.sgmnt_nr != G.pInfo->diskstart)
++ {
++ if (fd_is_valid(G.zipfd_sgmnt))
++ close_segment( __G); /* We need a different file. */
++
++ set_zipfn_sgmnt_name( __G__ G.pInfo->diskstart);
++ if (open_infile( __G__ OIF_SEGMENT))
++ {
++ /* TODO: ask for place/path of zipfile, see wild*!, ... */
++ /* Create new function for this all? */
++ izu_free(G.zipfn_sgmnt);
++ G.zipfn_sgmnt = NULL;
++ error = PK_NOZIP;
++ return error;
++ }
++ else
++ {
++ /* TODO: that's not best solution but for
++ * testing/alpha version is good enough now. */
++ G.zipfd = G.zipfd_sgmnt;
++ G.sgmnt_nr = G.pInfo->diskstart;
++ }
++ /* When we change file, we must refill buffer always!
++ * (Same method as in seek_zipf().)
++ */
++ G.cur_zipfile_bufstart = -1;
++ }
++ /* TODO: check better too -- Is G.extra_bytes important in
++ * segmented? Otherwise bigger harakiri is here
++ * needed (here = whole request block below)
++ */
++ request = G.pInfo->offset;
++ }
++ else
++ {
++ request = G.pInfo->offset + G.extra_bytes;
++ }
++
+ /* seek_zipf(__G__ pInfo->offset); */
+- request = G.pInfo->offset + G.extra_bytes;
+ inbuf_offset = request % INBUFSIZ;
+ bufstart = request - inbuf_offset;
+
+diff --git a/fileio.c b/fileio.c
+index 2a61a30..8bbe1b9 100644
+--- a/fileio.c
++++ b/fileio.c
+@@ -147,6 +147,10 @@ static int disk_error OF((__GPRO));
+ static ZCONST char Far CannotOpenZipfile[] =
+ "error: cannot open zipfile [ %s ]\n %s\n";
+
++static ZCONST char Far NoSuchSegment[] =
++ "Bad archive segment value (%d > %d)";
++
++
+ #if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
+ #if (!defined(TANDEM))
+ #if (defined(ATH_BEO_THS_UNX) || defined(DOS_FLX_NLM_OS2_W32))
+@@ -215,51 +219,234 @@ static ZCONST char Far ExtraFieldCorrupt[] =
+
+
+ /******************************/
+-/* Function open_input_file() */
++/* Function open_infile() */
+ /******************************/
+
+-int open_input_file(__G) /* return 1 if open failed */
++int open_infile(__G__ which) /* return 1 if open failed */
+ __GDEF
++ int which; /* 0: Primary archive; 1: Segment archive. */
++
+ {
+- /*
+- * open the zipfile for reading and in BINARY mode to prevent cr/lf
+- * translation, which would corrupt the bitstreams
+- */
++
++ /* Open an archive (zipfile) for reading and in BINARY mode to
++ * prevent CR/LF translation, which would corrupt the data.
++ * Return 0: success; 1: failure.
++ */
++
++ char *fn;
++ zipfd_t *pfd;
++
++ if (which == OIF_PRIMARY)
++ {
++ fn = G.zipfn; /* Primary archive file name (".zip"). */
++ pfd = &G.zipfd; /* Primary archive file descr/pointer. */
++ }
++ else
++ {
++ fn = G.zipfn_sgmnt; /* Segment archive file name (".zXX"). */
++ pfd = &G.zipfd_sgmnt; /* Segment archive file descr/pointer. */
++ }
+
+ #ifdef VMS
+- G.zipfd = open(G.zipfn, O_RDONLY, 0, OPNZIP_RMS_ARGS);
++ *pfd = open( fn, O_RDONLY, 0, OPNZIP_RMS_ARGS);
+ #else /* !VMS */
+ #ifdef MACOS
+- G.zipfd = open(G.zipfn, 0);
++ *pfd = open(fn, 0);
+ #else /* !MACOS */
+ #ifdef CMS_MVS
+- G.zipfd = vmmvs_open_infile(__G);
++ *pfd = vmmvs_open_infile(__G__ fn, pfd);
+ #else /* !CMS_MVS */
+ #ifdef USE_STRM_INPUT
+- G.zipfd = fopen(G.zipfn, FOPR);
++ *pfd = fopen(fn, FOPR);
+ #else /* !USE_STRM_INPUT */
+- G.zipfd = open(G.zipfn, O_RDONLY | O_BINARY);
++ *pfd = open(fn, O_RDONLY | O_BINARY);
+ #endif /* ?USE_STRM_INPUT */
+ #endif /* ?CMS_MVS */
+ #endif /* ?MACOS */
+ #endif /* ?VMS */
+
+-#ifdef USE_STRM_INPUT
+- if (G.zipfd == NULL)
+-#else
+- /* if (G.zipfd < 0) */ /* no good for Windows CE port */
+- if (G.zipfd == -1)
+-#endif
++ if (!fd_is_valid( *pfd))
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CannotOpenZipfile),
+- G.zipfn, strerror(errno)));
++ fn, strerror(errno)));
+ return 1;
+ }
+ return 0;
+
+ } /* end function open_input_file() */
+
++/***************************/
++/* Function close_infile() */
++/***************************/
++int close_infile( __G__ pfd)
++ __GDEF
++ zipfd_t *pfd;
++{
++ int sts = 0;
++
++ if (fd_is_valid( *pfd))
++ {
++#ifdef USE_STRM_INPUT
++ sts = fclose( *pfd);
++#else /* def USE_STRM_INPUT */
++ sts = close( *pfd);
++#endif /* def USE_STRM_INPUT [else] */
++ *pfd = ZIPFD_INVALID;
++ }
+
++ return sts;
++} /* close_infile() */
++
++/***********************************/
++/* Function set_zipfn_sgmnt_name() */
++/***********************************/
++int set_zipfn_sgmnt_name( __G__ sgmnt_nr)
++ __GDEF
++ zuvl_t sgmnt_nr;
++{
++ char *suffix;
++ int sufx_len;
++
++/* sizeof( ".z65535") == 8 should be safe. */
++#define SGMNT_NAME_BOOST 8
++
++ if (sgmnt_nr > G.ecrec.number_this_disk)
++ {
++ /* Segment number greater than (max?) central-dir disk number. */
++ Info(slide, 1, ((char *)slide, LoadFarString(NoSuchSegment),
++ sgmnt_nr, G.ecrec.number_this_disk));
++ return 1;
++ }
++
++ if (G.zipfn_sgmnt == NULL)
++ {
++ G.zipfn_sgmnt_size = strlen(G.zipfn)+ SGMNT_NAME_BOOST;
++ if ((G.zipfn_sgmnt = izu_malloc(G.zipfn_sgmnt_size)) == NULL)
++ {
++ G.zipfn_sgmnt_size = -1;
++ return 1;
++ }
++ }
++ else
++ {
++ if (G.zipfn_sgmnt_size < (int)strlen(G.zipfn)+ SGMNT_NAME_BOOST)
++ {
++ G.zipfn_sgmnt_size = strlen(G.zipfn)+ SGMNT_NAME_BOOST;
++ izu_free(G.zipfn_sgmnt);
++ if ((G.zipfn_sgmnt = izu_malloc(G.zipfn_sgmnt_size)) == NULL)
++ {
++ G.zipfn_sgmnt_size = -1;
++ return 1;
++ }
++ }
++ }
++
++
++ if (sgmnt_nr == G.ecrec.number_this_disk)
++ {
++ zfstrcpy(G.zipfn_sgmnt, G.zipfn);
++ return 0; /* Last segment. Name already ".zip." */
++ }
++
++#ifdef VMS
++
++ /* A VMS archive file spec may include a version number (";nnn"),
++ * confusing any simple scheme (like the one below). $PARSE can
++ * easily replace one file type with another (and null out the version
++ * number), so use it, instead.
++ */
++ vms_sgmnt_name( G.zipfn_sgmnt, G.zipfn, (sgmnt_nr+ 1));
++
++#else /* def VMS */
++
++ zfstrcpy(G.zipfn_sgmnt, G.zipfn);
++ /* Expect to find ".zXX" at the end of the segment file name. */
++ sufx_len = IZ_MAX( 0, ((int)strlen(G.zipfn_sgmnt)- 4));
++ suffix = G.zipfn_sgmnt+ sufx_len;
++
++ /* try find filename extension and set right position for add number */
++ if (zfstrcmp(suffix, ZSUFX) == 0)
++ {
++ suffix += 2; /* Point to digits after ".z". */
++# ifdef ZSUFX2
++ }
++ else if (zfstrcmp(suffix, ZSUFX2) == 0) /* Check alternate suffix. */
++ {
++ suffix[1] = 'z'; /* Should be always lowercase??? */
++ suffix += 2; /* Point to digits after ".z". */
++# endif
++ }
++ else
++ {
++ zfstrcpy( (suffix+ sufx_len), ZSUFX);
++ suffix += sufx_len+ 2;
++ }
++ /* Insert the next segment number into the file name (G.zipfn_sgmnt). */
++ sprintf(suffix, "%02d", (sgmnt_nr+ 1));
++
++#endif /* def VMS [else] */
++
++ return 0;
++} /* set_zipfn_sgmnt_name(). */
++
++/********************************/
++/* Function open_infile_sgmnt() */
++/********************************/
++int open_infile_sgmnt(__G__ movement)
++ __GDEF
++ int movement;
++{
++ zipfd_t zipfd;
++ zipfd_t zipfd_sgmnt;
++
++ if (movement == 0) /* Nothing to do. */
++ return 0;
++
++ zipfd = G.zipfd;
++ zipfd_sgmnt = G.zipfd_sgmnt;
++
++ /* Set the new segment file name. */
++ if (set_zipfn_sgmnt_name( __G__ G.sgmnt_nr+ movement))
++ return 1;
++
++ if (open_infile( __G__ OIF_SEGMENT))
++ {
++ /* TODO: ask for input and try it again */
++ /* error, load back old zipfn (it shouldn't be frequently) */
++ if (fd_is_valid(zipfd_sgmnt))
++ {
++ set_zipfn_sgmnt_name( __G__ G.sgmnt_nr);
++ }
++ else
++ {
++ /* Loading of central directory record probably??? */
++ izu_free(G.zipfn_sgmnt);
++ G.zipfn_sgmnt = NULL;
++ }
++
++ G.zipfd_sgmnt = zipfd_sgmnt;
++ return 1;
++ }
++
++ G.sgmnt_nr += movement;
++
++ /* close old file - yes, that's nasty solution */
++ /* Switch I/O to the new segment. */
++ G.zipfd = G.zipfd_sgmnt;
++ G.zipfd_sgmnt = zipfd; /* Old G.zipfd. */
++ CLOSE_INFILE( &G.zipfd_sgmnt);
++ if (fd_is_valid(zipfd_sgmnt)) /* Old G.zipfd_sgmnt. */
++ {
++ G.zipfd_sgmnt = G.zipfd;
++ }
++ else
++ {
++ izu_free(G.zipfn_sgmnt); /* We must clean it now. */
++ G.zipfn_sgmnt = NULL;
++ }
++
++ return 0;
++} /* open_infile_sgmnt() */
+
+
+ #if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
+@@ -581,11 +768,26 @@ unsigned readbuf(__G__ buf, size) /* return number of bytes read into buf */
+ unsigned n;
+
+ n = size;
+- while (size) {
+- if (G.incnt <= 0) {
++ while (size)
++ {
++ if (G.incnt <= 0)
++ {
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
+- return (n-size);
+- else if (G.incnt < 0) {
++ {
++ /* read() got no data. If the srchive is segmented, then
++ * try again with the next segment file.
++ */
++ if (G.ecrec.number_this_disk > 0)
++ {
++ if ((open_infile_sgmnt( __G__ 1) != 0) ||
++ (G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
++ return (n-size); /* Return short retry size. */
++ } else
++ return (n-size); /* Return short size. */
++ }
++
++ if (G.incnt < 0)
++ {
+ /* another hack, but no real harm copying same thing twice */
+ (*G.message)((zvoid *)&G,
+ (uch *)LoadFarString(ReadError), /* CANNOT use slide */
+@@ -620,16 +822,33 @@ int readbyte(__G) /* refill inbuf and return a byte if available, else EOF */
+ {
+ if (G.mem_mode)
+ return EOF;
+- if (G.csize <= 0) {
++ if (G.csize <= 0)
++ {
+ G.csize--; /* for tests done after exploding */
+ G.incnt = 0;
+ return EOF;
+ }
+- if (G.incnt <= 0) {
+- if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0) {
+- return EOF;
+- } else if (G.incnt < 0) { /* "fail" (abort, retry, ...) returns this */
+- /* another hack, but no real harm copying same thing twice */
++ if (G.incnt <= 0)
++ {
++ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
++ {
++ /* read() got no data. If the srchive is segmented, then
++ * try again with the next segment file.
++ */
++ /* if(fd_is_valid(G.zipfd_sgmnt)) { */
++ if (G.ecrec.number_this_disk > 0)
++ {
++ if ((open_infile_sgmnt( __G__ 1) != 0) ||
++ (G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
++ return EOF;
++ } else
++ return EOF;
++ }
++
++ if (G.incnt < 0)
++ { /* "fail" (abort, retry, ...) returns this.
++ * another hack, but no real harm copying same thing twice.
++ */
+ (*G.message)((zvoid *)&G,
+ (uch *)LoadFarString(ReadError),
+ (ulg)strlen(LoadFarString(ReadError)), 0x401);
+@@ -724,55 +943,142 @@ int seek_zipf(__G__ abs_offset)
+ * "proper offset" (i.e., if there were no extra bytes prepended);
+ * cur_zipfile_bufstart contains the corrected offset.
+ *
+- * Since seek_zipf() is never used during decompression, it is safe to
+- * use the slide[] buffer for the error message.
++ * Because seek_zipf() is never used during decompression, it is safe
++ * to use the slide[] buffer for the error message.
+ *
+ * returns PK error codes:
+ * PK_BADERR if effective offset in zipfile is negative
+ * PK_EOF if seeking past end of zipfile
+ * PK_OK when seek was successful
+ */
+- zoff_t request = abs_offset + G.extra_bytes;
+- zoff_t inbuf_offset = request % INBUFSIZ;
+- zoff_t bufstart = request - inbuf_offset;
+
+- if (request < 0) {
++ zoff_t request;
++ zoff_t inbuf_offset;
++ zoff_t bufstart;
++
++ request = abs_offset + G.extra_bytes;
++
++#if 0 /* Pre-segment-support. */
++ if (request < 0)
++ {
++ Info(slide, 1, ((char *)slide, LoadFarStringSmall(SeekMsg),
++ 2, G.zipfn, LoadFarString(ReportMsg)));
++ return PK_BADERR;
++ }
++#endif /* 0 */ /* Pre-segment-support. */
++
++ while (request < 0)
++ {
++ if (G.sgmnt_size == 0)
++ {
++ if ((G.sgmnt_nr == 0) || open_infile_sgmnt( __G__ -1))
++ {
+ Info(slide, 1, ((char *)slide, LoadFarStringSmall(SeekMsg),
+- G.zipfn, LoadFarString(ReportMsg)));
+- return(PK_BADERR);
+- } else if (bufstart != G.cur_zipfile_bufstart) {
+- Trace((stderr,
+- "fpos_zip: abs_offset = %s, G.extra_bytes = %s\n",
+- FmZofft(abs_offset, NULL, NULL),
+- FmZofft(G.extra_bytes, NULL, NULL)));
++ 3, G.zipfn, LoadFarString(ReportMsg)));
++ return PK_BADERR;
++ }
++ /* Get the new segment size, and calculate the new offset.
++ * This is where G.sgmnt_size gets a real (non-zero) value.
++ */
+ #ifdef USE_STRM_INPUT
+- zfseeko(G.zipfd, bufstart, SEEK_SET);
+- G.cur_zipfile_bufstart = zftello(G.zipfd);
++ zfseeko(G.zipfd, 0, SEEK_END);
++ G.sgmnt_size = zftello(G.zipfd);
+ #else /* !USE_STRM_INPUT */
+- G.cur_zipfile_bufstart = zlseek(G.zipfd, bufstart, SEEK_SET);
+-#endif /* ?USE_STRM_INPUT */
+- Trace((stderr,
+- " request = %s, (abs+extra) = %s, inbuf_offset = %s\n",
+- FmZofft(request, NULL, NULL),
+- FmZofft((abs_offset+G.extra_bytes), NULL, NULL),
+- FmZofft(inbuf_offset, NULL, NULL)));
+- Trace((stderr, " bufstart = %s, cur_zipfile_bufstart = %s\n",
+- FmZofft(bufstart, NULL, NULL),
+- FmZofft(G.cur_zipfile_bufstart, NULL, NULL)));
+- if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+- return(PK_EOF);
+- G.incnt -= (int)inbuf_offset;
+- G.inptr = G.inbuf + (int)inbuf_offset;
+- } else {
+- G.incnt += (G.inptr-G.inbuf) - (int)inbuf_offset;
+- G.inptr = G.inbuf + (int)inbuf_offset;
++ G.sgmnt_size = zlseek(G.zipfd, 0, SEEK_END);
++#endif /* USE_STRM_INPUT */
++ request += G.sgmnt_size;
+ }
+- return(PK_OK);
+-} /* end function seek_zipf() */
+-
++ else
++ {
++ /* SMSd. Can we trust that all segments have the same size? */
++ /* We know segment size(s?), so we can calculate against
++ * abs_offset and sgmnt_nr, and open the segment file which we
++ * actually need.
++ */
++ unsigned int tmp_disk = G.ecrec.number_this_disk;
++
++ while (request < 0)
++ {
++ tmp_disk--;
++ request += G.sgmnt_size;
++ }
++ /* for same as actual disk (movement == 0) return 0 */
++ if (open_infile_sgmnt( __G__ (tmp_disk- G.sgmnt_nr)))
++ {
++ Info(slide, 1, ((char *)slide, LoadFarStringSmall(SeekMsg),
++ 4, G.zipfn, LoadFarString(ReportMsg)));
++ return PK_BADERR;
++ }
++ }
++ /* In both cases we need to refill buffer, so set
++ * G.cur_zipfile_bufstart negative (so that bufstart !=
++ * G.cur_zipfile_bufstart, below).
++ */
++ G.cur_zipfile_bufstart = -1;
++ }
+
++ inbuf_offset = request % INBUFSIZ;
++ bufstart = request - inbuf_offset;
+
++ if (bufstart != G.cur_zipfile_bufstart)
++ {
++ Trace((stderr,
++ "fpos_zip: abs_offset = %s, G.extra_bytes = %s\n",
++ FmZofft(abs_offset, NULL, NULL),
++ FmZofft(G.extra_bytes, NULL, NULL)));
+
++#ifdef USE_STRM_INPUT
++ zfseeko(G.zipfd, bufstart, SEEK_SET);
++ G.cur_zipfile_bufstart = zftello(G.zipfd);
++#else /* def USE_STRM_INPUT */
++ G.cur_zipfile_bufstart = zlseek(G.zipfd, bufstart, SEEK_SET);
++#endif /* def USE_STRM_INPUT [else] */
++
++ Trace((stderr,
++ " request = %s, (abs+extra) = %s, inbuf_offset = %s\n",
++ FmZofft(request, NULL, NULL),
++ FmZofft((abs_offset+G.extra_bytes), NULL, NULL),
++ FmZofft(inbuf_offset, NULL, NULL)));
++ Trace((stderr, " bufstart = %s, cur_zipfile_bufstart = %s\n",
++ FmZofft(bufstart, NULL, NULL),
++ FmZofft(G.cur_zipfile_bufstart, NULL, NULL)));
++
++ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) < INBUFSIZ)
++ {
++ /* If we're not at the end of file, then we need move to the
++ * next segment file.
++ * TODO: Check if EOF, instead?
++ */
++ if (G.ecrec.number_this_disk != G.sgmnt_nr)
++ {
++ int tmp;
++
++ if (open_infile_sgmnt( __G__ 1))
++ return PK_EOF; /*TODO: Add some new return code? */
++
++ /* append rest of data to buffer - it's important when we are only
++ * few bytes before EOF and want read CDR! Now it's more safe.
++ * Only some disk error could be wrong for us in that case.
++ */
++ tmp = read(G.zipfd, (char *)(G.inbuf+ G.incnt), (INBUFSIZ- G.incnt));
++ if (tmp <= 0)
++ return PK_EOF;
++
++ G.incnt += tmp;
++ }
++ else if (G.incnt <= 0)
++ return PK_EOF;
++ }
++ G.incnt -= (int)inbuf_offset;
++ G.inptr = G.inbuf + (int)inbuf_offset;
++ }
++ else
++ {
++ G.incnt += (int)(G.inptr- G.inbuf) - (int)inbuf_offset;
++ G.inptr = G.inbuf + (int)inbuf_offset;
++ }
++ return(PK_OK);
++} /* end function seek_zipf() */
+
+ #ifndef VMS /* for VMS use code in vms.c */
+
+diff --git a/globals.c b/globals.c
+index fa8cca5..9cac035 100644
+--- a/globals.c
++++ b/globals.c
+@@ -198,6 +198,9 @@ Uz_Globs *globalsCtor()
+ G.mpause = UzpMorePause;
+ #endif
+ G.decr_passwd = UzpPassword;
++ G.zipfn_sgmnt = NULL; /* Archive segment name */
++ G.zipfn_sgmnt_size = 0; /* Archive segment size */
++ G.zipfd_sgmnt = ZIPFD_INVALID; /* Archive segment file descr/pntr */
+ #endif /* !FUNZIP */
+
+ #if (!defined(DOS_FLX_H68_NLM_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
+diff --git a/globals.h b/globals.h
+index 11b7215..0a84432 100644
+--- a/globals.h
++++ b/globals.h
+@@ -243,12 +243,13 @@ typedef struct Globals {
+ int zipeof;
+ char *argv0; /* used for NT and EXE_EXTENSION */
+ char *wildzipfn;
+- char *zipfn; /* GRR: WINDLL: must nuke any malloc'd zipfn... */
+-#ifdef USE_STRM_INPUT
+- FILE *zipfd; /* zipfile file descriptor */
+-#else
+- int zipfd; /* zipfile file handle */
+-#endif
++ char *zipfn; /* zipfile path/name */
++ char *zipfn_sgmnt; /* zipfile segment path/name */
++ int zipfn_sgmnt_size; /* zipfile segment path/name size */
++ zuvl_t sgmnt_nr; /* zipfile segment number */
++ zoff_t sgmnt_size; /* zipfile segment size */
++ zipfd_t zipfd; /* zipfile primary file descr/pointer */
++ zipfd_t zipfd_sgmnt; /* zipfile segment file descr/pointer */
+ zoff_t ziplen;
+ zoff_t cur_zipfile_bufstart; /* extract_or_test, readbuf, ReadByte */
+ zoff_t extra_bytes; /* used in unzip.c, misc.c */
+@@ -306,7 +307,8 @@ typedef struct Globals {
+ char *unipath_filename; /* UTF-8 path */
+ #endif /* UNICODE_SUPPORT */
+
+-#ifdef CMS_MVS
++# ifdef CMS_MVS_INFILE_TMP
++ /* 2015-03-17 SMS. See note in zos/vmmvs.c. */
+ char *tempfn; /* temp file used; erase on close */
+ #endif
+
+diff --git a/process.c b/process.c
+index 0d57ab4..76652a9 100644
+--- a/process.c
++++ b/process.c
+@@ -726,8 +726,10 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+ return PK_ERR;
+ #endif
+
+- if (open_input_file(__G)) /* this should never happen, given */
+- return PK_NOZIP; /* the stat() test above, but... */
++ if (open_infile(__G__ OIF_PRIMARY))
++ { /* This should never fail, given the stat() test above, but... */
++ return PK_NOZIP;
++ }
+
+ #ifdef DO_SAFECHECK_2GB
+ /* Need more care: Do not trust the size returned by stat() but
+@@ -740,7 +742,7 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+ printf(
+ " We need a better error message for: 64-bit file, 32-bit program.\n");
+ */
+- CLOSE_INFILE();
++ CLOSE_INFILE( &G.zipfd);
+ return IZ_ERRBF;
+ }
+ #endif /* DO_SAFECHECK_2GB */
+@@ -755,6 +757,7 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+
+ G.cur_zipfile_bufstart = 0;
+ G.inptr = G.inbuf;
++ G.sgmnt_size = 0; /* Init before ECREC for each archive in the list. */
+
+ #if ((!defined(WINDLL) && !defined(SFX)) || !defined(NO_ZIPINFO))
+ # if (!defined(WINDLL) && !defined(SFX))
+@@ -785,7 +788,7 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+ MIN(G.ziplen, 66000L)))
+ > PK_WARN )
+ {
+- CLOSE_INFILE();
++ CLOSE_INFILE( &G.zipfd);
+
+ #ifdef SFX
+ ++lastchance; /* avoid picky compiler warnings */
+@@ -804,7 +807,7 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+ }
+
+ if ((uO.zflag > 0) && !uO.zipinfo_mode) { /* unzip: zflag = comment ONLY */
+- CLOSE_INFILE();
++ CLOSE_INFILE( &G.zipfd);
+ return error_in_archive;
+ }
+
+@@ -892,10 +895,13 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+ else
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileEmpty),
+ G.zipfn));
+- CLOSE_INFILE();
++ CLOSE_INFILE( &G.zipfd);
+ return (error_in_archive > PK_WARN)? error_in_archive : PK_WARN;
+ }
+
++ /* Set the segment number (needed for segmented archives). */
++ G.sgmnt_nr = G.ecrec.number_this_disk;
++
+ /*-----------------------------------------------------------------------
+ Compensate for missing or extra bytes, and seek to where the start
+ of central directory should be. If header not found, uncompensate
+@@ -905,12 +911,12 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+
+ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+ if (error == PK_BADERR) {
+- CLOSE_INFILE();
++ CLOSE_INFILE( &G.zipfd);
+ return PK_BADERR;
+ }
+ #ifdef OLD_SEEK_TEST
+ if (error != PK_OK || readbuf(__G__ G.sig, 4) == 0) {
+- CLOSE_INFILE();
++ CLOSE_INFILE( &G.zipfd);
+ return PK_ERR; /* file may be locked, or possibly disk error(?) */
+ }
+ if (memcmp(G.sig, central_hdr_sig, 4))
+@@ -932,7 +938,7 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CentDirStartNotFound), G.zipfn,
+ LoadFarStringSmall(ReportMsg)));
+- CLOSE_INFILE();
++ CLOSE_INFILE( &G.zipfd);
+ return (error != PK_OK ? error : PK_BADERR);
+ }
+ #ifndef SFX
+@@ -950,7 +956,7 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+
+ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+ if (error != PK_OK) {
+- CLOSE_INFILE();
++ CLOSE_INFILE( &G.zipfd);
+ return error;
+ }
+
+@@ -996,7 +1002,7 @@ static int do_seekable(__G__ lastchance) /* return PK-type error code */
+ } /* end if (!too_weird_to_continue) */
+ #endif
+
+- CLOSE_INFILE();
++ CLOSE_INFILE( &G.zipfd);
+
+ #ifdef TIMESTAMP
+ if (uO.T_flag && !uO.zipinfo_mode && (nmember > 0L)) {
+diff --git a/unix/Makefile b/unix/Makefile
+index ab32270..783f261 100644
+--- a/unix/Makefile
++++ b/unix/Makefile
+@@ -47,7 +47,7 @@ LD = $(CC)# must match, else "unresolved symbol: ___main" is possible)
+ AS = as
+ LOC = $(D_USE_BZ2) $(LOCAL_UNZIP)
+ AF = $(LOC)
+-CFLAGS = -O
++CFLAGS = -O0
+ CF_NOOPT = -I. -I$(IZ_BZIP2) -DUNIX $(LOC)
+ CF = $(CFLAGS) $(CF_NOOPT)
+ LFLAGS1 =
+@@ -594,12 +594,12 @@ generic_shlib: unix_make
+ @echo\
+ 'which is UnZip linked with the DLL). This target is an example only.'
+ @echo ""
+- $(MAKE) objsdll CC=gcc CFLAGS="-O3 -Wall -fPIC -DDLL"
++ $(MAKE) objsdll CC=gcc CFLAGS="-O0 -Wall -fPIC -DDLL"
+ gcc -shared -Wl,-soname,libunzip.so.0 -o libunzip.so.0.4 $(OBJSDLL)
+ $(RM) libunzip.so.0 libunzip.so
+ $(LN) -s libunzip.so.0.4 libunzip.so.0
+ $(LN) -s libunzip.so.0 libunzip.so
+- gcc -c -O unzipstb.c
++ gcc -c -O0 unzipstb.c
+ gcc -o unzip_shlib unzipstb.o -L. -lunzip
+
+ #----------------------------------------------------------------------------
+@@ -694,7 +694,7 @@ _v7:
+ $(MAKE) unzips CF="$(CF) -DNO_DIR -DNO_MKDIR -DNO_STRNICMP -DNO_UID_GID -DNO_FCHMOD -DNO_LCHOWN -DNO_LCHMOD -DCBREAK=2"
+
+ 7300_gcc: unix_make
+- $(MAKE) unzips CC=gcc LD=gcc LF2="" CFLAGS="-O2" \
++ $(MAKE) unzips CC=gcc LD=gcc LF2="" CFLAGS="-O0" \
+ LOC="-DNO_DIR -DNO_MKDIR -DNO_STDLIB_H -DNO_STRNICMP -DNO_UID_GID -DNO_FCHMOD -DNO_LCHOWN -DNO_LCHMOD -DCBREAK=2 $(LOC)"
+ $(STRIP) $(UNZIPS)
+
+@@ -717,13 +717,13 @@ apollo: unix_make
+ bsdi: unix_make
+ @echo 'NOTE: use bsdi_noasm target for non-Intel BSD/OS compiles.'
+ $(MAKE) unzips CC=gcc2 LD=shlicc2 AS=gcc2\
+- CFLAGS="-O3 -Wall -DASM_CRC -DBSD" CRCA_O=crc_gcc$O
++ CFLAGS="-O0 -Wall -DASM_CRC -DBSD" CRCA_O=crc_gcc$O
+
+ # BSDI BSD/OS
+ bsdi_noasm: unix_make
+ # @echo 'NOTE: use bsd target for non-Intel BSD/OS compiles.'
+ $(MAKE) unzips CC=gcc2 LD=shlicc2 AS=gcc2\
+- CFLAGS="-O3 -Wall -DBSD"
++ CFLAGS="-O0 -Wall -DBSD"
+
+ # Coherent 3.x/4.x, Mark Williams C. ``For Coherent's CC, it needs either
+ # -T0 or -T150000 (or bigger) added to the CFLAGS, otherwise the compiler
+@@ -747,7 +747,7 @@ cyber_sgi: unix_make
+ # Info-ZIP recommends using "win32/Makefile.gcc" instead.
+ cygwin: unix_make
+ $(MAKE) unzips CC=gcc LD=gcc AS=gcc\
+- CFLAGS="-O3 -DASM_CRC -DNO_LCHOWN -DNO_LCHMOD"\
++ CFLAGS="-O0 -DASM_CRC -DNO_LCHOWN -DNO_LCHMOD"\
+ AF="-Di386 $(AF)" CRCA_O=crc_gcc$O\
+ E=".exe" CP="cp" LN="ln -s"
+
+@@ -764,7 +764,7 @@ dnix: unix_make
+ freebsd: unix_make
+ @echo 'NOTE: use bsd target for non-Intel FreeBSD compiles (if any).'
+ $(MAKE) unzips CC=gcc LD=gcc AS=gcc\
+- CFLAGS="-O3 -Wall -DASM_CRC -DBSD"\
++ CFLAGS="-O0 -Wall -DASM_CRC -DBSD"\
+ AF="-Di386 $(AF)" CRCA_O=crc_gcc$O
+
+ # Generic BSDish Unix gcc. ``The -O3 only works with later versions of gcc;
+@@ -775,7 +775,7 @@ freebsd: unix_make
+ # with "echo" instead).
+ #
+ gcc: unix_make
+- $(MAKE) unzips CC=gcc LD=gcc CFLAGS="-O3" LF2=""
++ $(MAKE) unzips CC=gcc LD=gcc CFLAGS="-O0" LF2=""
+ $(STRIP) $(UNZIPS)
+
+ # Heurikon HK68 (68010), UniPlus+ System V 5.0, Green Hills C-68000
+@@ -787,13 +787,13 @@ hk68: unix_make
+ # ISC Unix on 386 platform
+ isc: unix_make
+ $(MAKE) unzips LF2="-lc_s $(LF2)" CRCA_O=crc_sysv$O \
+- CFLAGS="-O" LOC="-DASM_CRC -DSYSV -DNO_UID_GID -DNEED_PTEM -DNO_LCHOWN -DNO_LCHMOD $(LOC)" \
++ CFLAGS="-O0" LOC="-DASM_CRC -DSYSV -DNO_UID_GID -DNEED_PTEM -DNO_LCHOWN -DNO_LCHMOD $(LOC)" \
+ AF="-DNO_UNDERLINE -Djecxz=jcxz -DALIGNMENT='.align 16' $(AF)"
+
+ isc_gcc: unix_make
+ $(MAKE) unzips AS=gcc CC=gcc LD=gcc CRCA_O=crc_gcc$O \
+ LF="-shlib $(LF)" SL="-shlib $(SL)" FL="-shlib $(FL)" LF2="" \
+- CFLAGS="-O3" LOC="-DSYSV -DASM_CRC -DNO_UID_GID -DNEED_PTEM -DNO_LCHOWN -DNO_LCHMOD $(LOC)" \
++ CFLAGS="-O0" LOC="-DSYSV -DASM_CRC -DNO_UID_GID -DNEED_PTEM -DNO_LCHOWN -DNO_LCHMOD $(LOC)" \
+ AF="-DNO_UNDERLINE -Djecxz=jcxz -DALIGNMENT='.align 16' $(AF)"
+ $(STRIP) $(UNZIPS)
+
+@@ -809,7 +809,7 @@ isi: unix_make
+ linux: unix_make
+ @echo 'NOTE: use linux_noasm target for non-Intel Linux compiles.'
+ $(MAKE) unzips CC=gcc LD=gcc AS=gcc\
+- CFLAGS="-O3 -Wall -DASM_CRC"\
++ CFLAGS="-O0 -Wall -DASM_CRC"\
+ AF="-Di386 $(AF)" CRCA_O=crc_gcc$O
+ # GRR: this echo is pointless; if user gets this far, no difference to install
+ # @echo 'Be sure to use the install_asm target rather than the install target'
+@@ -819,19 +819,19 @@ linux_asm: linux
+ # Linux (Posix, approximately SysV): virtually any version since before 0.96,
+ # for any platform. Change "-O" to "-O3" or whatever, as desired...
+ linux_noasm: unix_make
+- $(MAKE) unzips CC=gcc LD=gcc CFLAGS="-O -Wall"
++ $(MAKE) unzips CC=gcc LD=gcc CFLAGS="-O0 -Wall"
+
+ # Linux with lcc compiler: __inline__ (stat.h) not recognized, and must edit
+ # /usr/include/gnu/types.h to get rid of "long long" if __LCC__ defined. -O3
+ # (or -O2 or -O) is ignored. [GRR 960828: test target only]
+ #
+ linux_lcc: unix_make
+- $(MAKE) unzips CC=lcc LD=lcc CFLAGS="-O3 -Wall -D__inline__= "
++ $(MAKE) unzips CC=lcc LD=lcc CFLAGS="-O0 -Wall -D__inline__= "
+
+ # Linux host with go32 (djgpp) cross-compiler (go32crs.tgz) for 32-bit DOS.
+ linux_dos: unix_make
+ $(MAKE) unzips CC=go32gcc LD=go32gcc M=msdos OSDEP_H="msdos/doscfg.h" \
+- CFLAGS="-O2 -Wall"
++ CFLAGS="-O0 -Wall"
+ # go32-strip unzip
+ # Due to limitations of the cross-compiling package, this has to be
+ # done manually:
+@@ -845,25 +845,25 @@ linux_dos: unix_make
+ # library).
+ #
+ linux_shlib: unix_make
+- $(MAKE) objsdll CC=gcc CFLAGS="-O3 -Wall -fPIC"\
++ $(MAKE) objsdll CC=gcc CFLAGS="-O0 -Wall -fPIC"\
+ LOC="-DDLL -DASM_CRC $(LOC)"\
+ AS=gcc AF="-fPIC -Di386 $(AF)" CRCA_O=crc_gcc$O
+ gcc -shared -Wl,-soname,libunzip.so.0 -o libunzip.so.0.4 $(OBJSDLL)\
+ crc_gcc.pic.o
+ ln -sf libunzip.so.0.4 libunzip.so.0
+ ln -sf libunzip.so.0 libunzip.so
+- gcc -c -O unzipstb.c
++ gcc -c -O0 unzipstb.c
+ gcc -o unzip_shlib unzipstb.o -L. -lunzip
+
+ # Linux ELF shared library, as above, but using inflate() from zlib (libz.so)
+ # instead of the original UnZip version. (libz was libgz prior to 0.94)
+ linux_shlibz: unix_make
+ $(MAKE) objsdll CC=gcc AS=gcc AF="-fPIC -Di386 $(AF)" CRCA_O=crc_gcc$O\
+- CFLAGS="-O3 -Wall -fPIC" LOC="-DDLL -DUSE_ZLIB -DASM_CRC $(LOC)"
++ CFLAGS="-O0 -Wall -fPIC" LOC="-DDLL -DUSE_ZLIB -DASM_CRC $(LOC)"
+ gcc -shared -Wl,-soname,libunzip.so.0 -o libunzip.so.0.4 $(OBJSDLL)\
+ crc_gcc.pic.o
+ ln -sf libunzip.so.0.4 libunzip.so.0
+- gcc -c -O unzipstb.c
++ gcc -c -O0 unzipstb.c
+ gcc -o unzip unzipstb.o -L. -lunzip -lz
+
+ # LynxOS-x86 2.3.0 and newer, a real-time BSD-like OS; uses gcc.
+@@ -872,12 +872,12 @@ lynx: unix_make
+
+ # Macintosh MacOS X (Unix-compatible enviroment), using standard compiler
+ macosx: unix_make
+- $(MAKE) unzips CFLAGS="-O3 -Wall -DBSD" LF2=""
++ $(MAKE) unzips CFLAGS="-O0 -Wall -DBSD" LF2=""
+ $(STRIP) $(UNZIPS)
+
+ # Macintosh MacOS X (Unix-compatible enviroment), using gcc
+ macosx_gcc: unix_make
+- $(MAKE) unzips CC=gcc CFLAGS="-O3 -Wall -DBSD" LF2=""
++ $(MAKE) unzips CC=gcc CFLAGS="-O0 -Wall -DBSD" LF2=""
+ $(STRIP) $(UNZIPS)
+
+ # Minix 1.5 PC for the 386. Invoke as is to use default cc, or as "make
+@@ -914,12 +914,12 @@ next2x: unix_make
+
+ # NeXT 3.x: as above, plus better optimization.
+ next3x: unix_make
+- $(MAKE) unzips CFLAGS="-O2" LF2="-object -s"
++ $(MAKE) unzips CFLAGS="-O0" LF2="-object -s"
+
+ # NeXT 3.1+: make the executable fat (multi-architecture binary [MAB],
+ # for "black" [NeXT] and "white" [x86] hardware, so far).
+ nextfat: unix_make
+- $(MAKE) unzips CFLAGS="-O2 -arch i386 -arch m68k" \
++ $(MAKE) unzips CFLAGS="-O0 -arch i386 -arch m68k" \
+ LF2="-arch i386 -arch m68k -object -s"
+
+ # IBM OS/390 (formerly MVS) compiled under "OpenEdition" shell
+@@ -972,7 +972,7 @@ rs6000: unix_make
+ # recognize the -M0 flag that forces 8086 code.) (GRR: may need to reduce
+ # stack to 0c00h if using 286/small-model code...?)
+ sco_dos: unix_make
+- $(MAKE) unzips CFLAGS="-O -dos -M0" M=msdos OSDEP_H="msdos/doscfg.h" \
++ $(MAKE) unzips CFLAGS="-O0 -dos -M0" M=msdos OSDEP_H="msdos/doscfg.h" \
+ LF="-dos -F 2000" LF2="-o unzip.exe" \
+ FL="-dos" FL2="-o funzip.exe" SL="-dos" SL2="-o unzipsfx.exe"
+
+@@ -1000,7 +1000,7 @@ sunos3: unix_make
+
+ # Generic System V + GNU C
+ sysv_gcc: unix_make
+- $(MAKE) unzips CC=gcc LD=gcc CFLAGS="-O2 -DSYSV" LF2=""
++ $(MAKE) unzips CC=gcc LD=gcc CFLAGS="-O0 -DSYSV" LF2=""
+ $(STRIP) $(UNZIPS)
+
+ # AT&T 6300+, System V.2 Unix: run-time out-of-memory error if don't use -Ml;
+diff --git a/unix/configure b/unix/configure
+index 3c2d353..f981836 100755
+--- a/unix/configure
++++ b/unix/configure
+@@ -70,7 +70,7 @@ int main()
+ _EOF_
+ $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+- CFLAGS_OPT='-O3'
++ CFLAGS_OPT='-O0'
+ echo " DEC C ($CFLAGS_OPT)"
+ else
+ # HP-UX HP C?
+@@ -111,7 +111,7 @@ int main()
+ _EOF_
+ $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+- CFLAGS_OPT='-O3'
++ CFLAGS_OPT='-O0'
+ echo " GNU C ($CFLAGS_OPT)"
+ # Special Mac OS X shared library "ld" option?
+ if test ` uname -s 2> /dev/null ` = 'Darwin'; then
+@@ -123,7 +123,7 @@ _EOF_
+ rm -f conftest
+ fi
+ else
+- CFLAGS_OPT='-O'
++ CFLAGS_OPT='-O0'
+ echo " Other-unknown C ($CFLAGS_OPT)"
+ fi
+ fi
+@@ -662,8 +662,8 @@ _EOF_
+ fi
+
+
+-echo CC=\"${CC}\" CF=\"${CFLAGSR} ${D_USE_BZ2}\" CRCA_O=\"${CRC32OA}\" \
+- AS=\"${CC} -c\" LFLAGS1=\"${LFLAGS1}\" LF2=\"${LFLAGS2}\" \
+- CC_BZ=\"${CC_BZ}\" CFLAGS_BZ=\"${CFLAGS_BZ}\" \
++echo CC=\"${CC}\" CF=\"${CFLAGSR} ${D_USE_BZ2} -ggdb3 -O0\" CRCA_O=\"${CRC32OA}\" \
++ AS=\"${CC} -c\" LFLAGS1=\"${LFLAGS1} -ggdb3 -O0 \" LF2=\"${LFLAGS2} -ggdb3 -O0 \" \
++ CC_BZ=\"${CC_BZ}\" CFLAGS_BZ=\"${CFLAGS_BZ} -ggdb3 -O0 \" \
+ IZ_BZIP2=\"${IZ_BZIP2}\" D_USE_BZ2=\"${D_USE_BZ2}\" \
+ L_BZ2=\"${L_BZ2}\" LIBBZ2=\"${LIBBZ2}\" > flags
+diff --git a/unzpriv.h b/unzpriv.h
+index 5c83a6e..22ef1eb 100644
+--- a/unzpriv.h
++++ b/unzpriv.h
+@@ -567,7 +567,6 @@
+
+ #ifdef CMS_MVS
+ # include "vmmvs.h"
+-# define CLOSE_INFILE() close_infile(__G)
+ #endif
+
+ /*---------------------------------------------------------------------------
+@@ -669,8 +668,10 @@
+ typedef unsigned int extent;
+ #endif /* ?MODERN */
+
+-
+-
++/* compatible macros with upstream */
++# define izu_free free
++# define izu_malloc malloc
++# define izu_realloc realloc
+
+ /*************/
+ /* Defines */
+@@ -768,7 +769,7 @@
+ # define DATE_SEPCHAR '-'
+ #endif
+ #ifndef CLOSE_INFILE
+-# define CLOSE_INFILE() close(G.zipfd)
++# define CLOSE_INFILE( pfd) close_infile(__G__ pfd)
+ #endif
+ #ifndef RETURN
+ # define RETURN return /* only used in main() */
+@@ -1661,6 +1662,10 @@
+ #define GETPATH 4 /* retrieve the complete path and free it */
+ #define END 5 /* free root path prior to exiting program */
+
++/* Input archive file options for fileio.c:open_infile(). */
++#define OIF_PRIMARY 0 /* Primary archive (".zip") file. */
++#define OIF_SEGMENT 1 /* Segment archive (".zXX") file. */
++
+ /* version_made_by codes (central dir): make sure these */
+ /* are not defined on their respective systems!! */
+ #define FS_FAT_ 0 /* filesystem used by MS-DOS, OS/2, Win32 */
+@@ -1977,6 +1982,14 @@
+ # endif
+ #endif
+
++ /* Archive file descriptor/pointer. */
++#ifdef USE_STRM_INPUT
++ typedef FILE *zipfd_t; /* Stdio file pointer. */
++#else /* def USE_STRM_INPUT */
++ typedef int zipfd_t; /* UNIX I/O file descriptor. */
++#endif /* def USE_STRM_INPUT */
++
++
+ #if (defined(GOT_UTIMBUF) || defined(sgi) || defined(ATARI))
+ typedef struct utimbuf ztimbuf;
+ #else
+@@ -2305,8 +2318,10 @@ void fnprint OF((__GPRO));
+ Functions in fileio.c:
+ ---------------------------------------------------------------------------*/
+
+-int open_input_file OF((__GPRO));
++int close_infile OF((__GPRO__ zipfd_t *pfd));
++int open_infile OF((__GPRO__ int which));
+ int open_outfile OF((__GPRO)); /* also vms.c */
++int set_zipfn_sgmnt_name OF((__GPRO__ zuvl_t sgmnt_nr));
+ void undefer_input OF((__GPRO));
+ void defer_leftover_input OF((__GPRO));
+ unsigned readbuf OF((__GPRO__ char *buf, register unsigned len));
+@@ -2525,8 +2540,10 @@ int huft_build OF((__GPRO__ ZCONST unsigned *b, unsigned n,
+
+ #ifdef CMS_MVS
+ extent getVMMVSexfield OF((char *type, uch *ef_block, unsigned datalen));
+- FILE *vmmvs_open_infile OF((__GPRO)); /* vmmvs.c */
++ FILE *vmmvs_open_infile OF((__GPRO__ char *fn)); /* vmmvs.c */
++#if 0
+ void close_infile OF((__GPRO)); /* vmmvs.c */
++#endif /* 0 */
+ #endif
+
+ /*---------------------------------------------------------------------------
+@@ -2548,6 +2565,9 @@ int huft_build OF((__GPRO__ ZCONST unsigned *b, unsigned n,
+ ulg vms_unzip_cmdline OF((int *, char ***)); /* cmdline.c */
+ int VMSCLI_usage OF((__GPRO__ int error)); /* cmdline.c */
+ #endif
++ int vms_sgmnt_name OF((char *fn_sgmnt, /* vms.c */
++ char *fn_primary,
++ zuvl_t nr_sgmnt));
+ #endif
+
+ /*---------------------------------------------------------------------------
+@@ -2645,12 +2665,8 @@ char *GetLoadPath OF((__GPRO)); /* local */
+ /* Macros */
+ /************/
+
+-#ifndef MAX
+-# define MAX(a,b) ((a) > (b) ? (a) : (b))
+-#endif
+-#ifndef MIN
+-# define MIN(a,b) ((a) < (b) ? (a) : (b))
+-#endif
++#define IZ_MAX( a, b) ((a) > (b) ? (a) : (b))
++#define IZ_MIN( a, b) ((a) < (b) ? (a) : (b))
+
+ #ifdef DEBUG
+ # if (defined(THEOS) && defined(NO_BOGUS_SPC))
+@@ -2685,13 +2701,22 @@ char *GetLoadPath OF((__GPRO)); /* local */
+ /* ``Replace'' the unbuffered UNIX style I/O function with similar
+ * standard C functions from <stdio.h>.
+ */
+-# define read(fd,buf,n) fread((buf),1,(n),(FILE *)(fd))
+-# ifdef zlseek
+-# undef zlseek
+-# endif
+-# define zlseek(fd,o,w) zfseeko((FILE *)(fd),(o),(w))
+-# define close(fd) fclose((FILE *)(fd))
+-#endif /* USE_STRM_INPUT */
++# define read(fd,buf,n) fread((buf),1,(n),(FILE *)(fd))
++# ifdef zlseek
++# undef zlseek
++# endif
++# define zlseek(fd,o,w) zfseeko((FILE *)(fd),(o),(w))
++# define close(fd) fclose((FILE *)(fd))
++# define fd_is_valid(fd) (fd != NULL)
++# define ZIPFD_INVALID NULL
++#else /* def USE_STRM_INPUT */
++# ifdef _WIN32_WCE /* Really necessary? */
++# define fd_is_valid(fd) (fd != -1)
++# else /* def _WIN32_WCE [else] */
++# define fd_is_valid(fd) (fd >= 0)
++# endif /* def _WIN32_WCE [else] */
++# define ZIPFD_INVALID (-1)
++#endif /* def USE_STRM_INPUT [else] */
+
+ /* The return value of the Info() "macro function" is never checked in
+ * UnZip. Otherwise, to get the same behaviour as for (*G.message)(), the
+diff --git a/vms/vms.c b/vms/vms.c
+index d826174..a57f1d7 100644
+--- a/vms/vms.c
++++ b/vms/vms.c
+@@ -1,5 +1,5 @@
+ /*
+- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
++ Copyright (c) 1990-2015 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+@@ -34,6 +34,7 @@
+ screensize()
+ screenlinewrap()
+ version()
++ vms_sgmnt_name()
+
+ ---------------------------------------------------------------------------*/
+
+@@ -581,6 +582,59 @@ int open_outfile(__G)
+ }
+ }
+
++/* vms_sgmnt_name()
++ *
++ * Derive an archive segment file spec from an archive primary file
++ * spec and the desired segment number. File specs are VMS-style.
++ * Returns sys$parse() status, with expanded file spec in user's
++ * storage.
++ */
++int vms_sgmnt_name( char *fn_sgmnt, char *fn_primary, zuvl_t nr_sgmnt)
++{
++ int sts;
++ char sgmnt_type[ 16];
++
++ struct FAB fab;
++ struct NAMX_STRUCT nam;
++ char e_name[ NAMX_MAXRSS + 1];
++
++ fab = cc$rms_fab; /* Initialize FAB. */
++ nam = CC_RMS_NAMX; /* Initialize NAM[L]. */
++ fab.FAB_NAMX = &nam; /* Point FAB to NAM[L]. */
++
++ /* Form a ".zXX;" type string and version from the segment number. */
++ sprintf( sgmnt_type, ".z%02u;", nr_sgmnt);
++
++ NAMX_DNA_FNA_SET( fab)
++
++ /* Use the primary archive name as the default file spec. */
++ FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNA = fn_primary;
++ FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNS = strlen( fn_primary);
++
++ /* Use the segment type and version as the normal file spec. */
++ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = sgmnt_type;
++ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen( sgmnt_type);
++
++ nam.NAMX_ESA = e_name;
++ nam.NAMX_ESS = sizeof( e_name)- 1;
++
++ nam.NAMX_NOP = NAMX_M_SYNCHK; /* Syntax-only analysis. */
++ sts = sys$parse( &fab);
++ if ((sts & STS$M_SUCCESS) == STS$K_SUCCESS)
++ {
++ /* Save (NUL-terminated) result in user's storage. */
++ e_name[ nam.NAMX_ESL] = '\0';
++ strncpy( fn_sgmnt, nam.NAMX_ESA, (nam.NAMX_ESL+ 1));
++ }
++ else
++ {
++ fn_sgmnt[0] = '\0';
++ }
++
++ return sts;
++} /* vms_sgmnt_name(). */
++
++
+ static void init_buf_ring()
+ {
+ locptr = &locbuf[0];
diff --git a/unzip.spec b/unzip.spec
index 4e723c5..2c5f2aa 100644
--- a/unzip.spec
+++ b/unzip.spec
@@ -1,7 +1,7 @@
Summary: A utility for unpacking zip files
Name: unzip
Version: 6.0
-Release: 21%{?dist}
+Release: 22%{?dist}
License: BSD
Group: Applications/Archiving
Source: http://downloads.sourceforge.net/infozip/unzip60.tar.gz
@@ -36,6 +36,7 @@ Patch14: unzip-6.0-cve-2014-8139.patch
Patch15: unzip-6.0-cve-2014-8140.patch
Patch16: unzip-6.0-cve-2014-8141.patch
Patch17: unzip-6.0-overflow-long-fsize.patch
+Patch18: unzip-sgmnt-rfe.patch
URL: http://www.info-zip.org/UnZip.html
BuildRequires: bzip2-devel
@@ -69,6 +70,7 @@ a zip archive.
%patch15 -p1 -b .cve-2014-8140
%patch16 -p1 -b .cve-2014-8141
%patch17 -p1 -b .overflow-long-fsize
+%patch18 -p1 -b .segmented
%build
# IZ_HAVE_UXUIDGID is needed for right functionality of unzip -X
@@ -87,6 +89,9 @@ make -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} MANDIR=$RPM_BUILD_ROOT/%{
%{_mandir}/*/*
%changelog
+* Wed Mar 25 2015 Petr Stodulka <pstodulk at redhat.com> - 6.0-22
+- applied alpha patch for support of segmented archives
+
* Sat Feb 21 2015 Till Maas <opensource at till.name> - 6.0-21
- Rebuilt for Fedora 23 Change
https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code
--
cgit v0.10.2
http://pkgs.fedoraproject.org/cgit/unzip.git/commit/?h=pstodulk_segment&id=53b4bd8b698f28aaf185c2d2d51ffae90f7723ba
--
You received this message due to your preference settings at
https://apps.fedoraproject.org/notifications//fmnscmcommits.id.fedoraproject.org/email/29390
More information about the scm-commits
mailing list