17 #include <sys/param.h>
19 #include <sys/malloc.h>
20 #include <sys/vnode.h>
21 #include <sys/syslog.h>
22 #include <sys/endian.h>
23 #include <net/zutil.h>
24 #include <sys/libkern.h>
26 #include <sys/vnode.h>
27 #include <sys/mount.h>
29 #define GZ_HEADER_LEN 10
33 # define Z_BUFSIZE 4096
35 # define Z_BUFSIZE 16384
38 #ifndef Z_PRINTF_BUFSIZE
39 # define Z_PRINTF_BUFSIZE 4096
42 #define ALLOC(size) malloc(size, M_TEMP, M_WAITOK | M_ZERO)
43 #define TRYFREE(p) {if (p) free(p, M_TEMP);}
48 #define ASCII_FLAG 0x01
50 #define EXTRA_FIELD 0x04
51 #define ORIG_NAME 0x08
73 local
int do_flush OF((gzFile file,
int flush));
76 local
void *
gz_alloc OF((
void *notused, u_int items, u_int size));
77 local
void gz_free OF((
void *notused,
void *ptr));
94 int level = Z_DEFAULT_COMPRESSION;
95 int strategy = Z_DEFAULT_STRATEGY;
104 if (!path || !mode)
return Z_NULL;
107 if (!s)
return Z_NULL;
111 s->
stream.opaque = (voidpf)0;
125 if (s->
path == NULL) {
126 return destroy(s), (gzFile)Z_NULL;
128 strcpy(s->
path, path);
132 if (*p ==
'r') s->
mode =
'r';
133 if (*p ==
'w' || *p ==
'a') s->
mode =
'w';
134 if (*p >=
'0' && *p <=
'9') {
136 }
else if (*p ==
'f') {
137 strategy = Z_FILTERED;
138 }
else if (*p ==
'h') {
139 strategy = Z_HUFFMAN_ONLY;
143 }
while (*p++ && m != fmode +
sizeof(fmode));
145 if (s->
mode !=
'w') {
146 log(LOG_ERR,
"gz_open: mode is not w (%c)\n", s->
mode);
147 return destroy(s), (gzFile)Z_NULL;
150 err = deflateInit2(&(s->
stream), level,
151 Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
155 if (err != Z_OK || s->
outbuf == Z_NULL) {
156 return destroy(s), (gzFile)Z_NULL;
165 gz_magic[1], Z_DEFLATED, 0 , 0,0,0,0 ,
169 UIO_SYSSPACE, IO_UNIT, curproc->p_ucred,
170 NOCRED, &resid, curthread))) {
172 return destroy(s), (gzFile)Z_NULL;
190 if (!s)
return Z_STREAM_ERROR;
194 if (s->stream.state != NULL) {
195 if (s->mode ==
'w') {
196 err = deflateEnd(&(s->stream));
199 if (s->z_err < 0) err = s->z_err;
224 if (s == NULL || s->
mode !=
'w')
return Z_STREAM_ERROR;
226 s->
stream.next_in = (Bytef*)buf;
230 while (s->
stream.avail_in != 0) {
232 if (s->
stream.avail_out == 0) {
235 vfslocked = VFS_LOCK_GIANT(s->
file->v_mount);
237 curoff, UIO_SYSSPACE, IO_UNIT,
238 curproc->p_ucred, NOCRED, &resid, curthread);
239 VFS_UNLOCK_GIANT(vfslocked);
241 log(LOG_ERR,
"gzwrite: vn_rdwr return %d\n", error);
250 if (s->
z_err != Z_OK) {
252 "gzwrite: deflate returned error %d\n", s->
z_err);
257 s->
crc = ~crc32_raw(buf, len, ~s->
crc);
260 return (
int)(len - s->
stream.avail_in);
280 if (s == NULL || s->
mode !=
'w')
return Z_STREAM_ERROR;
283 log(LOG_WARNING,
"do_flush: avail_in non-zero on entry\n");
292 vfslocked = VFS_LOCK_GIANT(s->
file->v_mount);
294 UIO_SYSSPACE, IO_UNIT, curproc->p_ucred,
295 NOCRED, &resid, curthread);
296 VFS_UNLOCK_GIANT(vfslocked);
299 s->
outoff = curoff + len - resid;
310 if (len == 0 && s->
z_err == Z_BUF_ERROR) s->
z_err = Z_OK;
315 done = (s->
stream.avail_out != 0 || s->
z_err == Z_STREAM_END);
317 if (s->
z_err != Z_OK && s->
z_err != Z_STREAM_END)
break;
321 return s->
z_err == Z_STREAM_END ? Z_OK : s->
z_err;
332 return s->
z_err == Z_STREAM_END ? Z_OK : s->
z_err;
347 #if BYTE_ORDER == BIG_ENDIAN
352 vn_rdwr(UIO_WRITE, s->file, (caddr_t)&xx,
sizeof(xx), curoff,
353 UIO_SYSSPACE, IO_UNIT, curproc->p_ucred,
354 NOCRED, &resid, curthread);
355 s->outoff +=
sizeof(xx) - resid;
369 if (s == NULL)
return Z_STREAM_ERROR;
371 if (s->
mode ==
'w') {
374 log(LOG_ERR,
"gzclose: do_flush failed (err %d)\n", err);
378 printf(
"gzclose: putting crc: %lld total: %lld\n",
379 (
long long)s->
crc, (
long long)s->
stream.total_in);
380 printf(
"sizeof uLong = %d\n", (
int)
sizeof(uLong));
393 gz_alloc(
void *notused __unused, u_int items, u_int size)
397 MALLOC(ptr,
void *, items * size, M_TEMP, M_NOWAIT | M_ZERO);
struct gz_stream gz_stream
static void gz_free(void *opaque __unused, void *ptr)
int vn_rdwr_inchunks(enum uio_rw rw, struct vnode *vp, void *base, size_t len, off_t offset, enum uio_seg segflg, int ioflg, struct ucred *active_cred, struct ucred *file_cred, size_t *aresid, struct thread *td)
int snprintf(char *str, size_t size, const char *format,...)
local int destroy(gz_stream *s)
local int do_flush OF((gzFile file, int flush))
int ZEXPORT gzwrite(gzFile file, const voidp buf, unsigned len)
gzFile gz_open(char *path, const char *mode, struct vnode *vp) const
int vn_rdwr(enum uio_rw rw, struct vnode *vp, void *base, int len, off_t offset, enum uio_seg segflg, int ioflg, struct ucred *active_cred, struct ucred *file_cred, ssize_t *aresid, struct thread *td)
void log(int level, const char *fmt,...)
int printf(const char *fmt,...)
static void * gz_alloc(void *notused __unused, u_int items, u_int size)
local void putU32(gz_stream *s, uint32_t x)
local int do_flush(gzFile file, int flush)
int ZEXPORT gzflush(gzFile file, int flush)
int ZEXPORT gzclose(gzFile file)
const struct cf_level * level