static int copyzfile(filelist_t *fp, FILE *fo)
{
FILE *fi;
z_stream zs;
char filename[BUFSIZ];
unsigned char deflate_in[DV2_BUFSIZ], deflate_out[DV2_BUFSIZ], *ptr;
int zr;
int bytes, bytesin = 0, bytesout = 0, zbytes, flush = Z_NO_FLUSH;
snprintf(filename, sizeof(filename), "%s/%s",
fp->f_dir->d_name, fp->f_name);
if(!(fi = fopen(filename, "r")))
syserror("unable to open %s for reading", filename);
memset(&zs, 0, sizeof(zs));
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = Z_NULL;
if((zr = deflateInit(&zs, DV2_COMPRESSION)) != Z_OK)
error("deflateInit failed: %d", zr);
while(flush == Z_NO_FLUSH) {
bytes = fread(deflate_in, 1, DV2_BUFSIZ, fi);
bytesin += bytes;
zs.next_in = deflate_in;
zs.avail_in = bytes;
if(feof(fi))
flush = Z_FINISH;
do {
zs.next_out = deflate_out;
zs.avail_out = DV2_BUFSIZ;
if((zr = deflate(&zs, flush)) < Z_OK) {
if(zs.msg)
warn("deflate error: %s", zs.msg);
error("deflate of %s (%d bytes) failed: %d",
filename, bytes, zr);
}
for(zbytes = DV2_BUFSIZ - zs.avail_out,
ptr = deflate_out;
zbytes;
zbytes -= bytes, ptr += bytes, bytesout += bytes)
if(!(bytes = fwrite(ptr, 1, zbytes, fo)))
syserror("fwrite(3) failed for %s",
filename);
} while(zs.avail_out == 0);
}
if(ferror(fi))
syserror("fread(3) of %s failed", filename);
fclose(fi);
if((zr = deflateEnd(&zs)) != Z_OK) {
if(zs.msg)
warn("deflateEnd error: %s", zs.msg);
error("deflateEnd failed: %d", zr);
}
if(bytesin != fp->f_size)
error("%'d bytes does not match declared size of %'d for %s",
bytesout, fp->f_size, filename);
debug("deflated %s: orig=%'d, new=%'d",
filename, bytesin, bytesout);
return bytesout;
}