home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1999 mARCH
/
PCWK3A99.iso
/
Archiwiz
/
Tar320
/
SOURCES.ZIP
/
ZIPPIPE.C
< prev
next >
Wrap
Text File
|
1994-10-31
|
7KB
|
242 lines
#include <stdio.h>
#include "modern.h"
#include "zalloc.h"
#include "zippipe.h"
#include "zipguts.h"
#include "ziposcod.h"
#include "crc32.h"
#ifndef UNIX
# ifdef M_XENIX
# define UNIX
# endif
# ifdef unix
# define UNIX
# endif
#endif
#ifdef UNIX
# include <time.h>
#endif
#ifdef MSDOS
# include <dos.h>
# ifdef __TURBOC__
# include <io.h>
# endif
#endif
static unsigned long dostime __ARGS__((void))
{
#ifdef MSDOS
# ifdef __TURBOC__
union { struct date d; struct time t; } u;
struct ftime f;
getdate(&u.d);
f.ft_year = u.d.da_year - 1980;
f.ft_month = u.d.da_mon;
f.ft_day = u.d.da_day;
gettime(&u.t);
f.ft_hour = u.t.ti_hour;
f.ft_min = u.t.ti_min;
f.ft_tsec = u.t.ti_sec;
return *(unsigned long *)&f;
# else
uninon REGS r;
unsigned d;
r.h.ah = 0x2A; /* get date */ intdos(&r, &r);
d = ((r.x.cx - 1980) << 9) | (r.h.dh << 5) | r.h.dl;
r.h.ah = 0x2C; /* get time */ intdos(&r, &r);
return ((unsigned long)d << 16) |
(r.h.ch << 11) | (r.h.cl << 5) | (r.h.dh >> 1);
# endif
#else
# ifdef UNIX
extern long time();
struct tm *s;
long t;
(void)time(&t);
s = localtime(&t);
if (s->tm_year < 80) return 0L;
return ((unsigned long)(s->tm_year - 80) << 25) |
((unsigned long)s->tm_mon << 21) | ((unsigned long)s->tm_mday << 16) |
((unsigned)s->tm_hour << 11) | (s->tm_min << 5) | (s->tm_sec >> 1);
# else
/* dummy time stamp */ return 0L;
# endif
#endif
}
#ifndef zalloc
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
* and farmalloc(64K) returns a pointer with nonzero offset, so we
* must fix the pointer. Warning: the pointer must be saved in its
* original form in order to free it, use farfree().
* For MSC, use halloc instead of this function.
*/
void far *zalloc(void far **p, unsigned n, unsigned s)
{
register unsigned long l;
l = (unsigned long)(*p = farmalloc((unsigned long)n*s + 15));
return (void far *)
((0xffff0000L & l) + (0xffff0000L & (((0xffffL & l) + 15) << 12)));
}
#endif
int zipalloc()
{
#ifdef DYN_ALLOC
if (ct_alloc() != 0) return ZNOMEM;
if (lm_alloc() != 0) {
ct_free(); return ZNOMEM;
}
#endif
return 0;
}
void zipfree()
{
#ifdef DYN_ALLOC
lm_free();
ct_free();
#endif
}
static void putlong __ARGS__((ulg));
static void putlong(l)
ulg l;
{
putword((ush)l); putword((ush)(l >> 16));
}
static ulg inpsize;
#ifdef DEBUG
ulg isize;
#endif
static int ziptype;
int deflate_level = 6;
static ulg timestamp;
static ush flags;
/* speed options for the general purpose bit flag */
#define FAST 4
#define SLOW 2
int zipcreat(putb, ztype, dlevel)
void (*putb)__ARGS__((int));
int ztype, dlevel;
{
register k;
if (dlevel<1 || dlevel>9 ||
(ztype!=ZIP_PKW && ztype!=ZIP_GNU && ztype!=ZIP_RAW))
return (ziperror = ZUNSUP);
deflate_level = dlevel;
flags = dlevel <= 1 ? FAST : dlevel >= 9 ? SLOW : 0;
ziptype = ztype;
crcbegin();
bi_init();
if (ct_init() != 0) return (ziperror = ZNOMEM);
if ((k=lm_init()) != 0) {
#ifdef DYN_ALLOC
ct_free();
#endif
return (ziperror = k);
}
ziputbyte = putb;
/* Write the header to the gzip file */
/* No extra field, file name or comment; no encryption */
if (ziptype == ZIP_GNU) {
putword(GZIP_MAGIC);/* magic header */
putbyte(DEFLATED); /* compression method */
putbyte(0); /* general flags: nothing */
putlong(0L); /* dummy time stamp */
putbyte(flags); /* extra flags */
putbyte(OS_CODE); /* OS identifier */
} else if (ziptype == ZIP_PKW) {
putlong(PKW_LOCAL); /* magic header */
putword(19); /* version to extract */
putword(flags|=8);
putword(DEFLATED); /* compression method */
/* Who, the hell, needs in this time stamp? */
putlong(timestamp = dostime());
putlong(0L); /* dummy CRC */
putlong(0L); /* dummy compressed size */
putlong(0L); /* dummy original size */
putlong(0L); /* null file name & extra fields */
}
inpsize = 0L;
return 0;
}
int zipwrite(buffer, length)
char *buffer; unsigned length;
{
if (!ziputbyte) return (ziperror=ZNOPEN, -1);
if (length) {
updcrc((unsigned char *)buffer, length);
inpsize += length;
}
return deflate_level > 3 ?
lazy_deflate(buffer, length) :
fast_deflate(buffer, length);
}
long zipclose()
{
extern unsigned minlookahead;
register long l = -1;
ulg clen, crc;
minlookahead = 0; /* indicate end of input */
/* Flush out any remaining bytes */
if (zipwrite(NULL,0) != 0) goto end;
clen = (compressed_len >> 3);
crc = getcrc();
if (ziptype == ZIP_GNU) {
/* Write the crc. & uncompressed size */
putlong(crc); putlong(inpsize);
} else if (ziptype == ZIP_PKW) {
/* Write the /data descriptor/ extended locxal header */
putlong(PKW_EXT); /* signature */
putlong(crc); /* CRC */
putlong(clen); /* compressed size */
putlong(inpsize); /* uncompressed size */
/* Write the central directory entry */
putlong(PKW_CENTRAL);
putword((OS_CODE<<8)|20); /* version made by */
putword(19); /* version to extract */
putword(flags);
putword(DEFLATED);/* compression method */
putlong(timestamp);
putlong(crc); /* CRC */
putlong(clen); /* compressed size */
putlong(inpsize); /* original size */
putlong(0L); /* filename & extra field length */
putword(0); /* file comment length */
putword(0); /* disk number start */
putword(0); /* internal file attributes */
putlong(0L); /* external file attributes */
putlong(0L); /* relative offset of local header */
/* Finish the central directory */
putlong(PKW_END);
putword(0); /* number of this disk */
putword(0); /* number of the disk with the start of CD */
putword(1); /* total number of CD entries on this disk */
putword(1); /* total number of CD entries */
putlong(46L); /* size of the central directory */
putlong(30+clen+16); /* offset of start of CD */
putword(0); /* zipfile comment length */
}
l = clen;
end:
ziputbyte = NULL;
zipfree();
return l;
}