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