diff --git a/cmsmvs/vmmvs.c b/cmsmvs/vmmvs.c
index 8416ce8..f5bf356 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..37850a7 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;
@@ -1072,7 +1137,7 @@ static int extract_or_test_entrylist(__G__ numchunk,
(long)bufstart, (long)G.cur_zipfile_bufstart));
if (request < 0) {
Info(slide, 0x401, ((char *)slide, LoadFarStringSmall(SeekMsg),
- G.zipfn, LoadFarString(ReportMsg)));
+ G.zipfn, 1, LoadFarString(ReportMsg)));
error_in_archive = PK_ERR;
if (*pfilnum == 1 && G.extra_bytes != 0L) {
Info(slide, 0x401, ((char *)slide,
@@ -1093,7 +1158,7 @@ static int extract_or_test_entrylist(__G__ numchunk,
"debug: recompensated request still < 0\n"));
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall(SeekMsg),
- G.zipfn, LoadFarString(ReportMsg)));
+ G.zipfn, 2,LoadFarString(ReportMsg)));
error_in_archive = PK_BADERR;
continue;
}
diff --git a/fileio.c b/fileio.c
index 2a61a30..5a47b0a 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),
+ G.zipfn, 11, 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)));
+ G.zipfn, 12, 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),
+ G.zipfn, 13, 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/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];