GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/smtpd/smtpctl/../compress_gzip.c Lines: 0 57 0.0 %
Date: 2017-11-07 Branches: 0 40 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: compress_gzip.c,v 1.10 2015/12/28 22:08:30 jung Exp $	*/
2
3
/*
4
 * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
5
 * Copyright (c) 2012 Charles Longeau <chl@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/queue.h>
22
#include <sys/tree.h>
23
#include <sys/socket.h>
24
#include <sys/stat.h>
25
26
#include <ctype.h>
27
#include <err.h>
28
#include <fcntl.h>
29
#include <imsg.h>
30
#include <pwd.h>
31
#include <stdio.h>
32
#include <stdlib.h>
33
#include <string.h>
34
#include <unistd.h>
35
#include <limits.h>
36
37
#include <zlib.h>
38
39
#include "smtpd.h"
40
#include "log.h"
41
42
43
#define	GZIP_BUFFER_SIZE	16384
44
45
46
static size_t	compress_gzip_chunk(void *, size_t, void *, size_t);
47
static size_t	uncompress_gzip_chunk(void *, size_t, void *, size_t);
48
static int	compress_gzip_file(FILE *, FILE *);
49
static int	uncompress_gzip_file(FILE *, FILE *);
50
51
52
struct compress_backend	compress_gzip = {
53
	compress_gzip_chunk,
54
	uncompress_gzip_chunk,
55
56
	compress_gzip_file,
57
	uncompress_gzip_file,
58
};
59
60
static size_t
61
compress_gzip_chunk(void *ib, size_t ibsz, void *ob, size_t obsz)
62
{
63
	z_stream       *strm;
64
	size_t		ret = 0;
65
66
	if ((strm = calloc(1, sizeof *strm)) == NULL)
67
		return 0;
68
69
	strm->zalloc = Z_NULL;
70
	strm->zfree = Z_NULL;
71
	strm->opaque = Z_NULL;
72
	if (deflateInit2(strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
73
		(15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK)
74
		goto end;
75
76
	strm->avail_in  = ibsz;
77
	strm->next_in   = (unsigned char *)ib;
78
	strm->avail_out = obsz;
79
	strm->next_out  = (unsigned char *)ob;
80
	if (deflate(strm, Z_FINISH) != Z_STREAM_END)
81
		goto end;
82
83
	ret = strm->total_out;
84
85
end:
86
	deflateEnd(strm);
87
	free(strm);
88
	return ret;
89
}
90
91
92
static size_t
93
uncompress_gzip_chunk(void *ib, size_t ibsz, void *ob, size_t obsz)
94
{
95
	z_stream       *strm;
96
	size_t		ret = 0;
97
98
	if ((strm = calloc(1, sizeof *strm)) == NULL)
99
		return 0;
100
101
	strm->zalloc   = Z_NULL;
102
	strm->zfree    = Z_NULL;
103
	strm->opaque   = Z_NULL;
104
	strm->avail_in = 0;
105
	strm->next_in  = Z_NULL;
106
107
	if (inflateInit2(strm, (15+16)) != Z_OK)
108
		goto end;
109
110
	strm->avail_in  = ibsz;
111
	strm->next_in   = (unsigned char *)ib;
112
	strm->avail_out = obsz;
113
	strm->next_out  = (unsigned char *)ob;
114
115
	if (inflate(strm, Z_FINISH) != Z_STREAM_END)
116
		goto end;
117
118
	ret = strm->total_out;
119
120
end:
121
	deflateEnd(strm);
122
	free(strm);
123
	return ret;
124
}
125
126
127
static int
128
compress_gzip_file(FILE *in, FILE *out)
129
{
130
	gzFile  gzf;
131
	char  ibuf[GZIP_BUFFER_SIZE];
132
	int  r, w;
133
	int  ret = 0;
134
135
	if (in == NULL || out == NULL)
136
		return (0);
137
138
	gzf = gzdopen(fileno(out), "wb");
139
	if (gzf == NULL)
140
		return (0);
141
142
	while ((r = fread(ibuf, 1, GZIP_BUFFER_SIZE, in)) != 0) {
143
		if ((w = gzwrite(gzf, ibuf, r)) != r)
144
			goto end;
145
	}
146
	if (!feof(in))
147
		goto end;
148
149
	ret = 1;
150
151
end:
152
	gzclose(gzf);
153
	return (ret);
154
}
155
156
157
static int
158
uncompress_gzip_file(FILE *in, FILE *out)
159
{
160
	gzFile  gzf;
161
	char  obuf[GZIP_BUFFER_SIZE];
162
	int  r, w;
163
	int  ret = 0;
164
165
	if (in == NULL || out == NULL)
166
		return (0);
167
168
	gzf = gzdopen(fileno(in), "r");
169
	if (gzf == NULL)
170
		return (0);
171
172
	while ((r = gzread(gzf, obuf, sizeof(obuf))) > 0) {
173
		if  ((w = fwrite(obuf, r, 1, out)) != 1)
174
			goto end;
175
	}
176
	if (!gzeof(gzf))
177
		goto end;
178
179
	ret = 1;
180
181
end:
182
	gzclose(gzf);
183
	return (ret);
184
}