home *** CD-ROM | disk | FTP | other *** search
- #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);
- }