home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
zip
/
zipot11.arc
/
ZIPOT.C
< prev
next >
Wrap
Text File
|
1989-02-25
|
6KB
|
247 lines
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>
#include <dos.h>
#include "zip.h"
/****************************************************************************
* *
* zipot - change time stamp of ZIP file to be same as its latest contents *
* *
* Initial release : Feb 19, 1989 Russ Herman *
* Revision 1.1 : Feb 25, 1989 *
* Error in time calculation *
* *
****************************************************************************/
#define BUFLEN 512
char buf[BUFLEN]; /* place to read in file */
long buf0_off; /* file offset corresponding to buf */
unsigned buflen; /* size of the buffer */
unsigned bufgood; /* amount of valid info in buffer */
#ifdef DEBUG
#define REG
#else
#define REG register
#endif
/* prototypes */
long find_cdt(int);
int otzip(char *);
void main(int, char **);
/* rummage backwards thru the file looking for the trailer signature */
long find_cdt(int zip_handle)
{
REG char *p;
REG int i;
int front = 0;
bufgood = buflen;
while (buf0_off >= 0 && !front)
{
front = (buf0_off == 0);
if (buf0_off < BUFLEN)
{ /* short block */
bufgood = (unsigned) buf0_off; /* words to read */
buf0_off = 0L; /* position in file */
}
/* position to start of block */
if (lseek(zip_handle, buf0_off, 0) < 0L)
{
perror("cannot position ZIPfile");
return(-2l);
}
/* read some */
if (read(zip_handle, buf, bufgood) < 0)
{
perror("error reading ZIPfile");
return(-3L);
}
/* step backwards thru what we just read */
for(i=bufgood-4,p=&buf[bufgood-4]; i>=0; i--,p--)
{
if (*(unsigned long *)p == CDT_SIG)
return(buf0_off + i); /* exit on signature match */
}
/* We reread the first 4 bytes of each block as a quick&dirty way of *
* handling the case where the signature splits our buffer block */
buf0_off = buf0_off - bufgood + 4;
}
return(-1L); /* Couldn't find signature */
}
/* Process a single ZIPfile */
int otzip(char *fname)
{
int zip_handle;
int i, ret, later;
unsigned early_date, early_time;
long next_cdh;
long cdt_f_off;
long zip_fsize;
CDH *cdhp, cdh;
CDT *cdtp, cdt;
#ifdef __TURBOC__
union REGS tregs;
#endif
early_date = 0;
early_time = 0;
/* open the file */
if ((zip_handle=open(fname, O_RDONLY+O_BINARY)) < 1)
{
perror(fname);
return(97);
}
/* go to EOF */
if ((zip_fsize=lseek(zip_handle, 0l, 2)) < 0L)
{
perror("cannot get to ZIPfile EOF");
close(zip_handle);
return(98);
}
if (zip_fsize < (long) BUFLEN)
buf0_off = 0;
else
buf0_off = zip_fsize - buflen;
/* look for an "end of central directory record" (cdt) */
if ((cdt_f_off=find_cdt(zip_handle)) < 0)
{
if (cdt_f_off == -1L)
{
fprintf(stderr, "%s: not a ZIPfile\n", fname);
close(zip_handle);
return(97);
}
else
{
fprintf(stderr, "find_cdt code %d finding ZIPfile central directory\n",
(int) -cdt_f_off);
close(zip_handle);
return(99);
}
}
/* reread the cdt to make sure we get it all */
i = (lseek(zip_handle, cdt_f_off, 0) >= 0L);
if (i)
i = (read(zip_handle, (char *)&cdt, sizeof(cdt)-2) > 0);
if (!i)
{
perror("error rereading ZIPfile cdt");
close(zip_handle);
return(96);
}
#ifdef DEBUG
printf("%lx sig %08lx dno %u dno_cdh %u cnt_here %u cnt_all %u\n",
cdt_f_off, cdt.sig, cdt.dno, cdt.dno_cdh,
cdt.cnt_here, cdt.cnt_all);
printf("\tcd_size %lu cd_off %lu cmnt_len %u\n",
cdt.cd_size, cdt.cd_off, cdt.cmnt_len);
#endif
if (cdt.dno != 0 || cdt.dno_cdh != 0)
{
fprintf(stderr, "multivolume ZIPOT not yet implemented\n");
close(zip_handle);
return(95);
}
/* point to the first file header in the central directory structure */
ret = 0;
next_cdh = cdt.cd_off;
cdh.sig = 0L;
/* process each file header in the central directory structure */
for (i=cdt.cnt_all; i>0; i--)
{
/* position to and read a file header */
if (lseek(zip_handle, next_cdh, 0) < 0L)
{
perror("cannot position to ZIPfile header");
ret = 94;
break;
}
if (read(zip_handle, (char *)&cdh, sizeof(cdh)-2) <= 0)
{
perror("cannot read ZIPfile header");
ret = 93;
break;
}
#ifdef DEBUG
printf("sig %lx comp_ver %u extr_ver %u bit_flag %04x method %u\n",
cdh.sig, cdh.comp_ver, cdh.extr_ver, cdh.bit_flag, cdh.method);
printf("\tftime %04x fdate %04x crc %08lx comp_size %lu ur_size %lu\n",
cdh.ftime, cdh.fdate, cdh.crc, cdh.comp_size, cdh.ur_size);
printf("\tfname_len %u extra_len %u cmnt_len %u dno %u\n",
cdh.fname_len, cdh.extra_len, cdh.cmnt_len, cdh.dno);
printf("\tint_attr %04x ext_attr %08lx lfh_off %08lx\n",
cdh.int_attr, cdh.ext_attr, cdh.lfh_off);
#endif
/* is there really a header there ? */
if (cdh.sig != CDH_SIG)
{
fputs("ZIPfile header expected but not found\n", stderr);
ret = 92;
break;
}
/* stash latest file timestamp of the ZIP */
if (!(later = (cdh.fdate>early_date)))
later = (cdh.fdate==early_date && cdh.ftime>early_time);
if (later)
{
early_date = cdh.fdate;
early_time = cdh.ftime;
}
/* compute offset of next header */
next_cdh += sizeof(cdh) - 2 + cdh.fname_len + cdh.extra_len +
cdh.cmnt_len;
cdh.sig = 0L;
}
#ifdef DEBUG
printf("early_date %04x, early_time %04x\n", early_date, early_time);
#endif
#ifdef __TURBOC__
tregs.h.ah = 0x57;
tregs.h.al = 0x01;
tregs.x.bx = zip_handle;
tregs.x.cx = early_time;
tregs.x.dx = early_date;
intdos(&tregs, &tregs);
#else
_dos_setftime(zip_handle, early_date, early_time);
#endif
close(zip_handle);
return(ret);
}
void main(int argc, char **argv)
{
int i, ret;
for (i=1; i<argc; i++)
{
buflen = BUFLEN;
ret = otzip(argv[i]);
if (ret != 0 && ret != 97)
fprintf(stderr, " argument %s return code %d\n", argv[i], ret);
}
exit(0);
}