home *** CD-ROM | disk | FTP | other *** search
- /* v3.05 File related functions for unzip.c */
-
- /*
- * input file variables
- *
- */
-
- #define INBUFSIZ BUFSIZ /* same as stdio uses */
- byte *inbuf; /* input file buffer - any size is legal */
- byte *inptr;
-
- int incnt;
- UWORD bitbuf;
- int bits_left;
- boolean zipeof;
-
- int zipfd;
- char __huge zipfn[STRSIZ];
- local_file_header lrec;
-
- /* ----------------------------------------------------------- */
- /*
- * output stream variables
- *
- */
-
- byte *outbuf; /* buffer for rle look-back */
- byte *outptr;
- byte *outout; /* Scratch pad for ascebc trans v2.0g */
-
- longint outpos; /* absolute position in outfile */
- int outcnt; /* current position in outbuf */
-
- int outfd;
- char filename[STRSIZ];
- char extra[STRSIZ];
- char comment[STRSIZ]; /* v2.0b made it global for displays */
-
-
- void set_file_time()
- /*
- * set the output file date/time stamp according to information from the
- * zipfile directory record for this file
- */
- {
- #ifndef UNIX
- #ifndef AMIGA
- union {
- struct ftime ft; /* system file time record */
- struct {
- UWORD ztime; /* date and time words */
- UWORD zdate; /* .. same format as in .ZIP file */
- } zt;
- } td;
-
- /*
- * set output file date and time - this is optional and can be
- * deleted if your compiler does not easily support setftime()
- */
-
- td.zt.ztime = lrec.last_mod_file_time;
- td.zt.zdate = lrec.last_mod_file_date;
-
- setftime(outfd, &td.ft);
-
- #endif /* AMIGA */
- #else /* UNIX */
-
- time_t times[2];
- struct tm *tmbuf;
- long m_time;
- int yr, mo, dy, hh, mm, ss, leap, days = 0;
- #ifdef BSD
- struct timeval tv;
- struct timezone tz;
- #endif
-
- /*
- * These date conversions look a little wierd, so I'll explain.
- * UNIX bases all file modification times on the number of seconds
- * elapsed since Jan 1, 1970, 00:00:00 GMT. Therefore, to maintain
- * compatibility with MS-DOS archives, which date from Jan 1, 1980,
- * with NO relation to GMT, the following conversions must be made:
- * the Year (yr) must be incremented by 10;
- * the Date (dy) must be decremented by 1;
- * and the whole mess must be adjusted by TWO factors:
- * relationship to GMT (ie.,Pacific Time adds 8 hrs.),
- * and whether or not it is Daylight Savings Time.
- * Also, the usual conversions must take place to account for leap years,
- * etc.
- * C. Seaman
- */
-
- yr = (((lrec.last_mod_file_date >> 9) & 0x7f) + 10); /* dissect date */
- mo = ((lrec.last_mod_file_date >> 5) & 0x0f);
- dy = ((lrec.last_mod_file_date & 0x1f) - 1);
-
- hh = ((lrec.last_mod_file_time >> 11) & 0x1f); /* dissect time */
- mm = ((lrec.last_mod_file_time >> 5) & 0x3f);
- ss = ((lrec.last_mod_file_time & 0x1f) * 2);
-
- /* leap = # of leap years from 1970 up to but not including
- the current year */
-
- leap = ((yr+1969)/4); /* Leap year base factor */
-
- /* How many days from 1970 to this year? */
- days = (yr * 365) + (leap - 492);
-
- switch(mo) /* calculate expired days this year */
- {
- case 12:
- days += 30;
- case 11:
- days += 31;
- case 10:
- days += 30;
- case 9:
- days += 31;
- case 8:
- days += 31;
- case 7:
- days += 30;
- case 6:
- days += 31;
- case 5:
- days += 30;
- case 4:
- days += 31;
- case 3:
- days += 28; /* account for leap years */
- if (((yr+1970) % 4 == 0) && (yr+1970) != 2000)
- ++days;
- case 2:
- days += 31;
- }
-
- /* convert date & time to seconds relative to 00:00:00, 01/01/1970 */
- m_time = ((days + dy) * 86400) + (hh * 3600) + (mm * 60) + ss;
-
- #ifdef BSD
- gettimeofday(&tv, &tz);
- /* This program is TOO smart about daylight savings time.
- * Adjusting for it throws our file times off by one hour if it's true.
- * Remming it out.
- *
- * if (tz.tz_dsttime != 0)
- * m_time -= 3600;
- */
- m_time += tz.tz_minuteswest * 60; /* account for timezone differences */
- #else /* !BSD */
- tmbuf = localtime(&m_time);
- hh = tmbuf->tm_hour;
- tmbuf = gmtime(&m_time);
- hh = tmbuf->tm_hour - hh;
- if (hh < 0)
- hh += 24;
- m_time += (hh * 3600); /* account for timezone differences */
- #endif
-
- times[0] = m_time; /* set the stamp on the file */
- times[1] = m_time;
- utime(filename, times);
- #endif /* UNIX */
- }
-
-
- int create_output_file()
- /* return non-0 if creat failed */
- { /* create the output file with READ and WRITE permissions */
- static int do_all = 0;
- char answerbuf[10];
- UWORD holder;
-
- if (cflag) { /* output to stdout (a copy of it, really) */
- #ifdef AMIGA
- outfd = 1;
- #else
- outfd = dup(1);
- #endif /* AMIGA */
- return 0;
- }
- CR_flag = 0; /* Hack to get CR at end of buffer working. */
-
- /*
- * check if the file exists, unless do_all
- * ask before overwrite code by Bill Davidsen (davidsen@crdos1.crd.ge.com)
- */
- if (!do_all) {
- outfd = open(filename, 0);
- if (outfd >= 0) {
- /* first close it, before you forget! */
- close(outfd);
-
- /* ask the user before blowing it away */
- fprintf(stderr, "replace %s, y-yes, n-no, a-all: ", filename);
- fgets(answerbuf, 9, stdin);
-
- switch (answerbuf[0]) {
- case 'y':
- case 'Y':
- break;
- case 'a':
- case 'A':
- do_all = 1;
- break;
- case 'n':
- case 'N':
- default:
- while(ReadByte(&holder));
- return 1; /* it's done! */
- }
- }
- }
-
- #ifndef UNIX
- outfd = creat(filename, S_IWRITE | S_IREAD);
- #else
- outfd = creat(filename, 0666); /* let umask strip unwanted perm's */
- #endif
-
- if (outfd < 1) {
- fprintf(stderr, "Can't create output: %s\n", filename);
- return 1;
- }
-
- /*
- * close the newly created file and reopen it in BINARY mode to
- * disable all CR/LF translations
- */
- #ifndef UNIX
- #ifndef AMIGA
- close(outfd);
- outfd = open(filename, O_RDWR | O_BINARY);
- #endif /* AMIGA */
- #endif
- return 0;
- }
-
-
- int open_input_file()
- /* return non-0 if open failed */
- {
- /*
- * open the zipfile for reading and in BINARY mode to prevent cr/lf
- * translation, which would corrupt the bitstreams
- */
-
- #ifdef AMIGA
- zipfd = open(zipfn, O_RDONLY);
- #else
- #ifndef UNIX
- zipfd = open(zipfn, O_RDONLY | O_BINARY);
- #else
- zipfd = open(zipfn, O_RDONLY);
- #endif
- #endif /* AMIGA */
- if (zipfd < 1) {
- fprintf(stderr, "Can't open input file: %s\n", zipfn);
- return (1);
- }
- return 0;
- }
-
- /* ============================================================= */
-
- int __regargs readbuf(fd, buf, size)
- int fd;
- char *buf;
- unsigned size;
- {
- register int count;
- int n;
-
- n = size;
- while (size) {
- if (incnt == 0) {
- if ((incnt = read(fd, inbuf, INBUFSIZ)) <= 0)
- return(incnt);
- inptr = inbuf;
- }
- count = min(size, incnt);
- zmemcpy(buf, inptr, count);
- buf += count;
- inptr += count;
- incnt -= count;
- size -= count;
- }
- return(n);
- }
-
- int ReadByte(x)
- UWORD *x;
- /* read a byte; return 8 if byte available, 0 if not */
- {
- if (csize-- <= 0)
- return 0;
- if (incnt == 0) {
- if ((incnt = read(zipfd, inbuf, INBUFSIZ)) <= 0)
- return 0;
- inptr = inbuf;
- }
- *x = *inptr++;
- --incnt;
- return 8;
- }
-
-
- /* ------------------------------------------------------------- */
- static UWORD mask_bits[] =
- {0, 0x0001, 0x0003, 0x0007, 0x000f,
- 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff,
- 0x1fff, 0x3fff, 0x7fff, 0xffff
- };
-
-
- int __regargs FillBitBuffer(bits)
- int bits;
- {
- /* get the bits that are left and read the next UWORD */
- register int result = bitbuf;
- UWORD temp;
- int sbits = bits_left;
- bits -= bits_left;
-
- /* read next UWORD of input */
- bits_left = ReadByte(&bitbuf);
- bits_left += ReadByte(&temp);
-
- bitbuf |= (temp << 8);
- if (bits_left == 0)
- zipeof = 1;
-
- /* get the remaining bits */
- result = result | (int) ((bitbuf & mask_bits[bits]) << sbits);
- bitbuf >>= bits;
- bits_left -= bits;
- return result;
- }
-
- /* ------------------------------------------------------------- */
-
- int dos2unix (buf, len)
- unsigned char *buf;
- int len;
- {
- int new_len;
- int i;
- unsigned char *walker;
-
- new_len = len;
- walker = outout;
- if (CR_flag && *buf != LF)
- *walker++ = ascii_to_native(CR);
- CR_flag = buf[len - 1] == CR;
- for (i = 0; i < len; i += 1) {
- *walker++ = *buf;
- if (*buf++ == CR && *buf == LF) {
- new_len--;
- walker[-1] = ascii_to_native(*buf++);
- i++;
- }
- }
- /*
- * If the last character is a CR, then "ignore it" for now...
- */
- if (walker[-1] == CR)
- new_len--;
- return new_len;
- }
-
- void WriteBuffer(fd, buf, len)
- int fd;
- unsigned char *buf;
- int len;
- {
- if (aflag)
- len = dos2unix (buf, len);
- if (write (fd, outout, len) != len) {
- fprintf (stderr, "Fatal write error.\n");
- exit (1);
- }
- }
-
-
- /* ------------------------------------------------------------- */
-
- void FlushOutput()
- /* flush contents of output buffer */
- {
- if (outcnt) {
- UpdateCRC(outbuf, outcnt);
-
- if (!tflag)
- WriteBuffer(outfd, outbuf, outcnt);
-
- outpos += outcnt;
- outcnt = 0;
- outptr = outbuf;
- }
- }
-
-